Html 如何在多行 flexbox 布局中指定换行符?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29732575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 03:52:26  来源:igfitidea点击:

How to specify line breaks in a multi-line flexbox layout?

htmlcssflexbox

提问by Artem Svirskyi

Is there a way to make a line break in multiple line flexbox?

有没有办法在多行 flexbox 中换行?

For example to break after each 3rd item in this CodePen.

例如在此 CodePen 中的每个第 3 项之后中断

.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; */    
}

回答by Oriol

The simplest and most reliable solution is inserting flex items at the right places. If they are wide enough (width: 100%), they will force a line break.

最简单和最可靠的解决方案是在正确的位置插入弹性项目。如果它们足够宽 ( 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>

But that's ugly and not semantic. Instead, we could generate pseudo-elements inside the flex container, and use orderto move them to the right places.

但这很丑陋而且没有语义。相反,我们可以在 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>

But there is a limitation: the flex container can only have a ::beforeand a ::afterpseudo-element. That means you can only force 2 line breaks.

但是有一个限制:flex 容器只能有一个::before和一个::after伪元素。这意味着您只能强制换行 2 个。

To solve that, you can generate the pseudo-elements inside the flex items instead of in the flex container. This way you won't be limited to 2. But those pseudo-elements won't be flex items, so they won't be able to force line breaks.

为了解决这个问题,你可以在 flex 项目中而不是在 flex 容器中生成伪元素。这样你就不会被限制为 2 个。但是那些伪元素不会是 flex 项目,因此它们将无法强制换行。

But luckily, CSS Display L3has introduced display: contents(currently only supported by Firefox 37):

但幸运的是,CSS Display L3已经引入display: contents(目前仅 Firefox 37 支持):

The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.

元素本身不会生成任何框,但其子元素和伪元素仍会正常生成框。出于框生成和布局的目的,必须将元素视为已被替换为文档树中的子元素和伪元素。

So you can apply display: contentsto the children of the flex container, and wrap the contents of each one inside an additional wrapper. Then, the flex items will be those additional wrappers and the pseudo-elements of the children.

因此,您可以应用display: contents到 flex 容器的子容器,并将每个容器的内容包装在一个额外的包装器中。然后,弹性项目将是那些额外的包装器和子元素的伪元素。

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

Alternatively, according to Fragmenting Flex Layoutand CSS Fragmentation, Flexbox allows forced breaks by using break-before, break-afteror their CSS 2.1 aliases:

另外,根据碎片的Flex布局CSS碎片,Flexbox,就允许通过使用强制休息break-beforebreak-after或它们的CSS 2.1别名:

.item:nth-child(3n) {
  page-break-after: always; /* CSS 2.1 syntax */
  break-after: always; /* New 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;
  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>

Forced line breaks in flexbox are not widely supported yet, but it works on Firefox.

flexbox 中的强制换行尚未得到广泛支持,但它适用于 Firefox。

回答by Petr Stepanov

From my perspective it is more semantic to use <hr>elements as line breaksbetween flex items.

从我的角度来看,使用<hr>元素作为弹性项目之间的换行符更具语义。

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

.container hr {
  width: 100%;
}
<div class="container">
  <div>1</div>
  <div>2</div>
  <hr>
  <div>3</div>
  <div>2</div>
  ...
</div>

Tested in Chrome 66, Firefox 60 and Safari 11.

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

回答by Emil Borconi

@Oriol has an excellent answer, sadly as of October 2017, neither display:contents, neither page-break-afteris widely supported, better said it's about Firefox which supports this but not the other players, I have come up with the following "hack" which I consider better than hard coding in a break after every 3rd element, because that will make it very difficult to make the page mobile friendly.

@Oriol 有一个很好的答案,遗憾的是,截至 2017 年 10 月,两者都display:contents没有page-break-after得到广泛支持,最好说它是关于 Firefox 支持这一点而不是其他玩家,我提出了以下我认为比困难更好的“黑客”在每个第三个元素之后中断编码,因为这会使页面移动友好变得非常困难。

As said it's a hack and the drawback is that you need to add quite a lot of extra elements for nothing, but it does the trick and works cross browser even on the dated IE11.

如前所述,这是一个 hack,缺点是你需要添加很多额外的元素,但它确实有效,即使在过时的 IE11 上也可以跨浏览器工作。

The "hack" is to simply add an additional element after each div, which is set to display:noneand then used the css nth-childto decide which one of this should be actually made visible forcing a line brake like this:

“hack”是在每个 div 之后简单地添加一个附加元素,该元素被设置为display:none然后使用 cssnth-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>

回答by Simon_Weaver

You want a semantic linebreak?

你想要一个语义换行符吗?

Then consider using <br>. W3Schools may suggest you that BRis just for writing poems (mine is coming soon) but you can change the style so it behaves as a 100% width block element that will push your content to the next line. If 'br' suggests a break then it seems more appropriate to me than using hror a 100% divand makes the html more readable.

然后考虑使用<br>. W3Schools 可能会建议您BR仅用于写诗(我的即将推出),但您可以更改样式,使其表现为 100% 宽度的块元素,将您的内容推送到下一行。如果 'br' 建议休息,那么它对我来说似乎比 usinghr或 100%更合适div,并使 html 更具可读性。

Insert the <br>where you need linebreaks and style it like this.

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

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

You can disable <br>with media queries, by setting display:to blockor noneas appropriate (I've included an example of this but left it commented out).

您可以通过设置为或适当地禁用<br>媒体查询(我已经包含了一个示例,但将其注释掉)。display:blocknone

You can use order:to set the order if needed too.

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

And you can put as many as you want, with different classes or names :-)

您可以根据需要使用不同的类或名称放置任意数量的 :-)

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



No need to limit yourself to what W3Schools says:

无需将自己限制在 W3Schools 所说的范围内:

enter image description here

在此处输入图片说明

回答by Moshe Quantz

I think the traditional way is flexible and fairly easy to understand:

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

Markup

标记

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

Create grid.cssfile:

创建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;
  }
}

I've created an example (jsfiddle)

我创建了一个例子(jsfiddle)

Try to resize the window under 400px, it's responsive!!

尝试将窗口大小调整到 400 像素以下,它是响应式的!!

回答by Juanma Menendez

Another possible solution that doesn't require to add any extra markup is to add some dynamic margin to separate the elements.

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

In the case of the example, this can be done with the help of calc(), just adding margin-leftand margin-rightto the 3n+2 element (2, 5, 8)

在示例的情况下,这可以在 的帮助下完成calc(),只需将margin-left和添加margin-right到 3n+2 元素 (2, 5, 8)

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

Snippet Example

片段示例

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

回答by Gabriel

For future questions, It's also possible to do it by using floatproperty and clearing it in each 3 elements.

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

Here's an example I've made.

这是我做的一个例子。

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

回答by Andrew

I tried several answers here, and none of them worked. Ironically, what did work was about the simplest alternative to a <br/>one could attempt:

我在这里尝试了几个答案,但都没有奏效。具有讽刺意味的是,有效的是关于<br/>可以尝试的最简单的替代方案:

<div style="flex-basis: 100%;"></div>

<div style="flex-basis: 100%;"></div>

or you could also do:

或者你也可以这样做:

<div style="width: 100%;"></div>

<div style="width: 100%;"></div>

Place that wherever you want a new line. It seems to work even with adjacent <span>'s, but I'm using it with adjacent <div>'s.

把它放在任何你想要新行的地方。它似乎与相邻的<span>'s一起工作,但我将它与相邻的<div>'s 一起使用。

回答by Naseeruddin V N

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

you could try wrapping the items in a dom element like here. with this you dont have to know a lot of css just having a good structure will solve the problem.

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