有一种方法使换行在多行flexbox?

例如,在这个CodePen的每个第三个项目之后中断。

.container { background: tomato; display: flex; flex-flow: row wrap; align-content: space-between; justify-content: space-between; } .item { width: 100px; height: 100px; background: gold; border: 1px solid black; font-size: 30px; line-height: 100px; text-align: center; margin: 10px; } .item:nth-child(3n) { 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>

Like

.item:nth-child(3n){
  /* line-break: after; */    
}

最简单、最可靠的解决方案是在正确的位置插入伸缩件。如果它们足够宽(宽度: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容器内生成伪元素,并使用顺序将它们移动到正确的位置。

.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和一个::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; /* CSS 2.1 syntax */
  break-after: always; /* CSS 3 syntax */
}

但是这些强制换行只适用于Firefox,而且我不认为它们应该适用于当前的规范。新提议的方法(没有在任何地方实现)是前后换行:

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


对于将来的问题,也可以通过使用float属性并在每个3个元素中清除它来实现。

我举了一个例子。

.grid { display: inline-block; } .cell { display: inline-block; position: relative; float: left; margin: 8px; width: 48px; height: 48px; background-color: #bdbdbd; font-family: 'Helvetica', 'Arial', sans-serif; font-size: 14px; font-weight: 400; line-height: 20px; text-indent: 4px; color: #fff; } .cell:nth-child(3n) + .cell { clear: both; } <div class="grid"> <div class="cell">1</div> <div class="cell">2</div> <div class="cell">3</div> <div class="cell">4</div> <div class="cell">5</div> <div class="cell">6</div> <div class="cell">7</div> <div class="cell">8</div> <div class="cell">9</div> <div class="cell">10</div> </div>


.container { background: tomato; display: flex; flex-flow: row wrap; align-content: space-between; justify-content: space-between; } .item { width: 100px; height: 100px; background: gold; border: 1px solid black; font-size: 30px; line-height: 100px; text-align: center; margin: 10px; } <div class="container"> <div> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> </div> <div> <div class="item">4</div> <div class="item">5</div> <div class="item">6</div> </div> <div> <div class="item">7</div> <div class="item">8</div> <div class="item">9</div> </div> <div class="item">10</div> </div>

您可以尝试将项目包装在像这样的dom元素中。有了这个,你不需要知道很多CSS只是有一个良好的结构将解决问题。


@Oriol有一个很好的答案,遗憾的是,截至2017年10月,既不显示:内容,也不分页后得到广泛支持,更好地说,这是关于Firefox的支持,但不支持其他播放器,我已经提出了以下“hack”,我认为比硬编码在每个第三个元素后中断,因为这将使它很难使页面移动友好。

正如所说,这是一个黑客,缺点是你需要添加相当多的额外元素,但它做到了技巧,即使在过时的IE11上也能跨浏览器工作。

“黑客”是简单地在每个div后面添加一个额外的元素,它被设置为display:none,然后使用css n -child来决定哪个元素应该实际上是可见的,强制像这样的行制动:

.container { background: tomato; display: flex; flex-flow: row wrap; 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-1) { background: silver; } .breaker { display: none; } .breaker:nth-child(3n) { display: block; width: 100%; height: 0; } <div class="container"> <div class="item">1</div> <p class="breaker"></p> <div class="item">2</div> <p class="breaker"></p> <div class="item">3</div> <p class="breaker"></p> <div class="item">4</div> <p class="breaker"></p> <div class="item">5</div> <p class="breaker"></p> <div class="item">6</div> <p class="breaker"></p> <div class="item">7</div> <p class="breaker"></p> <div class="item">8</div> <p class="breaker"></p> <div class="item">9</div> <p class="breaker"></p> <div class="item">10</div> <p class="breaker"></p> </div>


我认为传统的方式比较灵活,也比较容易理解:

标记

<div class="flex-grid">
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>
    <div class="col-4">.col-4</div>

    <div class="col-3">.col-3</div>
    <div class="col-9">.col-9</div>

    <div class="col-6">.col-6</div>
    <div class="col-6">.col-6</div>
</div>

创建grid.css文件:

.flex-grid {
  display: flex;
  flex-flow: wrap;
}

.col-1 {flex: 0 0 8.3333%}
.col-2 {flex: 0 0 16.6666%}
.col-3 {flex: 0 0 25%}
.col-4 {flex: 0 0 33.3333%}
.col-5 {flex: 0 0 41.6666%}
.col-6 {flex: 0 0 50%}
.col-7 {flex: 0 0 58.3333%}
.col-8 {flex: 0 0 66.6666%}
.col-9 {flex: 0 0 75%}
.col-10 {flex: 0 0 83.3333%}
.col-11 {flex: 0 0 91.6666%}
.col-12 {flex: 0 0 100%}

[class*="col-"] {
  margin: 0 0 10px 0;

  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

@media (max-width: 400px) {
  .flex-grid {
    display: block;
  }
}

我已经创建了一个示例(jsfiddle)

试着将窗口大小调整到400px以下,它是有响应的!!


从我的角度来看,使用<hr>元素作为伸缩项之间的换行符更有语义意义。

.container { 显示:flex; flex-flow:包装; } .container hr { 宽度:100%; } < div class = "容器" > < div > < / div > 1 2 < div > < / div > <人力资源> < div > 3 < / div > 2 < div > < / div > ... < / div >

在Chrome 66, Firefox 60和Safari 11中测试。


你想要语义换行?

然后考虑使用<br>。W3Schools可能会建议你BR只是用来写诗的(我的很快就会出现),但你可以改变它的风格,让它表现为一个100%宽度的块元素,将你的内容推到下一行。如果'br'建议一个断点,那么对我来说,它似乎比使用hr或100% div更合适,使html更具可读性。

在需要换行符的地方插入<br>,并像这样设置样式。

 // Use `>` to avoid styling `<br>` inside your boxes 
 .container > br 
 {
    width: 100%;
    content: '';
 }

你可以在媒体查询中禁用<br>,方法是适当地设置display:为block或none(我已经包含了一个这样的例子,但是省略了注释)。

如果需要,也可以使用order:来设置顺序。

你可以放很多你想要的,用不同的类或名字:-)

.container { background: tomato; display: flex; flex-flow: row wrap; 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 } .container > br { width: 100%; content: ''; } // .linebreak1 // { // display: none; // } // @media (min-width: 768px) // { // .linebreak1 // { // display: block; // } // } <div class="container"> <div class="item">1</div> <div class="item">2</div> <br class="linebreak1"/> <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>


没有必要把自己局限于W3Schools所说的:


另一个不需要添加任何额外标记的解决方案是添加一些动态边距来分隔元素。

在本例中,这可以通过calc()的帮助来完成,只需在3n+2元素(2,5,8)上添加左边距和右边距。

.item:nth-child(3n+2) {
  background: silver;
  margin: 10px calc(50% - 175px);
}

片段的例子

.container { background: tomato; display: flex; flex-flow: row wrap; align-content: space-between; justify-content: space-between; } .item { width: 100px; height: 100px; background: gold; border: 1px solid black; font-size: 30px; line-height: 100px; text-align: center; margin: 10px; } .item:nth-child(3n+2) { background: silver; margin: 10px calc(50% - 175px); } <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>


我只是想把这个答案放在一起,意在提醒大家,在适当的条件下,你有时不需要过度思考手头的问题。你想要的也许可以通过flex: wrap和max-width来实现,而不是:n -child。

ul { display: flex; flex-wrap: wrap; justify-content: center; max-width: 420px; list-style-type: none; background-color: tomato; margin: 0 auto; padding: 0; } li { display: inline-block; background-color: #ccc; border: 1px solid #333; width: 23px; height: 23px; text-align: center; font-size: 1rem; line-height: 1.5; margin: 0.2rem; flex-shrink: 0; } <div class="root"> <ul> <li>A</li> <li>B</li> <li>C</li> <li>D</li> <li>E</li> <li>F</li> <li>G</li> <li>H</li> <li>I</li> <li>J</li> <li>K</li> <li>L</li> <li>M</li> <li>N</li> <li>O</li> <li>P</li> <li>Q</li> <li>R</li> <li>S</li> <li>T</li> <li>U</li> <li>V</li> <li>W</li> <li>X</li> <li>Y</li> <li>Z</li> </ul> </div>

https://jsfiddle.net/age3qp4d/