伪元素破坏了flexbox布局中的justify-content: space-between

20

我有一个父级div里面包含三个子级div,它们之间的距离是通过以下方式实现的:

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

然而,父级 div 上有一个 :after,这使得三个 div 不会到达父级 div 的边缘。是否有一种方法可以让 flexbox 忽略 :before: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>


1
你为什么要在flexbox容器上应用clearfix呢? - connexo
1
所有容器都具有相同的伪元素,无论我们是否在其中使用flexbox。 - Parzi
那么,这就是你应该停止的无聊行为... - CBroe
@CBroe,这些伪元素在Bootstrap中是标准配置。也许那就是来源。https://dev59.com/u1sV5IYBdhLWcg3w2h0s - Michael Benjamin
4
这是我非常不喜欢 CSS 框架的原因之一,其中还有成千上万个其他原因。 - connexo
1
@Michael_B 我知道它们是Bootstrap的标准配置;但没有人强制任何人使用默认的Bootstrap类,或者不覆盖在实际情况下没有意义的东西。而在flexbox中使用clearfix并没有任何作用,只会导致额外的问题。 - CBroe
4个回答

26

简短回答

CSS中目前没有一种100%可靠的方法来防止伪元素影响justify-content: space-between计算。

解释

在flex容器上的::before::after伪元素成为flex项目。

根据规范:

4. Flex Items

flex容器的每个流动子项都变成了flex项目。

换句话说,flex容器的每个正常流(即非绝对定位)的子项都被视为flex项目。

大多数,如果不是全部,浏览器将伪元素视为子项。 ::before伪元素是第一个flex项目。最后一个项目是::after项。

下面是来自Firefox文档的此渲染行为的进一步确认:

流动的::after::before伪元素现在是flex项目bug 867454)。

解决问题的一个可能方法是使用绝对定位将伪元素从正常流中删除。但是,这种方法可能在所有浏览器中都无法工作:

请查看我的答案以了解伪元素如何混乱justify-content的说明:


2
谢谢,这让我找到了答案,只需在父级内再添加一个包装 div。 - Parzi
谢谢,使用了 :before 不起作用。尝试了 ::before,嗯! - Pierre

8
如果这是一个继承属性,只需覆盖它即可。

.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>


3
在父级div中嵌套另一个div,并将所有的flex代码赋给该div,这样伪元素就不会影响它。

0

如果你必须这样做,你可以利用 flex 项目的自动边距行为。你还需要将第一个 flex 子元素的左边距归零,并将最后一个 flex 子元素的右边距同样归零。请参见下面的 codepen。

Flexbox 和自动边距:https://www.w3.org/TR/css-flexbox-1/#auto-margins

Codepen 演示:http://codepen.io/anderskleve/pen/EWvxqm

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

  div {
    background: red;
    height: 245px;
    width: 300px;
    margin: 0 auto;
  }

  div:first-child {
    margin-left: 0;
  }

  div:last-child {
    margin-right: 0;
  }

  &:before {
    content:'';
    display: table;
  }

  &:after {
    clear: both;
    content: '';
    display: table;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接