如何停止Flexbox中的最后一次保证金崩溃? [英] How can I stop the last margin collapsing in flexbox?
问题描述
我有一个项目列表,我试图安排成一个可滚动水平布局与flexbox。
容器中的每个项目都有左右边距,但最后一个项目的右边距已折叠。
是否有办法阻止此情况发生或是一个很好的解决方法?
问题Codepen: http://codepen.io/anon/pen/WxmdpN
ul {list-style-type:none; padding:0; margin:0;显示:flex; height:300px; overflow:auto; width:600px;背景:橙色;} ul li {background:blue; color:#fff; padding:90px; margin:0 30px; white-space:nowrap; flex-basis:auto;}
< div class容器> < ul> < li>项目1< / li> < li>第2项< / li> < li>项目3< / li> < li>项目4< / li> < / ul>< / div>
这似乎是所有主要浏览器的默认行为:在测试中,正确的边距在Firefox,Chrome,Safari,IE11和Edge中崩溃。
不进行大量的实验,我建议在规范中定义这个行为:
其他
属性的已使用值中必须包含以下约束:
margin-left
+border-left-width
++
width
+
padding-right
border-right-width +margin-right
=包含块的
的宽度
如果
width
不是auto
和border-left-width
+padding-left
+
width
+padding- / code> +
border-right-width
(加上
margin-left
margin-right
不是auto
)大于
包含块的宽度,auto
值
margin-left
或margin-right
对于以下规则,将
视为零。
如果上述所有计算值都不是
auto
,这些值被称为过约束,并且使用的值之一
将不得不与其计算值不同。如果包含块的方向
属性值为ltr
,则指定的
值margin-right
被忽略,并且该值被计算为
以使等式成立。 c $ c> direction 是rtl
,
这发生在margin-left
(强调已添加)
a href =https://www.w3.org/TR/CSS22/visudet.html =nofollow noreferrer> CSS可视化格式模型,您的包含块可能是过约束的,
甚至 justify-content:space-around
一个解决方案可能是在最后一个元素上添加右边框:
li:last-child {
border-right:30px solid orange;
}
ul {list-style-type:none; padding:0; margin:0;显示:flex; height:300px; overflow:auto; width:600px;背景:橙色;} ul li {background:blue; color:#fff; padding:90px; margin:0 30px; white-space:nowrap; flex-basis:auto;} li:last-child {border-right:30px solid orange;}
< ul> < li>项目1< / li> < li>第2项< / li> < li>项目3< / li> < li>项目4< / li>< / ul>
另一个解决方案使用伪元素作为弹性项占据空间:
ul :: after {
content:;
flex:0 0 30px;
}
ul {list-style-type:none; padding:0; margin:0; display:flex; height:300px; overflow:auto; width:600px; background:orange;} ul li {margin:0 30px;背景:蓝色; color:#fff; padding:90px; white-space:nowrap; flex-basis:auto;} ul :: after {content:; flex:0 0 30px;} ul :: before {content:; flex:0 0 30px;}
< ul& < li>项目1< / li> < li>第2项< / li> < li>项目3< / li> < li>第4项< / li>< / ul>
I have a list of items that I'm trying to arrange into a scrollable horizontal layout with flexbox.
Each item in the container has a margin left and right, but the right margin of the last item is being collapsed.
Is there a way to stop this happening, or a good workaround?
Codepen of issue: http://codepen.io/anon/pen/WxmdpN
ul {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
height: 300px;
overflow: auto;
width: 600px;
background: orange;
}
ul li {
background: blue;
color: #fff;
padding: 90px;
margin: 0 30px;
white-space: nowrap;
flex-basis: auto;
}
<div class"container">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
This appears to be the default behavior on all major browsers: In testing, the right margin collapses in Firefox, Chrome, Safari, IE11 and Edge.
Without going into a great deal of experimentation, I'll suggest that this behavior is defined in the spec:
10.3.3 Block-level, non-replaced elements in normal flow
The following constraints must hold among the used values of the other properties:
margin-left
+border-left-width
+padding-left
+width
+padding-right
+border-right-width
+margin-right
= width of containing blockIf
width
is notauto
andborder-left-width
+padding-left
+width
+padding-right
+border-right-width
(plus any ofmargin-left
ormargin-right
that are notauto
) is larger than the width of the containing block, then anyauto
values formargin-left
ormargin-right
are, for the following rules, treated as zero.If all of the above have a computed value other than
auto
, the values are said to be "over-constrained" and one of the used values will have to be different from its computed value. If thedirection
property of the containing block has the valueltr
, the specified value ofmargin-right
is ignored and the value is calculated so as to make the equality true. If the value ofdirection
isrtl
, this happens tomargin-left
instead(emphasis added)
So, according to the CSS Visual Formatting Model, your containing block may be "over-constrained" and, as a result, a right margin gets tossed out.
Not even justify-content: space-around
on the container is enough to add right margin space at the end of the line.
One solution may be to add a right border to your last element:
li:last-child {
border-right: 30px solid orange;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
height: 300px;
overflow: auto;
width: 600px;
background: orange;
}
ul li {
background: blue;
color: #fff;
padding: 90px;
margin: 0 30px;
white-space: nowrap;
flex-basis: auto;
}
li:last-child {
border-right: 30px solid orange;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
Another solution uses a pseudo-element as a flex item to occupy space:
ul::after {
content: "";
flex: 0 0 30px;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
height: 300px;
overflow: auto;
width: 600px;
background: orange;
}
ul li {
margin: 0 30px;
background: blue;
color: #fff;
padding: 90px;
white-space: nowrap;
flex-basis: auto;
}
ul::after {
content: "";
flex: 0 0 30px;
}
ul::before {
content: "";
flex: 0 0 30px;
}
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
这篇关于如何停止Flexbox中的最后一次保证金崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!