Aligning grid based form elements and their labels
Here is the fiddle: http://jsfiddle.net/nJZ6Y/19/
You have to add a span
inside each label
, then add these CSS rules.
label {
min-height: 3em;
}
label span {
vertical-align: -3em;
display: inline-block;
}
Aligning form labels in a CSS grid?
Adjust your HTML code to always keep the structure (label then input). You can also simplify your grid by having ony 2 columns and consider a gap:
@import url("https://fonts.googleapis.com/css?family=Lato:400,400i,700");body { font-family: "Lato", sans-serif; color: #fafafa;}
form { display: grid; grid-template-columns: 1fr 2fr; grid-gap: 1em; border-radius: 12px; padding: 1em; background: #009688; margin: 2rem auto 0 auto; max-width: 600px; align-items: center;}
form input { background: #fff; border: 1px solid #9c9c9c;}
form button { background: lightgrey; padding: 0.7em; width: 100%; border: 0;}
form button:hover { background: gold;}
label { padding: 0.5em 0.5em 0.5em 0;}
input { padding: 0.7em; margin-bottom: 0.5rem;}
input:focus { outline: 3px solid gold;}
select { height: 100%;}
@media (min-width: 400px) { form { grid-gap: 16px; } label { text-align: right; grid-column: 1; } input[type="checkbox"] { justify-self: start; margin: 0; } input, button { grid-column: 2; } textarea+label { align-self: start; }}
<form class="form1" action=""> <label for="firstName" class="first-name">First Name</label> <input id="firstName" type="text">
<label for="lastName" class="last-name">Last Name</label> <input id="lastName" type="text">
<label for="email">Email</label> <input id="email" type="text"> <label for="experience">Experience</label> <select id="experience" name="experience"> <option value="1">Less than a year</option> <option value="2">1 - 2 years</option> <option value="3">3 - 5 years</option> <option value="5">5 years or more</option> </select>
<label for="bootcamp">Bootcamp</label> <input id="bootcamp" name="bootcamp" type="checkbox">
<label for="tech">Tech School</label> <input id="tech" name="tech" type="checkbox">
<label for="college">College</label> <input id="college" name="college" type="checkbox">
<label for="comments">Comments</label> <textarea id="comments" name="comments" rows="5" cols="20"></textarea>
<button>Submit</button></form>
Use grid to align wrapped form labels and inputs
More suitable for a table layout than a grid one:
form {
display: table;
border-spacing: 5px;
}
form>div {
display: table-row;
}
label {
display: table-cell;
text-align: right;
}
input[type=checkbox] {
vertical-align: bottom;
margin-left:0;
}
<form>
<div>
<label>Name: </label>
<input type="text">
</div>
<div>
<label>Mileage: </label>
<input type="number">
</div>
<div>
<label>Track: </label>
<input type="checkbox">
</div>
</form>
Align labels in form next to input
While the solutions here are workable, more recent technology has made for what I think is a better solution. CSS Grid Layout allows us to structure a more elegant solution.
The CSS below provides a 2-column "settings" structure, where the first column is expected to be a right-aligned label, followed by some content in the second column. More complicated content can be presented in the second column by wrapping it in a <div>.
[As a side-note: I use CSS to add the ':' that trails each label, as this is a stylistic element - my preference.]
/* CSS */
div.settings { display:grid; grid-template-columns: max-content max-content; grid-gap:5px;}div.settings label { text-align:right; }div.settings label:after { content: ":"; }
<!-- HTML -->
<div class="settings"> <label>Label #1</label> <input type="text" />
<label>Long Label #2</label> <span>Display content</span>
<label>Label #3</label> <input type="text" /></div>
Elements in Grid Layout Form Won't Align
I think you misunderstood how grid
works, you need a wrapper or container that will display its content in a grid, what you did was put the display: grid
on the elements themselves
.grid-wrapper {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 2rem;
padding-top: 1rem;
align-items : flex-start;
}
.form-group {
grid-column: 1;
}
.form-details {
grid-column: 2;
}
.form-details h2 {
margin-top : 0;
}
<div class="grid-wrapper">
<form action="" method="post">
<div class="form-list">
<div class="form-group">
<label for="name" class="form-label">Name</label>
<input id="name" name="name" type="text" placeholder="Your name" class="form-control" required />
</div>
<div class="form-group">
<label for="email" class="form-label">Email</label>
<input id="email" name="email" type="text" placeholder="youremail@email.com" class="form-control" required />
</div>
<div class="form-group">
<label for="message" class="form-label">Message</label>
<textarea id="message" name="message" rows="4" class="message-control" required></textarea>
</div>
<div class="form-group">
<button type="submit" class="button">Contact us</button>
</div>
</div>
</form>
<div class="form-contact">
<div class="form-details">
<h2>Contact</h2>
<p><span>456 Random Street,</span><span>Sydney,</span>
<span>Australia</span></p>
<p><span>Phone: 024 123 45678</span><span>Email: sales@website.co.nz</span></p>
</div>
</div>
</div>
Best way to arrange labels and inputs side-by-side
align-items: stretch
Flexbox has a feature commonly known as "equal height columns". This feature enables flex items in the same container to all be equal height.
This feature comes from two initial settings:
flex-direction: row
align-items: stretch
With a slight modification, this feature can become "equal width rows".
flex-direction: column
align-items: stretch
Now a column of flex items will have the width of the longest item.
Reference:
- Equal Height Columns with Flexbox
align-content: stretch
An initial setting on a flex container is align-content: stretch
. This setting will distribute rows or columns (depending on flex-direction
) across the length of the container.
In this case, in order to pack two columns to the start of the container, we need to override the default with align-content: flex-start
.
References:
- Remove space (gaps) between multiple lines of flex items when they wrap
- How does flex-wrap work with align-self, align-items and align-content?
flex-direction: column
, flex-wrap: wrap
and height
Since you have a preferred HTML structure (with all form elements logically ordered in one container), flex items will need to wrap in order to form a column of labels and a column of inputs.
So we need to override flex-wrap: nowrap
(the default) with wrap
.
Also, the container must have a fixed height so that items know where to wrap.
References:
- Is it possible for flex items to align tightly to the items above them?
- Make a div span two rows in a grid
The order
property
The order
property is needed to properly align labels and inputs across columns.
Reference:
- Is there a “previous sibling” CSS selector?
.aligned_form { display: flex; flex-flow: column wrap; align-content: flex-start; height: 75px;}
label[for='a'] { order: -3; }label[for='b'] { order: -2; }label[for='c'] { order: -1; }
label, input { height: 25px; padding: 5px; box-sizing: border-box;}
<!-- No changes to the HTML. -->
<div class='aligned_form'>
<label for='a'>short_label</label> <input type='text' id='a' placeholder="short_label">
<label for='b'>medium_label</label> <input type='text' id='b' placeholder="medium_label">
<label for='c'>very_extra_long_label</label> <input type='text' id='c' placeholder="very_extra_long_label">
</div>
Align labels in form next to input
While the solutions here are workable, more recent technology has made for what I think is a better solution. CSS Grid Layout allows us to structure a more elegant solution.
The CSS below provides a 2-column "settings" structure, where the first column is expected to be a right-aligned label, followed by some content in the second column. More complicated content can be presented in the second column by wrapping it in a <div>.
[As a side-note: I use CSS to add the ':' that trails each label, as this is a stylistic element - my preference.]
/* CSS */
div.settings { display:grid; grid-template-columns: max-content max-content; grid-gap:5px;}div.settings label { text-align:right; }div.settings label:after { content: ":"; }
<!-- HTML -->
<div class="settings"> <label>Label #1</label> <input type="text" />
<label>Long Label #2</label> <span>Display content</span>
<label>Label #3</label> <input type="text" /></div>
Related Topics
Shiny Presentation (iOSlides): Custom CSS and Logo Windows 7/8
Issue with Embedded Svg Images in Dark Mode
How to Display Block Div on Hover a Tag
Make Maven Serve Files Like CSS.Gz and Js.Gz
How to Replace The Web Font with Svg Icon in CSS(Font Awesome)
Exclude Menu Item from Collapsing Bootsrap
How to Create Inline Style with: Before and: After
Sass Mixin for Background Transparency Back to Ie8
How to Do a 'Float: Left' with No Wrapping
How to Use "Flex-Flow: Column Wrap"
Tell Less to Not Freak Out in Certain Special Cases and Ignore Weird Characters
Why Does My Site Change My CSS for Me
CSS - How to Make Responsive Images
What CSS Properties Can Be Animated
Ie Bug: Absolutely-Positioned Element with a Non-Transparent Background Colour
Different Behaviours for Col-Lg