最简单、最可靠的解决方案是将柔性物品插入正确的位置。如果它们足够宽(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>
但有一个限制:flex容器只能有一个::before
and a ::after
伪元素。这意味着您只能强制换行 2 次。
为了解决这个问题,您可以在 Flex 项目内而不是在 Flex 容器中生成伪元素。这样您就不会被限制为 2 个。但是这些伪元素不会是弹性项目,因此它们无法强制换行。
但幸运的是,CSS 显示 L3 http://www.w3.org/TR/css-display-3/已经介绍了display: contents http://www.w3.org/TR/css-display-3/#valdef-display-outside-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>
或者,根据旧版本的规范 https://www.w3.org/TR/2014/WD-css-flexbox-1-20140925/#algo-line-break, Flexbox 允许通过使用强制中断break-before https://developer.mozilla.org/en-US/docs/Web/CSS/break-before, break-after https://developer.mozilla.org/en-US/docs/Web/CSS/break-after或其旧的 CSS 2.1 别名:
.item:nth-child(3n) {
page-break-after: always; /* CSS 2.1 syntax */
break-after: always; /* CSS 3 syntax */
}
但这些强制换行符仅适用于 Firefox,而且我认为它们不应该按照当前规范工作。新提出的方法(未在任何地方实施)是wrap-before or wrap-after https://www.w3.org/TR/css-text-4/#wrap-before:
.item:nth-child(3n) {
wrap-after: flex; /* New proposed syntax */
}
.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>