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
How to specify line breaks in a multi-line flexbox layout?
提问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 order
to 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 ::before
and a ::after
pseudo-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: contents
to 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-after
or their CSS 2.1 aliases:
另外,根据碎片的Flex布局和CSS碎片,Flexbox,就允许通过使用强制休息break-before
,break-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-after
is 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:none
and then used the css nth-child
to 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 BR
is 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 hr
or a 100% div
and 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 block
or none
as appropriate (I've included an example of this but left it commented out).
您可以通过设置为或适当地禁用<br>
媒体查询(我已经包含了一个示例,但将其注释掉)。display:
block
none
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 所说的范围内:
回答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-left
and margin-right
to 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 float
property 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,只要有一个好的结构就可以解决问题。