Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pseudo elements breaking justify-content: space-between in flexbox layout

I have three divs inside a parent div that are being spaced out using:

display: flex;
justify-content: space-between;

However, the parent div has an :after on it which is making the three divs not go out to the edge of parent div. Is there a way to have flexbox ignore the :before and :after?

codepen.io

.container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  background: gray;
}

.container div {
    background: red;
    height: 245px;
    width: 300px;
  }
.container:before {
    content: '';
    display: table;
  }
.container:after {
    clear: both;
    content: '';
    display: table;
  }
<div class="container">
  <div></div>
  <div></div>
  <div></div>
</div>
like image 552
Landon Call Avatar asked Nov 18 '16 22:11

Landon Call


People also ask

How do I reduce space between items in flexbox?

To set space between the flexbox you can use the flexbox property justify-content you can also visit all the property in that link. We can use the justify-content property of a flex container to set space between the flexbox.

Can I use justify-content space-evenly?

The "space-evenly" value for the justify-content property distributes the space between items evenly. It is similar to space-around but provides equal instead of half-sized space on the edges. Can be used in both CSS flexbox & grid.


2 Answers

Short Answer

In CSS, there is currently no 100% reliable way to prevent pseudo-elements from impacting the justify-content: space-between calculation.

Explanation

::before and ::after pseudo elements on a flex container become flex items.

From the spec:

4. Flex Items

Each in-flow child of a flex container becomes a flex item.

In other words, each child of a flex container that is in the normal flow (i.e., not absolutely positioned), is considered a flex item.

Most, if not all, browsers interpret this to include pseudo-elements. The ::before pseudo is the first flex item. The ::after item is the last.

Here is further confirmation of this rendering behavior from Firefox documentation:

In-flow ::after and ::before pseudo-elements are now flex items (bug 867454).

One possible solution to your problem is to remove the pseudo-elements from the normal flow with absolute positioning. However, this method may not work in all browsers:

  • Absolutely positioned flex item is not removed from normal flow in Firefox & IE11

See my answer here for illustrations of pseudo elements messing up justify-content:

  • justify-content: space-between failing to align elements as expected
like image 94
Michael Benjamin Avatar answered Nov 02 '22 20:11

Michael Benjamin


If this an inherited property, just override it

.container {
  width: 100%;
  display: flex;
  justify-content: space-between;
  padding-top: 50px;
  background: gray;
}

.container div {
    background: red;
    height: 245px;
    width: 100px;
}

/* definitions from a framework */
.container:before {
    content: '';
    display: table;
  }
.container:after {
    clear: both;
    content: '';
    display: table;
  }

/* definitions override */
.container.flexcontainer:before, 
.container.flexcontainer:after {
   display: none;  
}
<div class="container flexcontainer">
  <div></div>
  <div></div>
  <div></div>
</div>
like image 34
vals Avatar answered Nov 02 '22 19:11

vals