CSS grid auto-fill with always two columns - css

I have a grid container that has multiple labels and inputs. Is it possible to configure the grid in a way that it auto-fills the space with always two columns so that the label breaks the line with its corresponding input?
Grid before resize:
Label
Input
Label
Input
Label
Input
Grid after resize:
Label
Input
Label
Input
Label
Input

Simply wrap inputs inside their label:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap:5px;
}
input{
width:50%;
float:right;
}
<div class="grid">
<label>label <input type="text"></label>
<label>label <input type="text"></label>
<label>label <input type="text"></label>
<label>label <input type="text"></label>
<label>label <input type="text"></label>
<label>label <input type="text"></label>
</div>

You can provide multiple tracks in the second argument of repeat and it will always fill to a multiple of that number of tracks.
In the case of auto-fill the tracks must be <fixed-length>. It is explained better by MDN repeat() docs including auto-fill
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(50px, max-content) minmax(50px, max-content));
grid-gap:5px;
}
<div class="grid">
<label>label</label> <input type="text">
<label>label</label> <input type="text">
<label>label</label> <input type="text">
<label>label</label> <input type="text">
<label>label</label> <input type="text">
<label>label</label> <input type="text">
</div>

Related

CSS center positioning

I have kind of difficult css positioning for me and need help.
The problem is a have a row of div with flex-wrap: wrap. (picture 1)
Each div have 50% width so we have 2 columns.
I need each input of 2 element in row have to be on the the same position. (picture 2)
You can see that all element on the same label, independent of title's height and error's height.
I tried to use align-items: flex-start/end, but it doesn't work cause if you use start you depend on title's height and if you use flex-end then you depend on error's height. In both way moved on the different level.
I hope that I explained clear.
Can you tell me how I can achieve this behavior?
I tried to use different flex-items properties value, but it didn't work.
I would appreciate if you tell me how to place divs like on the picture 2.
I created a pen to demonstrate how this can be done with CSS Grid, but for those that want to see the code, here it is:
<form class="form">
<div class="form-group">
<label for="1">Input label</label>
<input id="1" type="text">
</div>
<div class="form-group">
<label for="2">Input label</label>
<input id="2" type="text">
<div>Some error, maybe long</div>
</div>
<div class="form-group">
<label for="3">Input label</label>
<input id="3" type="text">
</div>
<div class="form-group">
<label for="4">Input label</label>
<input id="4" type="text">
<div>A really, lreally looooooong error message that wraps onto multiple lines and may never happen in real life</div>
</div>
</div>
<div class="form-group">
<label for="5">Input label that is running onto multiple lines and is the root of the issue</label>
<input id="5" type="text">
<div>A really, lreally looooooong error message that wraps onto multiple lines and may never happen in real life</div>
</div>
<div class="form-group">
<label for="6">Input label</label>
<input id="6" type="text">
</div>
</form>
.form {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 1rem;
}
.form-group {
display: grid;
grid-template-rows: 1fr auto 1fr;
}
label {
font-weight: bold;
align-self: end;
}
The use of grid-template-rows, and not aligning elements using the grid container is the secret here.

Elements going outside of grid layout [duplicate]

