Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make container shrink-to-fit child elements as they wrap

Tags:

html

css

flexbox

I'm trying to figure out how flexbox works (supposed to work?…) for cases like below:

.holder {   width: 500px;   background: lightgray;   display: flex;   flex-direction: row;   justify-content: space-between;   flex-wrap: nowrap; } .v2 {   width: 320px; } .child {   display: inline-block;   border: 1px solid black;   padding: 30px 0px;   text-align: center; }
<div class="holder">   <div class="child">At a glance</div>   <div class="child">After coverage ends</div>   <div class="child">Forms &amp; documents</div> </div> <br> <br> <div class="holder v2">   <div class="child">At a glance</div>   <div class="child">After coverage ends</div>   <div class="child">Forms &amp; documents</div> </div> <br> <br> <div class="holder v2">   <div class="child">At a     <br>glance</div>   <div class="child">After coverage     <br>ends</div>   <div class="child">Forms &amp;     <br>documents</div> </div>

JSFiddle here

The problem is that when there's enough space to fit elements, I'm getting a nice tight-fitted children, with even spacing between. (first, top div block)

However, when there's no enough space and text inside children starts wrapping, it all kinda goes in a weird direction - children are not tightly fit anymore, and even though after wrapping, there's enough space around flex children, because there are not properly fit anymore, space-around doesn't really have a chance to work as well (second div block)

However still, IF I add manual line breaks at places where the automatic line breaks occur, everything gets laid out as it "should"… (bottom, third block)

What I'd like is to always have children tightly fitted within their boxes (black borders), and whatever space is left, would be distributed evenly between them, without me having to add manual line breaks (which is not an option in my case)

Is it possible at all?…

like image 352
Mikhail Kornienko Avatar asked May 24 '16 06:05

Mikhail Kornienko


2 Answers

In CSS, the parent container doesn't know when its children wrap. Hence, it continues scaling its size oblivious to what's going on inside.

Put another way, the browser renders the container on the initial cascade. It doesn't reflow the document when a child wraps.

That's why the container doesn't shrink-wrap the narrower layout. It just continues on as if nothing wrapped, as evidenced by the reserved space on the right.

The maximum length of the horizontal white space is the length of the element(s) that the container was expecting to be there.

In the following demo, whitespace can be seen coming and going as the window is re-sized horizontally: DEMO

You'll need a JavaScript solution (see here and here)... or CSS media queries (see here).

When dealing with wrapping text, text-align: right on the container may be helpful in some cases.

like image 134
Michael Benjamin Avatar answered Sep 29 '22 12:09

Michael Benjamin


Have a good look at my Fiddle in which I changed:

  • .holder width to max-width (in .v classes)
  • modified .holder to wrap and space-around its children
  • added 2 more .v classes for clarity
  • removed the <br>'s
  • and, most importantly, added flex: 0 0 to .child

Flexbox almost always needs max-width to be set, which is more flexible than width. Depending on how you need the .children to behave, modify the flex-grow and flex-shrink in flex: 0 0 to meet your needs. (the result of flex: 1 0 looks nice too)

...no Javascript needed...

UPDATE The Codrops Flexbox Reference really helped me a lot understanding FBL...

like image 25
Rene van der Lende Avatar answered Sep 29 '22 10:09

Rene van der Lende