Prefer Shrinking Over Growing in a Flex Container with Flex-Flow: Row Wrap

Prefer shrinking over growing in a flex container with flex-flow: row wrap

I modify your starting attempt.

Main idea is to change img width: 100%; to width: auto; and specify links' height. This will give us images with gaps.

To remove the gaps we could add to links display: flex; and flex-direction: column;. Almost done.

Last step is to add to links max-width: 100%;, it will protect from ovelflow if image width will be wider than column in small screen. Such problem we could see in Temani Afif's first solution with 4th image, if we put higher height of links. Edited

Look into snippet.

section {  display: flex;  flex-flow: row wrap;  justify-content: center;}
section a { flex: auto; display: flex; flex-direction: column; height: 166px; max-width: 100%;}
section img { height: 100%; width: auto; object-fit: cover;}
<!DOCTYPE html><html lang="en">
<head> <title>Controlling flex growability</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <style>
</style></head>
<body> <section> <a href="#"><img src="https://placekitten.com/400/195" width="400" height="195" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/256/400" width="256" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/237" width="400" height="237" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/111" width="400" height="111" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/245" width="400" height="245" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/227" width="400" height="227" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/250/400" width="250" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/269" width="400" height="269" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/255" width="400" height="255" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/288/400" width="288" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/234/400" width="234" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/194/400" width="194" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/222/400" width="222" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/227" width="400" height="227" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/192/400" width="192" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/141" width="400" height="141" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/289" width="400" height="289" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/255" width="400" height="255" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/210/400" width="210" height="400" alt="Kitty"></a> <a href="#"><img src="https://placekitten.com/400/187" width="400" height="187" alt="Kitty"></a> </section></body>
</html>

flex-box: shrink before wrap

Set flex-basis equal to min-width:

.column.stretch {
flex: 1 1 100px; /* or 1 0 100px, and no more need in min-width at all */
max-width: 300px;
min-width: 100px;
background: red;
}

edited JSfiddle example

Prevent flex items from overflowing a container

Your flex items have

flex: 0 0 200px; /* <aside> */
flex: 1 0 auto; /* <article> */

That means:

  • The <aside> will start at 200px wide.

    Then it won't grow nor shrink.

  • The <article> will start at the width given by the content.

    Then, if there is available space, it will grow to cover it.

    Otherwise it won't shrink.

To prevent horizontal overflow, you can:

  • Use flex-basis: 0 and then let them grow with a positive flex-grow.
  • Use a positive flex-shrink to let them shrink if there isn't enough space.

To prevent vertical overflow, you can

  • Use min-height instead of height to allow the flex items grow more if necessary
  • Use overflow different than visible on the flex items
  • Use overflow different than visible on the flex container

For example,

main, aside, article {
margin: 10px;
border: solid 1px #000;
border-bottom: 0;
min-height: 50px; /* min-height instead of height */
}
main {
display: flex;
}
aside {
flex: 0 1 200px; /* Positive flex-shrink */
}
article {
flex: 1 1 auto; /* Positive flex-shrink */
}
<main>
<aside>x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x </aside>
<article>don't let flex item overflow container.... y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y </article>
</main>

When flexbox items wrap in column mode, container does not grow its width

The Problem

This looks like a fundamental deficiency in flex layout.

A flex container in column-direction will not expand to accommodate additional columns. (This is not a problem in flex-direction: row.)

This question has been asked many times (see list below), with no clean answers in CSS.

It's hard to pin this as a bug because the problem occurs across all major browsers. But it does raise the question:

How is it possible that all major browsers got the flex container to
expand on wrap in row-direction but not in column-direction?

You would think at least one of them would get it right. I can only speculate on the reason. Maybe it was a technically difficult implementation and was shelved for this iteration.

UPDATE: The issue appears to be resolved in Edge v16.



Illustration of the Problem

The OP created a useful demo illustrating the problem. I'm copying it here: http://jsfiddle.net/nwccdwLw/1/



Workaround Options

Hacky solutions from the Stack Overflow community:

  • "It seems this issue cannot be solved only with CSS, so I propose you a JQuery solution."

  • "It's curious that most browsers haven't implemented column flex containers correctly, but the support for writing modes is reasonably good. Therefore, you can use a row flex container with a vertical writing mode."



More Analysis

  • Chromium Bug Report

  • Mark Amery's answer