This question already has an answer here:
Why does minmax(0, 1fr) work for long elements while 1fr doesn't?
(1 answer)
Closed 7 months ago.
The form has a fixed width of 300px with a grid layout. I have made it two columns by
grid-template-columns: repeat(2, 1fr) , and I have also tried grid-template-columns: auto auto , but the elements are still going outside of the form.
How to make the elements auto-adjust their width to suit the form width?
form {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 30px;
background-color: green;
width: 300px;
}
textarea {
grid-column: span 2 / span 2;
}
<form>
<input placeholder="First Name" type="text" name="first_name" required>
<input placeholder="Last Name" type="text" name="last_name" required>
<textarea placeholder="Message" name="message" rows="5"></textarea>
<input type="submit" value="Submit">
</form>
1fr means minmax(auto, 1fr) which is a well-known concern here. In your context, auto is not obvious, and that causes unexpected widths for your input fields.
To fix it, you should set grid-template-columns: repeat(2, minmax(0, 1fr)); instead.
form {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 30px;
background-color: green;
width: 300px;
}
textarea {
grid-column: span 2 / span 2;
}
<form>
<input placeholder="First Name" type="text" name="first_name" required>
<input placeholder="Last Name" type="text" name="last_name" required>
<textarea placeholder="Message" name="message" rows="5"></textarea>
<input type="submit" value="Submit">
</form>
You will need to set the overflow of any child elements to a value other than the default of visible.
form input {
overflow: hidden; // New
}
form {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(min-content, max-content);
gap: 30px;
background-color: green;
width: 300px;
}
textarea {
grid-column: span 2 / span 2;
}
<form>
<input placeholder="First Name" type="text" name="first_name" required>
<input placeholder="Last Name" type="text" name="last_name" required>
<textarea placeholder="Message" name="message" rows="5"></textarea>
<input type="submit" value="Submit">
</form>

Flexbox: justify-content ignored when row wraps and/or items consist of user inputs

I have referenced this article on flexbox referred to me earlier today. https://css-tricks.com/snippets/css/a-guide-to-flexbox/
So far, flex has behaved as documented, except for in the following case where the box wraps its items and/or the items are inputs/selects. Here is an example:
#searchbar {
border: solid 1px LightGray;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 100%;
}
.searchbar-control {
display: inline !important;
margin-bottom: 3px;
width: 40%;
}
<div id="searchbar">
<input type="text" class="searchbar-control" value="1">
<input type="text" class="searchbar-control" value="2">
<input type="text" class="searchbar-control" value="3">
<input type="text" class="searchbar-control" value="4">
<input type="text" class="searchbar-control" value="5">
<input type="text" class="searchbar-control" value="6">
<input type="text" class="searchbar-control" value="7">
<input type="text" class="searchbar-control" value="8">
</div>
I expect the box to contain 2 controls per row. 1 & 2 on the first row, 3 & 4 on the second row, etc. So far, so good. However, I am finding that justify-content is ignored no matter what value is used. In addition, flex-wrap (nowrap/wrap) are ignored. It looks like align-items is also ignored.
I haven't had this issue on flex boxes with elements which are not user inputs.
I want to see 2 items per row, and I want there to be 3 equal-width spaces: left/middle/right.
Widths for form elements (especially when mixing <input>s and <select>s) can be a bit fidgety. I've found that using the CSS style box-sizing: border-box can help standardize the widths:
#searchbar {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
border: solid 1px lightgray;
}
.searchbar-control {
box-sizing: border-box;
margin-bottom: 3px;
width: 40%;
}
<div id="searchbar">
<select class="searchbar-control">
<option value="1" selected></option>
<option value="2" selected></option>
</select>
<input type="text" class="searchbar-control" value="2">
<input type="text" class="searchbar-control" value="3">
<select class="searchbar-control">
<option value="3" selected></option>
<option value="4" selected></option>
</select>
<input type="text" class="searchbar-control" value="5">
<input type="text" class="searchbar-control" value="6">
<input type="text" class="searchbar-control" value="7">
<input type="text" class="searchbar-control" value="8">
</div>

Bootstrap : horizontal fields inside vertical form

