最简单和最可靠的解决方案是在正确的位置插入弹性项目。如果它们足够宽(width: 100%
),它们将强制换行。
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(4n - 1) {
background: silver;
}
.line-break {
width: 100%;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="line-break"></div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="line-break"></div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="line-break"></div>
<div class="item">10</div>
</div>
但这样很丑不够语义化。相反,我们可以在 flex 容器内生成伪元素,并使用 order
将它们移到正确的位置。
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(3n) {
background: silver;
}
.container::before, .container::after {
content: '';
width: 100%;
order: 1;
}
.item:nth-child(n + 4) {
order: 1;
}
.item:nth-child(n + 7) {
order: 2;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
但是有一个限制:弹性容器只能有一个::before
和一个::after
伪元素。这意味着您只能强制换行2次。
为了解决这个问题,您可以在弹性项目中生成伪元素,而不是在弹性容器中生成。这样,您就不会被限制为2个。但是那些伪元素不会成为弹性项目,因此它们将无法强制换行。
但是幸运的是,《CSS Display L3》引入了display: contents
(目前仅由Firefox 37支持):
元素本身不会生成任何盒子,但其子元素和伪元素仍然像平常一样生成盒子。为了生成盒子和布局,必须将该元素视为已用其子元素和伪元素替换在文档树中。
因此,您可以将display: contents
应用于弹性容器的子元素,并将每个子元素的内容包装在一个额外的包装器中。然后,弹性项目将是那些额外的包装器和子元素的伪元素。
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
display: contents;
}
.item > div {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px;
}
.item:nth-child(3n) > div {
background: silver;
}
.item:nth-child(3n)::after {
content: '';
width: 100%;
}
<div class="container">
<div class="item"><div>1</div></div>
<div class="item"><div>2</div></div>
<div class="item"><div>3</div></div>
<div class="item"><div>4</div></div>
<div class="item"><div>5</div></div>
<div class="item"><div>6</div></div>
<div class="item"><div>7</div></div>
<div class="item"><div>8</div></div>
<div class="item"><div>9</div></div>
<div class="item"><div>10</div></div>
</div>
或者,根据规范的旧版本,Flexbox可以通过使用break-before
、break-after
或它们的CSS 2.1别名来实现强制换行:
.item:nth-child(3n) {
page-break-after: always;
break-after: always;
}
但是这些强制换行只在Firefox上有效,而且我认为根据当前规范它们不应该起作用。新提出的方式(尚未在任何地方实现)是使用wrap-before
或wrap-after
:
.item:nth-child(3n) {
wrap-after: flex;
}
.container {
background: tomato;
display: flex;
flex-flow: row wrap;
align-content: space-between;
justify-content: space-between;
}
.item {
width: 100px;
background: gold;
height: 100px;
border: 1px solid black;
font-size: 30px;
line-height: 100px;
text-align: center;
margin: 10px
}
.item:nth-child(3n) {
page-break-after: always;
break-after: always;
wrap-after: flex;
background: silver;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>