CSS Responsive HTML forms - html

I have this HTML Code:
<h4>Company Details</h4>
<div>
<label for="company">Company</label>
<div>
<input type="text" name="company" value="<?php echo $customer["company"]; ?>" />
</div>
</div>
I would like to have the text inputs and labels displaying inline with each other then as the screen gets smaller to move the text inputs under the labels

There are many ways to achieve this. Chose the one that fits your project the best. I would set the label and the div containing the input as "inline" or "inline-block" using CSS. Then if you need then line to collapse into two, use media queries (see the last code snippet).
<h4>Company Details</h4>
<div class="input-group">
<label for="company">Company</label>
<div>
<input type="text" name="company" value="<?php echo $customer["company"]; ?>" />
</div>
</div>
// This will make them show inline occupying half the width
.input-group > label, .input-group > div{
display: inline-block;
width: 50%;
}
I sometimes have problems with extra pixels in inline-blocks,
and I typically solve it by floating the blocks or setting the
font size to zero.
// This way the label and input float
.input-group {
clear: both; // So the container doesn't collapse
}
.input-group > label, .input-group > div{
float: left;
width: 50%;
}
For the font size version:
// This way the font size in the container is zero
.input-group {
font-size: 0;
}
.input-group > label, .input-group > div{
display: inline-block;
width: 50%;
font-size: 12px;
}
Your div will automatically stretch to 100% of the screen, so You don't need media queries to set its width; it's already responsive as is. But if you insist on using them, or need them, add this as well:
#media (max-width: 500px) {
.input-group > label, .input-group > div{
display: block;
float: none;
}
}

It's pretty easy to achieve. Simply set:
.inputLine label, .inputLine div {
display: inline;
}
With the HTML being:
<h4>Company Details</h4>
<div class="inputLine">
<label for="company">Company</label>
<div>
<input type="text" name="company" value="My Company" />
</div>
</div>
Working example:
http://jsfiddle.net/wLjekogo/
Updated: april 20th, 2015
To achieve the requested output, while allowing multiple inline elements. You could use the following HTML/CSS combination:
HTML
<h4>Company Details</h4>
<div class="inputLine">
<label for="company">Company</label>
<input type="text" name="company" value="My Company" />
</div>
<div class="inputLine">
<label for="company">Company</label>
<input type="text" name="company" value="My Company" />
</div>
CSS
.inputLine {
display: inline-block;
}
.inputLine label {
display: inline-block;
max-width: "100%";
}
.inputLine input {
display: inline-block;
width: auto;
}
This would show all input fields inline, unless the screen is too small. In which case first the divs will be on a new line, and even more smaller, a vertical form.
Example:
http://jsfiddle.net/wLjekogo/2/

Related

Vertically align inputs with each other

I have two inputs, but the pre-displayed labels have different length, causing the inputs not to start from the same position (vertically speaking). How to achieve that?
Some of my attempts are:
input {
margin-left: 50px;
}
input {
vertical-align:middle;
}
Please notice that display: block; will make the label and input lose their initial corresponding positions!
My JSFiddle.
You can make use of CSS table layout. The parent element acts as a table row and the child elements as table cells.
.input-container {
display: table-row;
}
.input-container * {
display: table-cell;
margin-left: 5px;
}
<fieldset>
<legend>Team1</legend>
<div class="input-container">
<label for="player1">Player1</label>
<input type="number" name="player1">
</div>
<div class="input-container">
<label for="player2">Player2345</label>
<input type="number" name="player2">
</div>
</fieldset>

Align inputs next to labels in article section

I know that a lot of questions related to this topic have been asked. I went through most of them, but I still cannot figure out why it does not work in my case.
My website is divided into two parts using the aside and article tags. I would like my form to be inside the article tag. Moreover, I would like my labels to be aligned next to my inputs. I tried:
label{ display: inline-block; width: XXpx; text-align: right;}
label{ display: block; width: XXpx; float: left;}
and other configurations, but it does not work. The fact is I use display: table-cell in the aside and article tags to get the background color to extend all the way down the page. I am wondering if it has an impact.
HTML
<section>
.
.
.
<article>
.
.
.
<form method="post" action="Y.php">
<label for="name" id="name1"> Name<em>*</em> </label>
<input type="text" name="name" id="name2" placeholder="Ex : Tom" autofocus="" required="" /> <br>
<label for="email"> Email<em>*</em> </label>
<input type="email" name="email" id="email1" placeholder="Ex : Tom#gmail.com" required="" /> <br>
</form>
</article>
</section>
CSS
aside, article{ display: table-cell; vertical-align: top; text-align: justify; line-height: 1.5em;}
label{ display: inline-block; width: XXpx; text-align: right;}
Any idea is welcome!
Do you mean you want the labels to have the same width, so that all elements line up nicely?
You can do that by adding a min-width to your labels:
label {
min-width: 100px; /* Or whatever value and unit you want. */
}
Live example with your code: http://codepen.io/TheDutchCoder/pen/GggQRR

