Using either Flexbox or CSS Grid, is it possible to size my columns based on the contents of one of the columns?
I have 2 columns, a main and a side.
|------------------------container--------------------------|
| |
||----------------------------------------|----------------||
|| main | side ||
||----------------------------------------|----------------||
| |
|-----------------------------------------------------------|
I want the side to be automatically sized based on its content, and I want the main to be twice as wide as the side, at a minimum. It can grow bigger, but no smaller.
As the container increases, the main will grow at the same rate, while the side remains its auto width.
|--------------------------container increases----------------------|
| |
||------------------------------------------------|----------------||
|| main increases | side ||
||------------------------------------------------|----------------||
| |
|-------------------------------------------------------------------|
The container can shrink down to 3 times as big as the side, at which point the main will be twice as wide as the side. I want this to be the breakpoint.
|--------------------container----------------------|
| |
||--------------------------------|----------------||
|| main | side ||
||--------------------------------|----------------||
| |
|---------------------------------------------------|
If the container shrinks any more, I want the columns to stack, where both columns are now 100% width:
|--------------------container--------------------|
| |
||-----------------------------------------------||
|| main ||
||-----------------------------------------------||
||-----------------------------------------------||
|| side ||
||-----------------------------------------------||
| |
|-------------------------------------------------|
I tried doing this with Flexbox and with Grid, but I couldn’t get the main column to determine its size based on the side column.
.container-grid {
display: grid;
grid-template-columns: 1fr auto; /* works, but doesn’t wrap when left column gets too small */
/* I also tried the repeat() syntax, but that only worked for similarly-sized columns */
}
.container-flex {
display: flex;
flex-wrap: wrap;
}
.main { flex: 2; } .side { flex: 1; } /* same problem, doesn’t wrap */
.main ( flex: 0 1 auto; } .side { flex: 0 0 auto; } /* wraps columns too early, any time main is smaller than intrinsic width */
The only solution I’ve tried that works is knowing the fixed width of the side column (which I would have to predict without knowing its content), and then using a media query at 3 times its width. And of course, the media query only works on window width, not container width, so I would have to calculate the media query using any parent elements of the container.
.container-grid {
display: grid;
grid-template-columns: 1fr 15em;
}
@media screen and (max-width: 45em) {
.container-grid {
grid-template-columns: 1fr;
}
}
Here is one solution, using Flexbox, where you use a flex-grow value being very much bigger on main
than on side
.
With this, the side
will fill parent when wrapped, and when on wide screen, with the so much higher value on the main
, the flex-growth on side
will practically be none.
Combined with a min-width
on the main
being twice the size of the side
, it will wrap before it gets smaller, and for that we can use percent as that is based on parent's width.
So in this case twice the size on main
will be 2/3 of parent, 66.666%.
Fiddle demo
Stack snippet
.container-flex {
display: flex;
flex-wrap: wrap;
}
.main {
flex: 10000;
min-width: 66.666%;
background: lightblue;
}
.side {
flex: 1 0 auto;
background: lightgreen;
}
span {
display: inline-block;
padding: 20px;
}
<div class="container-flex">
<div class="main">
<span>Fill remain, min. twice the "side"</span>
</div>
<div class="side">
<span>Take content size</span>
</div>
</div>
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