Whenever the items inside a flexbox wrap, they tend to stretch the flexbox, leaving extra space on a side. It only happens when items wrap. How do I get rid of that extra spacing?
Screenshot of the issue
What I want it to do
HTML
<div>
<div class="red">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="green">
<div></div>
</div>
</div>
CSS
body > div {
display: flex;
width: 34rem;
justify-content: space-between;
border: 1px solid black;
}
body > div > div {
display: flex;
flex-flow: row wrap;
}
body > div > div.red {
background: rgba(255, 0, 0, .1);
}
body > div > div.green {
background: rgba(0, 255, 0, .1);
flex-shrink: 0;
}
body > div > div > div {
margin: 1rem;
height: 5rem;
width: 5rem;
background: rgba(0, 0, 0, .1);
}
See an example on JSFiddle
So what you would do is use grid-gap for spacing between the items. Then use padding for the same spacing between the items and the container. The last row margin problem is eliminated. The number of items is no longer a concern.
You need to add align-content: flex-start on flex-container or in your case #wrapper element. Show activity on this post. In a multi-line flex row layout, the align-content controls how the flex items aligns vertical when they wrap, and since its default is stretch , this is expected behavior.
Examples. The gap property is designed for use in grid, flex and multi-column layouts.
All criteria have been met to the best of my knowledge.
justify-content: space-between
which reduces the padding on both left and right sides of the red box.flex: 0 0 auto
.flex: 2 0 auto
.PLUNKER
OP stated that a fixed width will not work due to the fact that if content (i.e. flex items) can change widths and break layout. What really constitutes a fixed layout is that the outer container is rigid having an absolute value measurement and/or max limit length. Being fixed, liquid, responsive, adaptable, sauteed in some white wine, etc. isn't the real problem. What the real problem is that flexbox in a row direction does not handle calculations well when dealing with uneven rows. So to insure a uniform formation of content I find that:
justify-content: space-around
will work perfectly if you do the next step.visibility: hidden
or opacity: 0
, but not display: none
Details are in the JS area (no JS added, just it's space being utilized for comments).
/* Changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CSS
line 1 to 8
|| Needed basic reset
=====================
line 12
|| To demonstrate behavior in liquid layout.
=====================
line 19 to 24
|| Needed some type of measurement, otherwise it
|| will expand to fill in that extra space on
|| the right.
|| flex was set to shrink when width has reached
|| it's basis of 62%.
======================
line 22 to 28
|| Width and flex growth/shrink/basis were added
|| for the same reasons as explained of the
|| prior ruleset.
|| max-width: 380px is the limit for the red
|| box before the content is askew.
|| justify-content: space-around was added in
|| order to stabilize it's width.
======================
line 11, 31 to 33
|| Changed rem units to em because it's ideal for
|| a responsive layout. Although rem is a
|| relative measurement like it's sister
|| property, em, it's based on the root's default
|| so directly changing that measurement will
|| yield a change, whilst with em, only the
|| container (or parent) needs to resize on the
|| fly.
======================
line 44 to 46
|| This ghost flex item is the key to the red
|| boxes' content being able to maintain a
|| uniformed layout.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
HTML
line 8
|| Added an extra div in div.red to be the ghost
|| flex item. Flex items will exhibit a uniform
|| behavior when there are an equal amount of
|| them in each row.
*/
html,
body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
body > div {
display: flex;
width: 100vw;
justify-content: space-between;
border: 1px solid black;
}
body > div > div {
display: flex;
flex-flow: row wrap;
}
body > div > div.red {
background: rgba(255, 0, 0, .1);
flex: 0 1 62%;
min-width: 60%;
justify-content: space-around;
}
body > div > div.green {
background: rgba(0, 255, 0, .1);
justify-content: space-around;
flex: 0 1 22%;
width: 20%;
}
body > div > div > div {
margin: 1em;
height: 5em;
width: 4em;
background: rgba(0, 0, 0, .1);
}
div.red > div:last-of-type {
opacity: 0;
}
<div>
<div class="red">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="green">
<div></div>
</div>
</div>
Would setting a max-width
on body > div > div.red
achieve what you're looking for?
JSFiddle
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