Using <br> together with display: inline-block. Bad practice?

I'm using a form like the following:
<form action="#" method="post">
<div class="row">
<label for="email">E-Mail</label>
<input type="text" name="email" id="email">
</div>
<div class="row">
<label for="password">Password</label>
<input type="password" name="password" id="password">
<br>
<label for="passwordRepeat">Repeat Password</label>
<input type="password" name="passwordRepeat" id="passwordRepeat">
</div>
<div class="row">
<label for="phonenumber">Phone Number</label>
<input type="text" name="phonenumber" id="phonenumber">
</div>
</form>
with the following styles:
.row {
background-color: #eee;
margin-bottom: 10px;
padding: 5px;
}
.row > * {
display: inline-block;
vertical-align: middle;
}
.row > label {
width: 200px;
}
Take a look at the JSFiddle.
I'm using a <br> tag to break the line between a bunch of elements with the property display: inline-block. I'm aware that it is of course bad practice to use <br> instead of margin and padding. That's the reason it became so unpopular.
As far as I know there is no good reason to not use a single <br> tag in an inline element as it is intended to be: As a line break in text without creating a new text section. With display: inline-block, you simulate the inline behaviour to your block elements. Spaces between elements appear as they would in an inline element.
In my case, the <br> is used instead of two wrapper <div>'s. I do like my HTML code clean, so I hesitate in using to many wrapper <div>'s. Is it bad practice to use a <br> in this exact case? I think it is very clear what happens here, if you just read the HTML flie. What do you think about that (without any prejudgments about <br> in general)?
I believe the answer is Yes. <br /> is for line breaks in text and not for positioning, But I will give you a situation where it would hurt you in the long run. Say you have a mobile layout for your fields, and you want them to be 100% width on small screens - with labels above... and then in another case you want them to vertically align next to another... and then in another situation land in a grid like setup. Those linebreaks are going to become cumbersome.
Here is a jsFiddle of that.
I did see someone using them in a clever way where they used display: none; on them at certain break points that rendered them inactive. I didn't expect that to work. I can only really imagine using them for:
Cosmo magazine
style - huge
text layouts
and even then I would use lettering.js to insert spans. But hey --- it's not that people will say you were wrong... it's what does the job best. And I don't think that <br /> ever really suits positioning.
With HTML5, it seems like everything has an element now, so div's are for positioning. That seems pretty semantic to me.
HTML
<div class="input-wrapper">
<label data-required="required">E-Mail</label>
<input type="email" name="email" />
</div>
CSS
.your-form .input-wrapper {
width: 100%;
float: left;
margin-bottom: 2em;
}
.your-form label {
display: block;
width: 100%;
float: left;
}
[data-required="required"]:after{
content: "*";
color: red;
font-size: .8em;
vertical-align: top;
padding: .2em;
}
.your-form input{
display: block;
width: 100%;
float: left;
}
#media screen and (min-width: 28em) {
.your-form label {
width: auto;
float: none;
display: inline-block;
vertical-align: middle;
min-width: 10em;
}
.your-form input{
width: auto; /* overide previous rule */
float: none; /* overide previous rule */
display: inline-block; /* center vertically */
vertical-align: middle; /* center vertically */
/* min-width: 20em; */
font-size: 1.4em; /* just to show vertical align */
}
} /* end break point */
Yes, as you are using a content element for styling.
It might be shorter, but that doesn't mean it's cleaner.
Adding elements just for styling purposes should be avoided if possible.
And in this case it's possible: Demo
HTML:
<form action="#" method="post">
<div class="row">
<label>E-Mail <input type="text" name="email" /></label>
</div>
<div class="row">
<label>Password <input type="password" name="password" /></label>
<label>Repeat Password <input type="password" name="passwordRepeat" /></label>
</div>
<div class="row">
<label>Phone Number <input type="text" name="phonenumber" /></label>
</div>
</form>
CSS:
.row {
background-color: #eee;
margin-bottom: 10px;
padding: 5px;
}
.row > label {
display: block;
overflow: hidden;
width: 350px;
}
.row > label > input {
float: right;
}
I would avoid it where possible. You may be able to achive what you want, and not use floats by adding a margin to the input element like:
.row > input
{
margin-right:50%;
}
http://jsfiddle.net/pwtA4/
You may need to add some media queries if you want for smaller view ports

How can I layout text and inputs on a form to fit a specific width (justified)?

