I have a very simple HTML layout I'm trying to implement. It is something like this:
A Label: [Input ]
Another Label: [Input ]
The Last Label: [Input ]
In the past, I'd just go ahead and use a table for this. Otherwise, it's a pain getting the input controls to line up correctly.
Can anyone suggest a simple and reliable way to implement this layout without using a table?
Thanks.
You can use display: inline-block
<style type="text/css">
label { display: inline-block; width: 200px; }
ul { list-style: none; }
</style>
<ul>
<li><label for="input1">A Label:</label> <input type="text" name="input1" id="input1"></li>
<li><label for="input2">Another Label:</label> <input type="text" name="input2" id="input2"></li>
<li><label for="input3">The Last Label:</label> <input type="text" name="input3" id="input3"></li>
</ul>
However, in order for this to line up vertically, you either have to wrap the label-input pairs in another tag (such as <li> or <div>) or put linebreaks after the inputs.
<style>
label { width: 200px; float:left; clear:left; }
input { float:left;}
</style>
<form>
<label for="fullname">Full Name:</label>
<input type="text" name="fullname" id="fullname">
<label for="email">Email Address:</label>
<input type="text" name="email" id="email">
</form>
With the added benefit that, if the horizontal space isn't sufficient, the inputs will wrap below the labels.
http://jsbin.com/anuziq (narrow down your browser window)
If you don't actually want them to wrap around, I suggest this approach:
<style>
label { white-space: nowrap; }
span { width: 200px; display: inline-block; }
</style>
<form>
<label>
<span>Full Name:</span>
<input type="text" name="fullname">
</label>
<label>
<span>Email Address:</span>
<input type="text" name="email">
</label>
</form>
From my experience, structuring the HTML like that usually allows for any layout you can possibly think of. Want the inputs always below the label? Use display:block on the span elements. Want the text to the right of the input? Just use float:right on the span.
Bonus here is that you don't need the for and id attributes to connect the label with the input. They're only really necessary, if you can't put the label right next to the input, like in 2 separate table cells.
Related
I have a simple form like this:
<form method="post" action="/registration">
<label for="alias">Alias:</label>
<input type="text" name="alias" id="alias">
<br>
<label for="email">E-mail:</label>
<input type="text" name="email" id="email">
<br>
<input type="button" value="registger">
</form>
It works fine, but the I have found out that <br> shouldn't be used for this purpose, as it is only intended to be used with text.
If I remove the <br>, then everything will be rendered on a single line, which I do not want.
What is the correct, most clean way to display name-input pairs in a form with CSS, like this:
Alias: [__field__]
E-mail: [__field__]
[SUBMIT BUTTON]
I'd use divs, which will put the labels and inputs into their own block.
<form method="post" action="/registration">
<div>
<label for="alias">Alias:</label>
<input type="text" name="alias" id="alias">
</div>
<div>
<label for="email">E-mail:</label>
<input type="text" name="email" id="email">
</div>
<input type="button" value="registger">
</form>
I typically would put the input inside of the label (so when you click the label, it focuses the input), and then tell the label to be display: block;.
So,
<form method="post" action="/registration">
<label for="alias">
Alias: <input type="text" name="alias" id="alias">
</label>
<label for="email">
E-mail: <input type="text" name="email" id="email">
</label>
<input type="button" value="registger">
</form>
Then do:
label[for], // just selects labels that have the "for" attribute.
input[type="button"] {
display: block;
// And a bottom margin for good measure :)
margin: 0 0 10px; // shorthand for margin-bottom
}
And that should get you what you want.
You could use divs with corresponding CSS:
.myFrm {
width: 250px;
}
input[type=text] {
float: right;
}
.form-group {
margin-bottom: 10px;
}
.form-group::after {
content: "";
clear: both;
display: table;
}
<form method="post" action="/registration">
<div class="myFrm">
<div class="form-group">
<label for="alias">Alias:</label>
<input type="text" name="alias" id="alias">
</div>
<div class="form-group">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email">
</div>
</div>
<input type="button" value="registger">
</form>
I would just use a bit of css to do the trick. Give each of the labels a display:block;
label {
display: block;
}
You can use container divs around the label and input to group them or else make sure "display: block" is added to the label and input elements.
If you need the label to the left of the input then wrap both with a container div and to give you more control on the positioning you could float the label and input to the left or use flexbox.
You ask:
What is the correct, most clean way to display name-input pairs in a
form with CSS
I interpret your question to be related to matters of performance, code efficiency and maintainability. Since just changing the HTML structure does not address responsiveness in different view-ports, adding bits of CSS may have render blocking features but it does nevertheless makes your application ready for mobile responsiveness. This is how I see it:
form {
display: inline-block;
}
label {
margin: 10px;
font-weight: 600;
}
input{
position: absolute;
left: 15%;
}
input[type=button]{
top: 4%;
}
Note that for mobile viewports you may want to adjust the relative measures with media queries. So the question here is not about writing less code but the main requirements of the application.
Get a plunk for this here
What you have there is a list.
https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/HTML_text_fundamentals#Lists
http://reisio.com/temp/form1.html
I'm making an HTML page with a list of fields for filling out billing info.
Since the labels are in-line, their width is determined by the text contained in them, thus making them different widths which makes the input boxes unaligned. This makes a very ugly, unorganized look.
<fieldset>
<legend>Billing Information</legend><br>
Card Number: <input type="text"><br><br>
Expiration Month: <input type="number"><br><br>
Expiration Year: <input type="number"><br><br>
Name on Card: <input type="text"><br><br>
Address: <input type="text"><br><br>
City: <input type="text"><br><br>
State: <input type="text"><br><br>
Country: <input type="text"><br><br>
ZIP Code: <input type="number"><br><br>
</fieldset><br>
What do I need to do to my HTML code to align the right side of the labels and the left side of the input boxes?
Use table structure for your lists of fields for proper alignment.
<fieldset>
<legend>Billing Information</legend>
<table>
<tr><td>Card Number:</td><td><input type="text"></td></tr>
<tr><td>Expiration Month:</td><td> <input type="number"></td></tr>
<tr><td>Expiration Year:</td><td> <input type="number"></td></tr>
<tr><td>Name on Card:</td><td> <input type="text"></td></tr>
<tr><td>Address:</td><td> <input type="text"></td></tr>
<tr><td>City:</td><td> <input type="text"></td></tr>
<tr><td>State:</td><td> <input type="text"></td></tr>
<tr><td>Country:</td><td> <input type="text"></td></tr>
<tr><td>ZIP Code:</td><td> <input type="number"></td></tr>
</table>
</fieldset>
You can use tables or use display: table-row & display: table-cell css to simulate table cell layouts as following:
fieldset {display: inline-block; padding: 10px 20px;} /* 'display: inline-block' is not necessary, just for appearance */
.row {display: table-row; }
.lbl {display: table-cell; text-align:right; padding: 8px 5px;}
<fieldset>
<legend>Billing Information</legend>
<div class="row"><span class="lbl">Card Number: </span><input type="text"></div>
<div class="row"><span class="lbl">Expiration Month: </span><input type="number"></div>
<div class="row"><span class="lbl">Expiration Year: </span><input type="number"></div>
<!-- ... /-->
</fieldset><br>
You will find it much easier if you put your elements into suitable containers and use CSS to do the hard work.
<style type="text/css">
label {
display: inline-block;
font-weight: bold;
width: 10em;
}
</style>
<fieldset>
<legend>Billing Information</legend><br>
<p><label for="card-number">Card Number:</label><input type="text" name="card-number" id="card-number"></p>
<p><label for="expiration-month">Expiration Month:</label><input type="text" name="expiration-month" id="expiration-month"></p>
<!-- etc -->
</fieldset>
Here the label does 3 jobs:
It creates a clickable text to activate your input box.
It makes the purpose of the text clear for screen readers and other software.
You can easily apply CSS to the element.
The label element can either be wrapped around the input element:
<label>Expiration Month: <input …></label>
or attached with the for attribute. The for attribute references an id, which is independent of the name attribute. As you see in the example, they are often set to the same value.
In the CSS, we set the width to something reasonable. However, the label needs to be displayed as an inline-block for the width to take effect.
Use flexbox to fix your problem.
Wrap the container fieldset using display: flex, Set the flex-direction as column. Wrap the children inside a div and set the flex-grow property for the span element as 1.
Using flexbox will take care of responsiveness.
Refer CSS Flexbox
fieldset {
display: flex;
flex-direction: column;
}
div {
display: flex;
margin: 10px;
}
span {
flex: 1;
}
<fieldset>
<legend>Billing Information</legend>
<div><span>Card Number: </span><input type="text"> </div>
<div><span>Expiration Month:</span> <input type="number"></div>
<div><span> Expiration Year:</span> <input type="number"></div>
<div><span>Name on Card:</span> <input type="text"> </div>
<div><span>Address:</span> <input type="text"> </div>
<div><span>City:</span> <input type="text"></div>
<div><span>State: </span><input type="text"></div>
<div><span>Country:</span> <input type="text"></div>
<div><span>ZIP Code:</span> <input type="number"></div>
</fieldset>
Suppose I have a web page with a form:
<form>
<label for="FirstName">First:</label>
<input name="FirstName" type="text">
<label for="MiddleName">Middle:</label>
<input name="MiddleName" type="text">
<label for="LastName">Last:</label>
<input name="LastName" type="text">
</form>
If I size the browser window small enough, I get a line break between the label that says "Middle:" and the "MiddleName" input. It would be better to put a break between labels and input fields that are not related, e.g. break between "FirstName" input and label for "MiddleName", and/or between input "MiddleName" and label for "LastName". Obviously I can add <br/> tags, but is there a good way to keep the related items together, and still use only 1 line when the browser window is wide enough?
I realize this is a contrived example, but this is pattern I am having trouble with in several more complicated real world forms.
Put the inputs inside the labels, you don't even need the for attributes. Then style the labels with white-space: nowrap to prevent automatic line breaks.
label { white-space: nowrap; }
<form>
<label>First: <input name="FirstName" type="text"></label>
<label>Middle: <input name="MiddleName" type="text"></label>
<label>Last: <input name="LastName" type="text"></label>
</form>
Surround the related elements within an wrapper and then prevent line breaks inside the wrapper with CSS:
.wrapper {
white-space: nowrap;
}
<form>
<span class="wrapper">
<label for="FirstName">First:</label>
<input name="FirstName" type="text" />
</span>
<span class="wrapper">
<label for="MiddleName">Middle:</label>
<input name="MiddleName" type="text" />
</span>
<span class="wrapper">
<label for="LastName">Last:</label>
<input name="LastName" type="text" />
</span>
</form>
You can surround each set with a wrapper that is display: inline-block;
.wrap {
display: inline-block;
/* Only include this if
you don't want the text within the spans
to wrap when the window is small enough
*/
white-space: nowrap;
}
<form>
<span class="wrap">
<label for="FirstName">First:</label>
<input name="FirstName" type="text" />
</span>
<span class="wrap">
<label for="MiddleName">Middle:</label>
<input name="MiddleName" type="text" />
</span>
<span class="wrap">
<label for="LastName">Last:</label>
<input name="LastName" type="text" />
</span>
</form>
I use getuikit for form styling, they do it with something like this:
HTML
<label>My label</label>
<div class="controls"><input type=text/></div>
CSS
label {
float:left;
margin-top:5px; //to center the label vertically
width: 200px;
}
.controls {
margin-left:200px;
}
It doesn't break semantics. Putting input inside label is little strange :)
I want to design a nice form for my webpage, which I want to resemble something like this.
Basically, I want that the text describing the input field as well as the input fields have some predefined width. I am not using a table layout for my forms, instead I am using the label for approach.
What happens is something like this
I can set the size for the text field as I have done. I don't know how to deal with setting a width for the text or the label. The html goes something like this:
<form class="myform" method="POST" action="./php/prescribe.php">
<label for="fname">First Name :</label>
<input type="password" name="fname" size="35"><br>
<label for="fname">Give your email address :</label>
<input type="password" name="lname" size="35"><br>
<label for="fname">First Name :</label>
<input type="password" name="fname" size="35"><br>
<label for="fname">First Name :</label>
<input type="password" name="fname" size="35"><br>
</form>
Use CSS. Also, you would want to use a wrapper around each row. Here's a quick and dirty example.
CSS:
.form-row{}
.form-row-alt {} /* add alternating color here */
.form-row label, .form-row-alt label { display: inline-block; width: 150px; }
HTML:
<div class="form-row">
<label>First Name:</label>
<input type="text" name="username" />
</div>
You could float the labels:
.myform label {
float: left;
clear: both;
width: 12em; /* or whatever */
}
Floats can be a little irritating because old IE versions sometimes do stupid things.
Or you could use display: inline-block, which I prefer:
.myform label {
display: inline-block;
width: 12em; /* or whatever */
}
With that, you'd need to add <br> elements between the inputs, which some might consider unpleasant.
Another alternative would be to use a <dl> block for the whole thing, though that really doesn't change the basic problem.
How do I correct the following E-mail textbox alignment: ?
To make it look like this:
I know I can use tables, but how do I solve this problem without using tables? CSS maybe?
HTML:
<form action="" name="contactform" method="post">
<p></p>
First name: <input type="text" class="contact" name="contactfirstname" value="">
<br/>
Last name: <input type="text" class="contact" name="contactlastname" value="">
<br/>
E-mail: <input type="text" class="contact" name="email" value="">
<p></p>
The most minimalized version I could think of...
<form>
<label>First Name: <input type="text" name="firstName"></label>
<label>Last Name: <input type="text" name="lastName"></label>
<label>Email Address: <input type="email" name="emailAddress"></label>
</form>
and
form {
width: 300px;
}
label {
display: block;
margin: 5px;
padding: 5px;
clear: both;
}
label input {
float: right;
}
Since OP has edited his question to include his markup, I'll expand the answer.
Some Points of Improvement:
Remove the empty <p> element, and the <br/> elements. They have no value inside a form.
Use <label>s, that's what they were made for. You can wrap the label and the input inside of the <label> tag, or you can use <label for="element_id">Label</label><input id="element_id">.
Be consistent. If you decided to go with the <br /> type of format for singular tags, stick with it to the <input />s as well.
Use correct input types for specific inputs, there is type="email" for the email field, which will optionally have the browser check for you if it's a valid email address or not!.
Use CSS for design and layout, not <p>s and <br>s.
Good luck!
I'm assuming your HTML is something like:
<p>
Email
<input />
</p>
Change this to:
<p>
<label>Email</label>
<input />
</p>
This means you can then apply a fixed width to all your labels, making them consistent:
label
{
width:100px;
float:left;
}
http://jsfiddle.net/zvWqk/1/
Or as #Zeta has pointed out, nest your input inside the label, and float right. This will prevent you needing to apply a for attribute to your label.
http://jsfiddle.net/tt8gx/
Use CSS to make the labels display as block elements and have a fixed width. Display the inputs as block elements and float them left. Put a clear:left on the labels so they'll each be on a new line.