I'd like to have some "horizontally styled" fields inside a "vertically styled" form with Bootstrap.
How can I do that (if possible)?
You can leverage Bootstrap's existing classes (checkbox.inline)to get the effect you're looking for. The key to making it look right is to specify padding-left: 0px; on the labels:
<div class="control-group">
<div class="controls">
<label class="checkbox inline" style="padding-left: 0px;" for="inputColor">Favorite Color <input type="text" id="inputColor" class="span2" /></label>
<label class="checkbox inline" style="padding-left: 0px;" for="inputNColor">Next Color <input type="text" id="inputNColor" class="span2" /></label>
</div>
</div>
Please see http://jsfiddle.net/jhfrench/Hzucn/ for a working example.
I tried to create a new class for you (along the lines of .controls-row label.inline { padding-left: 0px;} so you wouldn't have to do styling on the element, but it caused more conflicts than I anticipated. So if you're going to use this solution pervasively, you might want to invest the time in untangling that...
You can use similar formatting to .form-horizontal implementation in bootstrap. (scroll sown to Horizontal Forms here: http://twitter.github.com/bootstrap/base-css.html#forms)
Wrap your labels and form elements in grouping divs (that's what .control-group does in Horizontal Form layout in bootstrap).
Float labels left to show them in horizontal alignment with the fields.
label.horizontal {
float: left;
width: 160px;
padding-top: 5px;
margin-right: 20px;
text-align: right;
}
In the above example, labels with class .horizontal will be "horizontally styled" and the rest "vertical" or default form layout.
there is a class ready to use on bootstrap!
check this example:
<div class="span6">
<form>
<div class="controls controls-row">
<input id="name" name="name" type="text" class="span3" placeholder="Name">
<input id="email" name="email" type="email" class="span3" placeholder="Email address">
</div>
<div class="controls">
<textarea id="message" name="message" class="span6" placeholder="Your Message" rows="5"></textarea>
</div>
<div class="controls">
<button id="contact-submit" type="submit" class="btn btn-primary input-medium pull-right">Send</button>
</div>
</form>
</div>

Forcing label to flow inline with input that they label

I need the label to stay on the same line as the input field they are labeling. I want these elements to flow like they normally would when the window resizes, i just want the label to stick to the left of the input they are labeling. How would I do that? Any ideas?
<label for="id1">label1:</label>
<input type="text" id="id1"/>
<label for="id2">label2:</label>
<input type="text" id="id2"/>
ANSWERED: Josiah Ruddell's answer was on the right path, using a span instead of div gave me the correct behavior. Thanks!
<span style="white-space:nowrap">
<label for="id1">label1:</label>
<input type="text" id="id1"/>
</span>
<span style="white-space:nowrap">
<label for="id2">label2:</label>
<input type="text" id="id2"/>
</span>
put them both inside a div with nowrap.
<div style="white-space:nowrap">
<label for="id1">label1:</label>
<input type="text" id="id1"/>
</div>
Put the input in the label, and ditch the for attribute
<label>
label1:
<input type="text" id="id1" name="whatever" />
</label>
But of course, what if you want to style the text? Just use a span.
<label id="id1">
<span>label1:</span>
<input type="text" name="whatever" />
</label>
<style>
.nowrap {
white-space: nowrap;
}
</style>
...
<label for="id1" class="nowrap">label1:
<input type="text" id="id1"/>
</label>
Wrap your inputs within the label tag
http://jsfiddle.net/jwB2Y/123/
The following CSS class force the label text to flow inline and get clipped if its length is more than max-length of the label.
.inline-label {
white-space: nowrap;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
float:left;
}
HTML:
<div>
<label for="id1" class="inline-label">This is the dummy text i want to display::</label>
<input type="text" id="id1"/>
</div>
If you want they to be paragraph, then use it.
<p><label for="id1">label1:</label> <input type="text" id="id1"/></p>
<p><label for="id2">label2:</label> <input type="text" id="id2"/></p>
Both <label> and <input> are paragraph and flow content so you can insert as paragraph elements and as block elements.
What I did so that input didn't take up the whole line, and be able to place the input in a paragraph, I used a span tag and display to inline-block
html:
<span>cluster:
<input class="short-input" type="text" name="cluster">
</span>
css:
span{display: inline-block;}
Why don't You just use:
label {
display: block;
width: 50px;
height: 24px;
float: left;
}

Resources