column-count:2 doesn't work when there are 2 divs - html

I have the below example that work fine for all cases except when the number of divs is 2!
The wanted behavior is to always display divs in 2 columns.
.container {
column-count: 2;
}
.square {
border: 1px solid black;
box-sizing: border-box;
height: 200px;
display:inline-block;
width:100%;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
</div>
This is the behavior I have for more than 2 divs (That I want to preserve):
.container {
column-count: 2;
}
.square {
border: 1px solid black;
box-sizing: border-box;
height: 200px;
display:inline-block;
width:100%;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
<div class="square">4</div>
<div class="square">5</div>
</div>

You can write a specific rule for the case of 2 divs using float:
.container {
column-count: 2;
margin:5px;
}
.square {
border: 1px solid black;
box-sizing: border-box;
height: 200px;
display:inline-block;
width:100%;
}
.square:first-child:nth-last-child(2) {
float:left;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
</div>
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
Even with display:block
.container {
column-count: 2;
margin:5px;
}
.square {
border: 1px solid black;
box-sizing: border-box;
height: 200px;
display:inline-block;
width:100%;
}
.square:first-child:nth-last-child(2) {
display:block;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
</div>
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>

You put width: 100% on each of the elements, which, remember is relative to the container. Therefore it can't fit two full width elements and expands them into two rows. Removing that line puts them into two columns. 50% is the upper limit for the width otherwise it can't fit two elements in a row.

If you are trying to use css grid you have to adjust your container to allow for two columns. If you have unlimited squares but always want them to break into two columns use flexbox instead
Flexbox
.container {
display: flex;
flex-wrap: wrap;
}
.square {
width: 50%;
}
Grid
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
.square {
border: 1px solid black;
box-sizing: border-box;
height: 200px;
width:100%;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
</div>

Related

Display divs in 2 columns ordered from above to below

I want to display divs in 2 columns ordered from above to below:
I tried the following solution based on column-count which works nice if the number of divs is even but breaks if it's odd.
.container {
column-count:2;
}
.square {
box-sizing: border-box;
border: 1px solid black;
height: 200px;
padding: 5px;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
Then I tried a solution based on flex, but I can't seem to find a solution for the order:
.container {
display:flex;
flex-wrap: wrap;
}
.square {
box-sizing: border-box;
border: 1px solid black;
flex: 0 0 50%;
height: 200px;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>
What I want to achieve is smoothing like this:
add display:inline-block;width:100%; to the square element:
.container {
column-count: 2;
}
.square {
border: 1px solid black;
height: 200px;
display:inline-block;
width:100%;
}
<div class="container">
<div class="square">1</div>
<div class="square">2</div>
<div class="square">3</div>
</div>

How to make Flex Grid width relative to the biggest child's width?

I have something like this :
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
width: 25%;
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
I can't understand how :
The width of the .row element is calculated
The width of the .col elements are calculated
Why some content overflows the box and some don't
What I want is a grid system that gets its size relative to the largest child, so that each content fits in its .col cell.
I saw that I could do that with display: grid and grid-template-columns: 1fr 1fr 1fr 1fr, but then how do you make it responsive and how well is it supported ?
To answer your 3 first questions, you simly need to remove the width:25% to have the following:
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
We didn't define any width, so each col will fit its content and the row will have the width equal to the sum of all the col.
Now since we have the width of the row defined based on the content, it won't change and it will get used as a reference for the percentage. Using 25% for the col means that each one will get 25% of the previously defined width and we will logically have some overflow since the content inside each col isn't the same.
.wrapper {
display: flex;
width: 300px;
}
.content {
flex: auto;
}
.row {
display: flex;
flex-flow: row wrap;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
.width .col {
width:25%;
}
<div class='wrapper'>
<div class='content'>before width</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
<div class='wrapper'>
<div class='content'>after width</div>
<div class='row width'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>
To obtain what you want, I think the 1fr of CSS grid is the way to go (like you already noticed). Actually CSS grid is well supported. You will simply have issues with IE and you can follow this link to see the known bugs: https://caniuse.com/#feat=css-grid
In order to make it responsive you may consider media query to switch to a column layout on small screens:
.wrapper {
display: flex;
width: 300px;
}
.row {
display: grid;
grid-auto-columns:1fr;
grid-auto-flow:column;
}
.col {
padding: 5px;
border: 1px solid black;
box-sizing: border-box;
}
#media all and (max-width:500px) {
.row {
grid-auto-flow:row;
}
}
<div class='wrapper'>
<div class='content'>Content</div>
<div class='row'>
<div class='col'>aa</div>
<div class='col'>aaaa</div>
<div class='col'>aaaaaa</div>
<div class='col'>aaaaaaaa</div>
</div>
</div>

CSS 2 fluid 1 fixed column

I am trying to achieve this layout.
left column fixed size
right column fluid, it may have x number of elements inside, for example up to 4 divs 50px wide (this is done dynamically) so it must be max 200px wide, or if it has 3 such elements, then it must be 150px wide...
center column fluid, takes all the rest space
The closest I have comes is this:
#container {
overflow:hidden;
width: 100%;
}
#leftcol {
border: 1px solid #0f0;
float: left;
width: 80px;
}
#rightcol {
border: 1px solid #0f0;
float: right;
}
#centercol {
border: 1px solid #000;
margin-left: 80px;
}
.box{
width:50px;
height:20px;
background:red;
float:left;
}
<div id="container">
<div id="leftcol">
fixed 80px
</div>
<div id="rightcol">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
<div id="centercol">
fluid center
</div>
</div>
but center fluid is not correct width.
I can change some html if it will be easier to achieve desired effect.
You can do it with the Flexbox:
body {margin: 0}
#container {
display: flex; /* displays flex-items (children) inline */
overflow: hidden;
}
#leftcol {
border: 1px solid #0f0;
width: 80px;
}
#centercol {
flex: 1; /* takes the remaining horizontal space */
border: 1px solid #000;
}
#rightcol {
display: flex;
border: 1px solid #0f0;
max-width: 200px; /* adjust to your needs */
}
.box {
width: 50px;
height: 20px;
background: red;
}
<div id="container">
<div id="leftcol">
fixed 80px
</div>
<div id="centercol">
fluid center
</div>
<div id="rightcol">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
</div>

