Reputation: 6329
Is there a way to specify column width ratios and minimum widths to allow wrapping for narrow screens (responsive design)?
+-----+-----+-----+
| 1/3 | 2/3 |
| |(1/3 | 1/3)|
+-----+-----+-----+
+-----+-----+
| 1/3 | 1/3 | (actual ratio now 1/2)
| | 1/3 |
+-----+-----+
+-----+
| 1/3 | (actual ratio now 1 - full width)
+-----+
| 1/3 |
| 1/3 |
+-----+
Each 1/3
is a div, so is 2/3
.
It should fill 100% of its parent's width (centered "main" container column).
I've tried the following:
div {
box-sizing: border-box;
border: 1px solid red;
margin: 1px;
padding: 0;
}
#container>div {
float: left;
}
#container::after {
content: "";
display: block;
clear: both;
}
.flex {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1rem;
}
.flex>div {
flex-basis: 200px;
flex-shrink: 0;
}
.fone {
flex-grow: 1;
}
.ftwo {
flex-grow: 2;
}
.gthree {
display: grid;
grid-template-columns: 1fr 2fr;
grid-gap: 1rem;
}
.gtwo {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 1rem;
}
float: not quite right
<div id="container">
<div style="width:33%;">A</div>
<div style="width:66%;">
<div style="width:50%;">B</div>
<div style="width:50%;">C</div>
</div>
</div>
flex: wraps, uneven sizing, children overflow
<div class="flex">
<div class="fone">A</div>
<div class="ftwo flex">
<div>B</div>
<div>C</div>
</div>
</div>
grid: nice sizing, but does not wrap
<div class="gthree">
<div>A</div>
<div class="gtwo">
<div>B</div>
<div>C</div>
</div>
</div>
Intended result:
<div class="one">
<div>A</div>
<div>
<div>B</div>
<div>C</div>
</div>
</div>
Upvotes: 1
Views: 674
Reputation: 6329
Flex proportions work well in my application. The actual contents have (different) widths, so they may shrink and overflow at different screen widths. I have added minimum size values for flex in an attempt to simulate that. It does not work well here in the Snippet.
<div style="display:flex; flex-wrap: wrap; gap:1rem;">
<div style="flex:1 250px;">AAA unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,</div>
<div style="flex:2; display:flex; flex-wrap: wrap; gap:1rem;">
<div style="flex:1 250px;">BBB unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,</div>
<div style="flex:1 250px;">CCC unde omnis iste natus error sit voluptatem accusantium doloremque laudantium,</div>
</div>
</div>
Upvotes: 0
Reputation: 136
Try this:
div {
box-sizing: border-box;
border: 1px solid red;
margin: 1px;
padding: 0;
}
.container {
display: flex;
flex-wrap:wrap;
justify-content:space-evenly;
/* Or you can use any of the
following as per needs:
justify-content:space-between;
justify-content:space-around;
justify-content:space-evenly;
justify-content:center; */
}
.inner {
display: flex;
flex-wrap:wrap;
flex:1;
}
.middle {
display: flex;
flex-wrap:wrap;
flex:1;
}
.single{
/* For occupying equal space: */
flex:1;
}
/* `Note: The flex-wrap works when you use a specific width, else the width will adjust automatically depends on screen size` */
<div class="container">
<div class='single'>A</div>
<div class='middle'>
<div class='inner'>B</div>
<div class='inner'>C</div>
</div>
</div>
Upvotes: 0
Reputation: 3178
Not perfect, but you can get really close with grids and auto-fit
(1)
and minmax
.
We set the min value in our min max to the width it'll wrap after, and the max to 1fr
for the cells to flex with the grid.
The issue is repeat()
with auto-fit
sets an equal ratio between all columns, so A will be as big as B & C until everything wraps together. Which is fine for scenarios 2 and 3 but not 1.
This could be fixed by using flex and and setting the flex-grow's accordingly so that when everything's in one line, the ratios are correct, but then in the other scenarios the ratios would have to go change again, which is an issue.
div {
box-sizing: border-box;
border: 1px solid red;
margin: 1px;
padding: 0;
}
#container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.inner {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
<div id="container">
<div class='single'>A</div>
<div class='inner'>
<div>B</div>
<div>C</div>
</div>
</div>
Upvotes: 2