I have a form and I am trying to make a row "justified" so the entire row (which is a 4 textboxes and labels) to fit an exact pixel width (lets say 800px). Normally, if i just lay it out without any special css, It is less than 800px. I want to "stretch" it to be 800px. I don't care if I have to stretch the textboxes or the spaces in between them.
This is similar to justified layout in MS word if that helps describe what i am looking for. Is this possible within html / css in a form layout?
You basically need text-align-last: justify which specifies the justification of the "last text line" in a block element, this defaults namely to the standard direction, which is left in LTR.
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 15994654</title>
<style>
#fields {
width: 1000px;
border: 1px solid gray;
}
.justified {
text-align-last: justify;
}
</style>
</head>
<body>
<p id="fields" class="justified">
<label for="input1">label1</label>
<input id="input1" />
<label for="input2">label2</label>
<input id="input2" />
<label for="input3">label3</label>
<input id="input3" />
<label for="input4">label4</label>
<input id="input4" />
<p>
</body>
</html>
This works in IE and Firefox (for older Firefox versions, add -moz-text-align-last: justify if necessary), however this fails in Webkit based browsers (Chrome/Safari). To cover those browser as well, you'd need to replace .justified as follows, so that the last line doesn't appear as a "last line" anymore, so that text-align: justify can do its job the usual way:
.justified {
text-align: justify;
}
.justified:after {
content: '';
display: inline-block;
width: 100%;
}
Note that the text-align-last: justify becomes redundant this way.
Here's the jsfiddle demo.
Actually, there's a very natural way to do this with pure CSS using text-align: justify;.
You didn't succeed because justification doesn't work for the last line (and when there's only one line, it's considered to be the last). There's a CSS3 property that sets text alignment for the last line: text-align-last. Unfortunately, it is not broadly supported.
The solution is to spawn an extra element that will drop to next line, then the first line will be justified:
<form>
<input type="text" value="" />
<input type="text" value="" />
<input type="text" value="" />
<input type="text" value="" />
</form>
form {
width: 800px;
text-align: justify; /* Can we really make this work? Sure! */
}
input {
display: inline-block; /* making elements respect text-align */
}
form:after {
content: ""; /* creating a hidden element that drops to next line */
display: inline-block; /* making it respect text-align and width */
width: 100%; /* forcing it to drop to next line */
}
Demo: http://jsbin.com/ituroj/5/ (click "edit" in top right corner to fiddle with the code).
Result: semantic, no HTML footprint, minimal CSS code, full browser support.
One approach would be:
input[type=text] {
width: 25%;
box-sizing: border-box;
}
Or, if the fields are really inside a <table/> like in this Fiddle, you can set the width of the textboxes to 100%, so the table controls the width:
input[type=text] {
width: 100%;
box-sizing: border-box;
}
You can do it by nesting the input and labels inside of 'columns' that you determine the width of by percentage - this way you can control the width of the form and the inputs will stay justified.
HTML
<form>
<div class="col4">
<label>Input</label>
<div class="inputWrapper">
<div class="textInput">
<input type="text"/>
</div>
</div>
</div>
<div class="col4">
<label>Input</label>
<div class="inputWrapper">
<div class="textInput">
<input type="text"/>
</div>
</div>
</div>
<div class="col4">
<label>Input</label>
<div class="inputWrapper">
<div class="textInput">
<input type="text"/>
</div>
</div>
</div>
<div class="col4 last">
<label>Input</label>
<div class="inputWrapper">
<div class="textInput">
<input type="text"/>
</div>
</div>
</div>
</form>
CSS
form{
width:800px;
}
.col4{
width:23.5%;
margin-right:2%;
float:left;
}
.last{
margin:0;
}
.inputWrapper{
width:100%;
}
.textInput{
border:1px solid #ccc;
display:block;
padding:5px;
}
.textInput input{
width:100%;
border:none;
padding:0;
}
You can see a jsFiddle example here http://jsfiddle.net/patricklyver/4mbks/
You can combine float with box-sizing. You will have to float, because forms have different weirdness around them in different browsers. For example in Safari on OS X there is always a hidden 1px padding on the top.
JSfiddle
HTML
<form id="myForm">
<input type="text" value="" />
<input type="text" value="" />
<input type="text" value="" />
<input type="text" value="" />
<div class="clear"></div>
</form>
CSS
#myForm {
border: 1px solid blue;
width: 800px;
}
#myForm input[type=text] {
margin: 0px;
display: block;
float: left;
box-sizing: border-box;
width: 25%;
border: 0px;
background-color: orange;
}
#myForm .clear {
clear: both;
}

I Want my Label to Vertically Align With my Input Field

