Aligning Grid Based Form Elements and Their Labels

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



Leave a reply



Submit