Make child divs inside a parent div equal width and fluid

How can I make the 3 child divwith class .box have the same width while fluidly occupying the entire parent container div while staying inline.
Here is a fiddle
#container {
width: 20em;
background: red;
text-align: center;
}
.box {
display: inline-block;
margin: 1em;
border: 1px solid #000;
}
<div id="container">
<div class="box">test</div>
<div class="box">test</div>
<div class="box">test</div>
</div>
use CSS flexbox for that
#container {
width: 20em;
display: flex;
background: red;
text-align: center;
}
.box {
flex: 1;
border: 1px solid #000;
}
<div id="container">
<div class="box">test</div>
<div class="box">test</div>
<div class="box">test</div>
</div>
OR
use inline-block as you already are using, with a few tweaks.
* {
box-sizing: border-box
}
#container {
width: 20em;
background: red;
text-align:center
}
.box {
font-size: 16px;
display: inline-block;
width: calc(100% / 3);
border: 1px solid #000;
}
<div id="container">
<div class="box">test</div><div class="box">test</div><div class="box">test</div>
</div>
OR
use CSS tables for old browsers support
#container {
width: 20em;
display: table;
background: red;
text-align: center;
}
.box {
display:table-cell;
border: 1px solid #000;
}
<div id="container">
<div class="box">test</div>
<div class="box">test</div>
<div class="box">test</div>
</div>
display:table version:
#container {
width: 20em;
background: red;
text-align: center;
display: table;
table-layout: fixed;
border-spacing: 1em;
/* instead the margin:1em; you applied to children */
}
.box {
display: table-cell;
;
border: 1px solid #000;
}
.middle{vertical-align:middle;}
<div id="container">
<div class="box">test</div>
<div class="box">test</div>
<div class="box">test</div>
</div>
<hr/>
<div id="container">
<div class="box">test
<br/>+ 1line ?</div>
<div class="box">test</div>
<div class="box middle">test</div>
</div>
table-layout:fixed will fix width value you set, for main container and children.
if children(table-cell) have no width set, they will spray evenly
#container {
width: 20em;
background: red;
text-align: center;
display: table;
table-layout: fixed;
border-spacing: 1em;
/* instead the margin:1em; you applied to children */
}
.box {
display: table-cell;
;
border: 1px solid #000;
}
.middle{vertical-align:middle;}
<div id="container">
<div class="box">test test test test </div>
<div class="box">test</div>
<div class="box">test</div>
</div>
<hr/>
<div id="container"class=" bis ">
<div class="box">testtesttesttest testtesttest</div>
<div class="box">test</div>
<div class="box">test</div>
</div>
If you want to do this with display: inline-block you can set equal width of 33.33% on each .box, remove white space from HTML and also add box-sizing: border-box.
* {
box-sizing: border-box;
}
#container {
width: 20em;
background: red;
text-align: center;
}
.box {
display: inline-block;
width: 33.33%;
border: 1px solid #000;
}
<div id="container">
<div class="box">test</div><div class="box">test</div><div class="box">test</div>
</div>