Other Posts Describing the Same Problem

  • Flex box container width doesn't grow
  • How can I make a display:flex container expand horizontally with its wrapped contents?
  • Flex-flow: column wrap. How to set container's width equal to content?
  • Flexbox flex-flow column wrap bugs in chrome?
  • How do I use "flex-flow: column wrap"?
  • Flex container doesn't expand when contents wrap in a column
  • flex-flow: column wrap, in a flex box causing overflow of parent container
  • Html flexbox container does not expand over wrapped children
  • Flexbox container and overflowing flex children?
  • How can I make a flexbox container that stretches to fit wrapped items?
  • Flex container calculating one column, when there are multiple columns
  • Make container full width with flex
  • Flexbox container resize possible?
  • Flex-Wrap Inside Flex-Grow
  • Flexbox grow to contain
  • Expand flexbox element to its contents?
  • flexbox column stretch to fit content
  • https://stackoverflow.com/q/48406237/3597276
  • flex-flow: column wrap doesn't stretch the parent element's width
  • Why doesn't my <ul> expand width to cover all the <li>?
  • https://stackoverflow.com/q/55709208/3597276
  • Flexbox wrap not increasing the width of parent?
  • Absolute Flex container not changing to the correct width with defined max-height

Flex-wrap is not wrapping when I reduce the window size

You need to use max-width instead of width on the container, you have to allow the container to shrink for the items to wrap.

body {  font-family: arial;}
p { color: white;}
.container { background-color: #666; max-width: 800px; height: 200px; margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: center;}
.item { padding: 10px; box-sizing: border-box;}
.item1 { flex: 1; background-color: red;}
.item2 { flex: 1; background-color: blue;}
.item3 { flex: 1; background-color: green;}
<div class="container">
<div class="item item1"> <h1>ITEM1</h1> <p>flex: 1</p> </div>
<div class="item item2"> <h1>ITEM2</h1> <p>flex: 1</p> </div>
<div class="item item3"> <h1>ITEM3</h1> <p>flex: 1</p> </div>
</div>

How to prevent flex-items from overflowing flex parent with no wrap?

Set display: inline-flex on the .parent class to change it to an inline element. This will also force the .parent to expand to contain its children. Then by setting min-width: 100% on the .parent class, it will force it to expand to 100% of the containing element.

.parent {
display: inline-flex;
flex-direction: row;
background-color: red;
min-width: 100%;
}
.child {
min-width: 100px;
flex-basis: 0px;
flex-grow: 1;

margin: 5px;
height: 100px;
background-color: blue;
}

Flex item shrinking even with flex-shrink: 0

You haven't specified enough width for the flex items to overflow the container (nowrap) or the line (wrap). Therefore, flex-shrink isn't being called into action. If the flex items are wide enough, they will overflow the container or wrap, and not shrink, as you expect.

#content {  display: flex;  flex-flow: row wrap;}.box {  flex: 1 0 150px;  border: 3px solid rgba(0, 0, 0, .2);}.box1 {  flex: 1 0 200px;  border: 3px solid rgba(0, 0, 0, .2);}
<h4>it shinks with a flex-shrink of 0</h4><div id="content">  <div class="box" style="background-color:red;">A</div>  <div class="box" style="background-color:lightblue;">B</div>  <div class="box" style="background-color:yellow;">C</div>  <div class="box1" style="background-color:brown;">D</div>  <div class="box1" style="background-color:lightgreen;">E</div>  <div class="box" style="background-color:brown;">F</div></div>

Flexbox: flex-flow column; flex-basis 100% not working without explicit height

grid and mediaquerie is , IMHO, a good way to manage the swhitching from a 1 column layout to a 2 columns layout.

Demo of the idea :

:root {/* possible use of var here */--col1 : 1fr;--col2 : 2fr;}main {  display: grid;  grid-template-columns: var(--col1) var(--col2);}main> * {  border:solid 1px;  margin:2px;}section {  grid-column:1;}article {  grid-column:2;  grid-row:1 / 10;}
/* breakpoint at 768px */@media screen and (max-width: 768px) { main { display: flex; flex-flow: column; } main section + section {/* best is to use an id */ order: 1; }}
<main>  <section>    <h1>About</h1>    <p>Blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah.</p>  </section>  <section><! -- that one might deserve an id to easy reorder its position -->    <h1>Disclaimer</h1>    <p>Here there be naughty things!!!</p>  </section>  <article class="blog">    <h1>Blog Entry</h1>    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum eleifend molestie orci. Donec pellentesque viverra magna, nec viverra velit laoreet non. Etiam blandit erat nulla, semper faucibus eros rhoncus vel.</p>  </article>
</main>


Related Topics



Leave a reply



Submit