CSS - Align div elements in three columns - html

I am trying to align a list of labels, input radios and icons. The alignment should be:
Label Icon
() LongLabel Icon
() Label Icon
Here my code:
div.mygrid {
display:grid;
grid-template-columns: max-content max-content;
grid-gap:5px;
}
div.mygrid > div > label { text-align:left; }
<div class="mygrid">
<div>
<label> Long Text #1</label>
<i>Colum2</i>
</div>
<div>
<label><input type="radio">Label #2</label>
<i>Colum2</i>
</div>
<div>
<label><input type="radio">Label #3</label>
<i>Colum2</i>
</div>
</div>
Also I find awful to define spaces to replace the space of the radiobutton:
<label> Long Text #1</label>
Any idea how can I achieve that?

If you don't insist on using Grid, I propose a solution similar to the following (should be self-explanatory). Adjust values (width and padding) as needed.
label {
text-align: left;
display: inline-block;
width: 160px;
}
label.L1 {
padding-left: 30px;
}
input[type="radio"] {
width: 30px;
margin: 0;
}
i {
width: 200px;
}
<div class="mygrid">
<div>
<label class="L1">Long Text #1</label>
<i>Colum2</i>
</div>
<div>
<input type="radio"><label>Label #2</label>
<i>Colum2</i>
</div>
<div>
<input type="radio"><label>Label #3</label>
<i>Colum2</i>
</div>
</div>

div.mygrid {
display:flex;
flex-direction: column;
}
div.mygrid > div > label { text-align:left; }
.ml-3 {
margin-left: 17px;
}
<div class="mygrid">
<div class="ml-3">
<label>Long Text #1</label>
<i>Colum2</i>
</div>
<div>
<label><input type="radio">Label #2</label>
<i>Colum2</i>
</div>
<div>
<label><input type="radio">Label #3</label>
<i>Colum2</i>
</div>
</div>

Related

Checkboxes aligned on row

I have multiple checkboxes and everyone is displayed on a row. I want to have 3 or 4 checkboxes on a row, but I can't do it.
Angular:
<div class="form">
<mat-label>Choose skills:</mat-label>
<div class="container">
<div *ngFor="let skill of listOfSkills; index as i" id="skills">
<input type="checkbox" (change)="getSkill($event,i)">{{skill}}
</div>
</div>
</div>
CSS:
.container input[type=checkbox]{
display:inline-block;
width: 200px;
text-align: center;
}
Base on your question, maybe I can understand as you try to align all checkbox inside a container div ? Not sure is this what you looking for ?
div{
display:flex;
align-items:center;
}
input{
margin-right:10px;
}
input:last-child{
margin-right:0px;
}
<div>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
</div>
Your css sets the display property to inline-block on the input tag, but the surrounding div tag is still a block element and therefore will always wrap.
Your css should look like this:
css:
.container .checkbox {
display:inline-block;
width: 200px;
text-align: center;
}
html:
<div class="form">
<mat-label>Choose skills:</mat-label>
<div class="container">
<div *ngFor="let skill of listOfSkills; index as i" class="checkbox">
<input type="checkbox" (change)="getSkill($event,i)">{{skill}}
</div>
</div>
</div>

Use grid to align wrapped form labels and inputs

I am using grid layout to align form labels and inputs vertically:
form {
display: grid;
width: 10%;
grid-template-columns: repeat(2, 1fr);
grid-gap: 5px;
}
label {
grid-column: 1;
text-align: right;
}
input {
grid-column: 2;
margin-left: 0;
}
<form>
<label>Name: </label>
<input type="text">
<label>Mileage: </label>
<input type="number">
<label>Track: </label>
<input type="checkbox">
</form>
It works, but I want to keep the same layout (and still use grid) when each <label> and <input> is contained inside a <div> like this:
<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>
I have tried dividing the <form> and/or each <div> in various combinations, but nothing gets me the exact same result.
How can I align the inputs and labels vertically when they are contained in a <div>, using grid?
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>

How can I make input fields line up next to the middle of the labels?

Here's an example of the problem I am facing:
https://jsfiddle.net/v10un11s/1/
This is my HTML:
<div>
<div class="component">
<div>
<label for="test1" id="short-label">Short label: </label>
</div>
<div>
<input type="text" id="test1" />
</div>
</div>
<div class="component">
<div>
<label for="test2" id="long-label">This is my very very very very very very very very very very very very very very very very very very long label: </label>
</div>
<div>
<input type="text" id="test2" />
</div>
</div>
</div>
My css:
.
component > div:first-child {
width: 150px;
text-align: right;
margin-right: 5px;
margin-bottom: 10px;
}
.component > div {
display: inline-block;
}
This results in the input field lining up to the right of the labels. This is what I want, however, it lines at the end of the line of a very long label.
What I really want is that the input field line to the right AND to the relative middle of the label.
So in the JS Fiddle example above, I would want the input field to line up to the right of the third line of the long label.
I've been playing around with margins, paddings, line-height, etc etc, and I've not been able to figure out the correct solution.
Just one line of CSS should do the trick!
.component > div {
display: inline-block;
vertical-align: middle;
}
Just remember, this works both ways - so if your input is taller than your label, the label will center to the input.
You can use Flexbox and set align-items: center on .component
.component {
display: flex;
align-items: center;
}
.component > div:first-child {
width: 150px;
text-align: right;
}
<div>
<div class="component">
<div>
<label for="test1" id="short-label">Short label:</label>
</div>
<div>
<input type="text" id="test1" />
</div>
</div>
<div class="component">
<div>
<label for="test2" id="long-label">This is my very very very very very very very very very very very very very very very very very very long label:</label>
</div>
<div>
<input type="text" id="test2" />
</div>
</div>
</div>

