Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing extra spacing on a flexbox with wrapped children?

Tags:

css

flexbox

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 enter image description here

What I want it to do enter image description here

Code

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

like image 896
timofey.com Avatar asked Jun 17 '16 17:06

timofey.com


People also ask

How do I get rid of extra margin on Fitbit Flex?

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.

How do you reduce the gap between Flex rows?

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.

Does gap work with Flexbox?

Examples. The gap property is designed for use in grid, flex and multi-column layouts.


2 Answers

UPDATE 2

All criteria have been met to the best of my knowledge.

  • No fixed widths
  • Accommodates content of various widths
  • No excessive padding

Changes

  • Red box has justify-content: space-between which reduces the padding on both left and right sides of the red box.
  • Each flex item (with the exception of flex-ghost) is flex: 0 0 auto.
  • Flex-ghost is now pure width, no height with flex: 2 0 auto.
  • Added a little JS to make it interactive.

PLUNKER


UPDATE 1

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:

  1. justify-content: space-around will work perfectly if you do the next step.
  2. Add one more flex item to make the rows even, and if you have to have an odd amount of flex items, make the last item invisible either with 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).

SNIPPET

/* 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>
like image 121
zer00ne Avatar answered Sep 30 '22 19:09

zer00ne


Would setting a max-width on body > div > div.red achieve what you're looking for?

JSFiddle

like image 26
Nicholas Qiao Avatar answered Sep 30 '22 18:09

Nicholas Qiao