Here is what my work is so far:
http://jsfiddle.net/2RCBQ/
<div id="main">
<form>
<label>First Name:<input type="text" id="firstname"></label><br/>
<label>Last Name:<input type="text" id="lastname"></label><br>
<label>E-Mail:<input type="text" id="email"></label><br/>
<label>Phone:<input type="text" id="phone"></label><br/>
</form>
</div>
CSS
#main {
width:300px;
}
#main input {
float:right;
display:inline;
}
#main label {
color: #2D2D2D;
font-size: 15px;
width:250px;
display: block;
}
Currently, the label (on the left) is kind of towards to top of the input field (on the right). I want to vertically align them so the label since in the middle of the input field.
I've tried vertical-align and it does not work. Please help me try to figure out the problem. Thanks.
I feel nesting <span> adds a lot of unnecessary markup.
display: inline-block lets the <label> and <input> sit next to each other just like with float: right but without breaking document flow. Plus it's much more flexible and allows more control over alignment if you (or the user's screen reader) want to change the font-size.
Edit: jsfiddle
label, input {
display: inline-block;
vertical-align: baseline;
width: 125px;
}
label {
color: #2D2D2D;
font-size: 15px;
}
form, input {
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
form {
width: 300px;
}
<form>
<label for="firstname">First Name:</label><input type="text" id="firstname">
<label for="lastname">Last Name:</label><input type="text" id="lastname">
<label for="email">E-Mail:</label><input type="text" id="email">
<label for="phone">Phone:</label><input type="text" id="phone">
</form>
You can use flexbox css to vertical align.
Just wrap the parent element display-flex.
.display-flex {
display: flex;
align-items: center;
}
html:
I add span in your label so we can add style specific for the text label:
<div id="main">
<form>
<label><span>First Name:</span><input type="text" id="firstname"></label><br/>
<label><span>Last Name:</span><input type="text" id="lastname"></label><br>
<label><span>E-Mail:</span><input type="text" id="email"></label><br/>
<label><span>Phone:</span><input type="text" id="phone"></label><br/>
</form>
</div>
css:
#main label span {
position:relative;
top:2px;
}
demo
You can enclose the <label> elements in a span and set the span's vertical-align to middle
HTML
<div id="main">
<form> <span><label>First Name:<input type="text" id="firstname" /></label></span>
<br/> <span><label>Last Name:<input type="text" id="lastname" /></label></span>
<br/> <span><label>E-Mail:<input type="text" id="email" /></label></span>
<br/> <span><label>Phone:<input type="text" id="phone" /></label></span>
<br/>
</form>
</div>
CSS
#main {
width:300px;
}
#main input {
float:right;
display:inline;
}
#main label {
color: #2D2D2D;
font-size: 15px;
}
#main span {
display: table-cell;
vertical-align: middle;
width:250px;
}
http://jsfiddle.net/2RCBQ/2/
I think that the following is the only method that works for all input types.
label { display: flex; align-items: center; }
input { margin: 0; padding: 0; }
<label><input type="checkbox"> HTML</label>
<label><input type="radio"> JS</label>
<label>CSS <input type="text"></label>
<label>Framework
<select><option selected>none</option></select>
</label>
I put because it seems to be the simplest way to align different input types; however, margins work just fine.
I know this is a super-old post, but I feel that the answers mix things and come to different solutions.
The original author asked about the label text's vertical alignment of implicit labelling; some answers solve this by using explicit labelling. I think this was not asked for.
See the difference between implicit vs. explicit labelling here: https://css-tricks.com/html-inputs-and-labels-a-love-story/#aa-how-to-pair-a-label-and-an-input
As I'm confronted every now and then I'd like to share my solution for implicit labelling.
The problem at explicit labelling is easily solved, since then you have your label as its own box and can apply any CSS of your liking to it rather independent of the associated input field.
However, at implicit labelling, the situation is different, since then the label text and the input are not separated items in this box. I think you do not have any other choice but to add a span around the text if you want to address the text independently from the input (note: you may not use a div here. Inside a label, only phrasing content elements are allowed: https://developer.mozilla.org/en-US/docs/Web/HTML/Content_categories#phrasing_content and div is not.)
This is what https://stackoverflow.com/a/15193954/8754067 stated above correctly, but the answer is lacking the dichotomy between implicit and explicit labelling. And has been not up-voted enough (at least in my personal view). Therefore, I feel the need to stress this again here.
form {
width: 400px;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
form label {
display: grid;
grid-template-columns: 10rem 1fr;
gap: 0.5rem;
min-width: 100%;
font-size: 15px;
/* increase height to see effect. */
height: 3rem;
}
form label span {
margin-block: auto;
}
<form>
<label><span>First Name (middle):</span><input type="text" id="firstname"></label>
<label><span>Last Name (middle):</span><input type="text" id="lastname"></label>
<label>E-Mail (default):<input type="text" id="email"></label>
<label>Phone (default):<input type="text" id="phone"></label>
</form>