46

Is there a way to put a full unit of space on both sides of all items, including the first and last?

I am trying to find a way to have equal spacing around flexbox children.

In this article it seems like the nearest thing is justify-content: space-around. It says that:

space-around: items are evenly distributed in the line with equal space around them. Note that visually the spaces aren't equal, since all the items have equal space on both sides. The first item will have one unit of space against the container edge, but two units of space between the next item because that next item has its own spacing that applies.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Alexis
  • 23,545
  • 19
  • 104
  • 143
  • Check this thread https://stackoverflow.com/questions/42287771/justify-content-space-between-with-equal-space-between-first-and-last-items-als It has a similar question. – Rajesh P Jul 17 '17 at 00:28
  • @RajeshP the 'pseudo element' method they describe is the sorta hack I'm using now – Alexis Jul 17 '17 at 00:40
  • 1: Are we talking about 1 line (row) or multi-line? ... 2: Is the amount of items per row known? – Asons Jul 17 '17 at 20:36

6 Answers6

44

There are at least two methods for equal space between all items, including the first and last items. One method, however, doesn't yet have full browser support.


pseudo-elements

Note this section from Firefox documentation:

In-flow ::after and ::before pseudo-elements are now flex items.

In fact, all major browsers consider pseudo-elements on a flex container to be flex items.

Knowing that, add ::before and ::after to your container.

With justify-content: space-between and zero-width pseudo-elements, the visible flex items will appear evenly spaced.

flex-container {
  display: flex;
  justify-content: space-between;
}

flex-container::before {
  content: "";
}

flex-container::after {
  content: "";
}

/* non-essential decorative styles */
flex-container {
  padding: 5px 0;
  background-color: lightyellow;
  border: 1px solid #aaa;
}
flex-item {
  height: 50px;
  width: 75px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

space-evenly

The CSS Box Alignment Module, which is the W3C's unfinished proposal to establish a common set of alignment properties for use across all box models, provides the space-evenly value for use with the justify-content and align-content properties.

4.3. Distributed Alignment: the stretch, space-between, space-around, and space-evenly keywords

space-evenly

The alignment subjects are evenly distributed in the alignment container, with a full-size space on either end.

The alignment subjects are distributed so that the spacing between any two adjacent alignment subjects, before the first alignment subject, and after the last alignment subject is the same.

As of this writing, however, it looks like space-evenly only works in Firefox and Chrome.

flex-container {
  display: flex;
  justify-content: space-evenly;
}

/* non-essential decorative styles */
flex-container {
  padding: 5px 0;
  background-color: lightyellow;
  border: 1px solid #aaa;
}
flex-item {
  height: 50px;
  width: 75px;
  background-color: lightgreen;
}
<flex-container>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
  <flex-item></flex-item>
</flex-container>

Also, here's a useful demo from the MDN justify-content page for testing space-evenly and other values in your browser. https://jsfiddle.net/gkrsr86n/

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
17

This is a perfect use case for flex-basis and justify-content: space-between if you know how many components will be in your row beforehand. Specify a flex-basis percentage on your flex-items that totals less than 100% for all items. The leftover percentages will become margins.

No psuedo elements, child selectors or padding/margin.

div {
  display: flex;
  justify-content: space-between;
  height: 100px;


}
span {
  flex-basis: 32%;
  background: red;
}
<div>
  <span></span>
  <span></span>
  <span></span>
</div>
J.McLaren
  • 611
  • 6
  • 9
  • 1
    If there's text in the red boxes and you want to even up the space between the chunks of text (i.e. no red boxes--homogeneous background), add this to the span tag: `max-width: max-content`. – Luther Jun 20 '21 at 08:09
  • So they go hand in hand – themhz Dec 23 '21 at 13:50
  • Read more on MDN docs: [flex-basis](https://developer.mozilla.org/en-US/docs/Web/CSS/flex-basis). This is the way, I've never used/understood this before. – Enfield Li Oct 07 '22 at 18:37
15

You can do this by setting the padding of the flex container and the margin of the flex items:

.container { 
  display: flex;   
  padding: 0 1%;
}
.item { 
  flex: 1; 
  margin: 0 1%;
}

https://codepen.io/danieldilly/pen/PjgRbe

Daniel D
  • 918
  • 9
  • 18
9

In firefox only there is a space-evenly value for justify-content that does this.

It's in the CSS3 working draft

https://www.w3.org/TR/css-align-3/#valdef-align-content-space-evenly

div {
  display: flex;
  height: 100px;
  justify-content: space-evenly;
  border: 1px solid black;
  margin: auto;
}
span {
  width: 20%;
  background: red;
}
<div>
  <span></span>
  <span></span>
  <span></span>
</div>
Michael Coker
  • 52,626
  • 5
  • 64
  • 64
0

You could try this:

*, *:before, *:after {
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}
.list_wrap {
  display: flex;
  flex-wrap: wrap;
  border: 1px solid purple;
  padding-top: 5px;
}
.list_item {
  width: 24%;
  margin-right: 0.8%;
  margin-bottom: 5px;
  height: 30px;
  border: 1px solid green;
}
.list_item:nth-child(4n+1) {
  margin-left: 0.8%;
}
<div class="list_wrap">
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
  <div class="list_item"></div>
</div>
itacode
  • 3,721
  • 3
  • 21
  • 23
-2

You can use flexbox's all property form here. this is perfect example for how to use complete flex property with example http://the-echoplex.net/flexyboxes/

Anil
  • 523
  • 1
  • 8
  • 16
  • 4
    It is simply a link to an external resource, which is not recommended. Please read https://stackoverflow.com/help/how-to-answer to maximize the chance to have your answers upvoted – Asons Jul 17 '17 at 08:53