CSS flexbox (flex-grow / flex-basis) - Same width but no longer complete

I use flexboxes to arrange the elements on my page.

I want flexboxes to use all available horizontal spaces, so I am adding flex-grow:1 .

Then I want each element on the same line to be the same size (e.g. 50% each if there are two elements, 33% if there are three, etc.), so I add flex-basis:0 .

But in the third stage, the elements are no longer transferred. If I change the width of the window, the number of elements in the line remains unchanged, and their contents are compressed. I do not want it. I want the element to be placed on the next line when their width becomes smaller than the content, since it works in the first two steps. I tried playing with flex-shrink and other things without success.

What can I do? Thanks!

Answer TL; DR: Adding min-width: fit-content works!

Jsfiddle

+5
source share
4 answers

Although your flex-wrap set to wrap , the flex ( li ) elements are not set to width , and your flex-basis set to 0. This means that the initial main size of the flex elements is 0. It will not wrap because it can be compressed to zero (even if the flex-shrink property is 0).

Solution No. 1

One thing you can do is set the flex-basis property to content or auto .

 li { flex-basis: auto; } 

This tells the flex element to affect the width of its contents.

jsfiddle demo

flex-basis

The initial base size of the flex element.

auto

When specified in a flex element, the auto keyword gets the value of the main size property as the flex-basis . If this value is also auto , then the content value used.

content

Indicates automatic calibration based on the contents of flexible elements.

Note. Note that content not present in the initial release of Flexible Box Layout, and therefore some older versions will not support it. An equivalent effect can be obtained by using auto together with the basic size (width or height) of auto .

This diagram from flexbox spec is trying to explain the difference between flex-basis: 0 and flex-basis: auto . Here is a more complete explanation.

enter image description here


Decision No. 2

Another way to vertically place flex-direction items on smaller screens is to change the flex-direction in the media request:

 @media screen and ( max-width: 500px ) { ul { flex-direction: column; } li { flex-basis: auto; } } 

jsfiddle demo

+3
source

I would use media queries to change the flex-direction element to column if the elements are too large for the width of the window. This will put the list items below each other.

HTML

 <ul class="grid__row grid__row--sm"> <li>1 small</li> <li>1 wide wide wide wide wide wide</li> </ul> <ul class="grid__row grid__row--sm"> <li>2 medium medium</li> <li>2 small</li> </ul> <ul class="grid__row grid__row--md"> <li>3 small</li> <li>3 wide wide wide wide wide wide</li> <li>3 medium medium</li> </ul> 

CSS

 .grid__row { margin: auto; padding: 0; list-style-type: none; display: flex; flex-direction: column; } .grid__row li { background: green; color: white; margin: 1px; padding: 15px; display:flex; flex: 1; } @media (min-width: 480px) { .grid__row--sm { flex-direction: row; } } @media (min-width: 768px) { .grid__row--md { flex-direction: row; } } 

Jsfiddle

+1
source

You cannot set flex-base to auto or content because you want all the boxes to be the same size, so flex-basis should be 0 and flex-grow set to 1 , as you did right. Now you need to set min-width (e.g. 200px ) on flex items. Your mileage may vary, I believe that safari (webkit does a terrible job of maintaining since google went to blink) may be a mistake from min-width to flex-items .

Alternatively, you can simply set the flex base as the min-width property, which should work even in safari ( flex: 1 0 200px )

 ul { margin: auto; padding: 0; list-style-type: none; display: flex; flex-wrap: wrap; } li { background: green; margin: 1px; flex: 1 0 200px; } 
 <ul> <li>1 small</li> <li>1 wide wide wide wide wide wide</li> </ul> <ul> <li>2 medium medium</li> <li>2 small</li> </ul> <ul> <li>3 small</li> <li>3 wide wide wide wide wide wide</li> <li>3 medium medium</li> </ul> 
+1
source

Thanks to Michael_B and Adam, I found a solution to my problem.

 flex-grow: 1; flex-basis: 0; min-width: fit-content; 

The value of fit-content min-width is the key. This is experimental (you may have to add a browser prefix), but it does exactly what I wanted: the same width, with a wrapper!

+1
source

Source: https://habr.com/ru/post/1234012/


All Articles