Is there a way to get 2 column layout that is transformed to a 1 column layout with a media query?
Conditions for 2 column layout:
Conditions for 1 column layout:
I have been considering two separate containers for columns - but that construct blocks me for reordering (mix) elements between columns when layout becomes 1 column. I seems that all elements should be placed within one container - then for 1 column layout flex can be used for reordering, but how to achieve 2 column layout in that case?
To simulate media query behaviour remove class "one-column" from main container.
<div id="container" class="one-column"> -> <div id="container" class="">
In this concept the main problem is that items within columns (2 column layout) are not flowing directly one after another (there are gaps between items in the right column).
Here's what I achieved so far:
* {
box-sizing: border-box;
}
div {
width: 100%;
height: 100px;
float: left;
}
#container.one-column {
display: flex;
flex-direction: column;
height: auto;
}
#container {
display: block;
}
.col1 {
width: 60%;
background-color: red;
height:300px;
float: left;
}
.col2 {
width: 40%;
background-color: blue;
border: 1px solid white;
float: right;
}
.one-column > div {
width: 100%;
}
<div id="container" class="one-column">
<div class="col1" style="order:2;">
ONE
</div>
<div class="col2" style="order:1;">
TWO
</div>
<div class="col1" style="order:4;">
THREE
</div>
<div class="col2" style="order:3;">
FOUR
</div>
</div>
JSFiddle: https://jsfiddle.net/3b6htt1d/40/
Conditions for 2 column layout:
- items should flow one after another within columns
- items within columns will have different heights
- item position (order) can be imposed by html markup element position
That is exactly what CSS Columns does.
Conditions for 1 column layout:
- items should flow one after another
- items within columns will have different heights
- item position (!) cannot be imposed by html markup (should be controlled over css)
That is exactly what one can do with Flexbox and column
direction.
So if one combine the two, for 2 columns they will, as shown in the left image sample, flow from top to bottom, and for 1 columns, you can control their position with order
.
With this you avoid fixed heights and get dynamic/flexible sized items.
Updated fiddle
Stack snippet
* {
box-sizing: border-box;
}
div {
width: 100%;
height: 100px;
}
#container.one-column {
display: flex;
flex-direction: column;
height: auto;
}
.col1 {
width: 60%;
background-color: red;
height:300px;
}
.col2 {
width: 40%;
background-color: blue;
border: 1px solid white;
}
.one-column > div {
width: 100%;
}
@media (min-width: 500px) {
#container.one-column {
display: block;
columns: 2;
}
#container.one-column > div {
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
.zcol1 ~ .col1 {
background-color: yellow;
height:100px;
}
}
<div id="container" class="one-column">
<div class="col1" style="order:2;">
ONE
</div>
<div class="col2" style="order:1;">
TWO
</div>
<div class="col1" style="order:4;">
THREE
</div>
<div class="col2" style="order:3;">
FOUR
</div>
</div>
Here is another answer of mine, that might be another option, combining Flexbox with float
.
Updated based on a comment
Here is a version combining Flexbox and float
, which produce the layout your screen shot shows:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With