Stretch an element of unknown width alongside elements of fixed width inside parent of unknown width

I have a parent div of unknown width (the width depend on some screen width calculations). The number of the child divs is 4 and are floated so that they are horizontally aligned. The 1st, 2nd and 4th are good candidates for fixed width value. However, the 3rd element can stretch to fit the remaining space in the parent div.
I don't know why the approach of display:table; for parent and display:table-cell for children didn't work for me. The three element's width is fixed except for the concerned div where I also tried width:auto to no avail.
<div class="parent">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
<div class="fourth"></div>
</div>
A minimal CSS:
.parent
{
width: 100%;
display:table;
}
.first
{
width: 80px;
height: 80px;
float: left;
display: table-cell;
}
.second
{
width: 80px;
height: 80px;
float: left;
display: table-cell;
}
.third
{
height: 80px;
float: left;
display: table-cell;
}
.fourth
{
width: 80px;
height: 80px;
float: left;
display: table-cell;
}
Your usual help is much appreciated.
You can do this with Flexbox, so if you add flex: 1 to one child div it will take rest of free width
.parent {
display: flex;
border: 1px solid black;
}
.child {
border: 1px solid black;
margin: 5px;
padding: 5px;
width: 50px;
}
.long {
flex: 1;
}
<div class="parent">
<div class="child">Div 1</div>
<div class="child">Div 2</div>
<div class="child long">Div 3</div>
<div class="child">Div 4</div>
</div>
Or you can use CSS Table with table-layout: fixed here is Browser support
.parent {
display: table;
width: 100%;
border: 1px solid black;
table-layout: fixed;
}
.child {
border: 1px solid black;
display: table-cell;
margin: 5px;
padding: 5px;
width: 50px;
}
.long {
width: 100%;
}
<div class="parent">
<div class="child">Div 1</div>
<div class="child">Div 2</div>
<div class="child long">Div 3</div>
<div class="child">Div 4</div>
</div>
For IE9+
You can use inline-block and calc() for this.
Snippet
body {
margin:0
}
.parent {
border:solid black;
font-size:0; /*fix inline-block gap*/
}
.child {
border: 1px solid red;
margin: 5px;
width:100px;
display:inline-block;
font-size:16px /*restore font -size*/
}
.calc{
width: calc(100% - 348px)
}
<div class="parent">
<div class="child">one</div>
<div class="child">two</div>
<div class="child calc">three</div>
<div class="child">four</div>
</div>
For IE8+
you can use display:table/table-cell
Snippet
body {
margin: 0
}
.parent {
border: solid black;
display: table;
table-layout: fixed;
width: 100%;
/*optional*/
border-collapse:separate;
border-spacing:5px;
box-sizing:border-box;
}
.child {
border: 1px solid red;
width: 100px;
display:table-cell;
}
.big {
width:100%
}
<div class="parent">
<div class="child">one</div>
<div class="child">two</div>
<div class="child big">three</div>
<div class="child">four</div>
</div>