Why does using an input group break the baseline alignment in bootstrap?

If I have a form with a label next to an input, in plain HTML, and both are inline (or inline block), then they are aligned by their baseline. But when using bootstrap and putting the input in an input group, it seems they get aligned by their bottom.
I tried to replicate this without bootstrap, but I couldn't, it just works. I created fiddle to show the problem:
http://jsfiddle.net/pupeno/9aJCF/3/
The HTML is:
<p>A case working, with just an input:</p>
<div class="form-group without-input-group">
<label>label</label>
<input type="text" class="form-control" value="value" />
</div>
<hr/>
<p>A case broken with the same HTML structure, but not using bootstrap:</p>
<div class="without-bootstrap">
<label>label</label>
<div class="group">
<input type="text" class="form-control" value="value" />
<span>addon</span>
</div>
</div>
<hr/>
<p>The broken situation, with the input group:</p>
<div class="form-group with-input-group">
<label>label</label>
<div class="input-group">
<input type="text" class="form-control" value="value" />
<span class="input-group-addon">addon</span>
</div>
</div>
and the CSS:
.without-input-group input {
max-width: 250px;
display: inline-block;
}
.without-bootstrap .group {
max-width: 250px;
display: inline-table;
}
.without-bootstrap .group input {
display: table-cell;
}
.without-bootstrap .group span {
display: table-cell;
}
.with-input-group .input-group {
max-width: 250px;
display: inline-table;
}
Because the input group is display: inline-table; and the label is outside the input-group.
If you inspect the input-group-addon element, you see that it is set to display: table-cell; and vertical-align: middle;.
If you move the label inside the input-group and style it same as the input-group-addon it lines up correctly.
<div class="form-group with-input-group">
<div class="input-group">
<label>label</label>
<input type="text" class="form-control" value="value" />
<span class="input-group-addon">addon</span>
</div>
</div>
.
.input-group label {
padding: 4px;
display: table-cell;
vertical-align: middle;
}
http://jsfiddle.net/N62he/

"Fluid" hanging indent in CSS

On a website, I would like this layout:
Some text [input 1]
[input 2]
I want:
the first input to be placed where the next word would appear and the distance between "text" and "[input 1]" to be one space
the second input to be placed below the first and aligning with it
both inputs moving to the left or right if the text width changes
Here is what I tried, but did not succeed:
When I surround the two inputs in a DIV, without any styling, it looks like this:
Some text
[input 1]
[input 2]
When I style the DIV as display: inline-block, it looks like this, i.e. the text drops to the bottom:
[input 1]
Some text [input 2]
When I style the DIV as display: inline or float the text to the left, it looks like this:
Some text [input 1]
[input 2]
When I style the div with margin left, I get:
Text [input 1]
[input 2]
i.e. the position does not change when I change the text width.
I can easily do this with tables. Please show me how to do it in CSS, without JavaScript. Thank you.
DEMO
HTML
<div>
<div id="text-container">
Some text
</div>
<div id="input-container">
<input />
<input />
</div>
</div>
CSS
#text-container:after {
content:"\00a0"; /*spacing*/
}
#text-container,
#input-container {
display:inline-block;
vertical-align:top;
}
#input-container input {
display:block;
}
This is repeatable and responsive!
Live demo (click).
<form>
<div>
<label>Set One</label>
<label>Set Two</label>
<label>Set Three</label>
</div>
<div class="inputs">
<input type="text" placeholder="set 1">
<input type="text" placeholder="set 1">
<input type="text" placeholder="set 2">
<input type="text" placeholder="set 2">
<input type="text" placeholder="set 3">
<input type="text" placeholder="set 3">
</div>
</form>
CSS:
form {
position: relative;
}
form div {
display: inline-block;
vertical-align: top;
}
label, input {
display: block;
}
label {
margin-top: 26px;
}
label:first-child {
margin-top: 0;
}
#media (max-width: 300px) {
label {
margin-bottom: 62px;
}
form .inputs {
display: block;
position: absolute;
top: 0;
}
input {
margin-top: 20px;
}
}
This is probably really the easiest way, which is to emulate a table using CSS and a few more non-semantic elements. Live demo (click).
<form class="table">
<div class="row">
<label class="cell">Set One</label>
<div class="cell">
<input type="text" placeholder="set 1">
<input type="text" placeholder="set 1">
</div>
</div>
<div class="row">
<label class="cell">Set Two</label>
<div class="cell">
<input type="text" placeholder="set 2">
<input type="text" placeholder="set 2">
</div>
</div>
</form>
CSS:
.table {
display: table;
}
.row {
display: table-row;
}
.cell {
display: table-cell;
}
input {
display: block;
}
#media (max-width: 300px) {
.cell {
display: block;
}
}
A version using CSS3 flexbox:
DEMO
Works even when inputs are inline elements and they wrap.
HTML
<div class="flexbox">
<div>
Some text
</div>
<div class="inputs">
<input />
<input />
</div>
</div>
CSS
.flexbox { display: flex }
.inputs input { display: block }