我有一个元素列表,我正在尝试使用 flexbox 将其排列成可滚动的水平布局。
容器中的每个元素都有左右边距,但最后一个元素的右边距正在折叠。
有没有办法阻止这种情况发生,或者有好的解决方法?
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>
最佳答案
潜在问题#1
最后一个边距没有折叠。它被忽略了。
overflow
属性仅适用于content。它不适用于填充或边距。
这是规范中的内容:
11.1.1 Overflow: the
overflow
propertyThis property specifies whether content of a block container element is clipped when it overflows the element's box.
现在让我们看一下 CSS Box Model :
来源:W3C
overflow
属性仅限于内容框区域。如果内容溢出其容器,则 overflow
适用。但是 overflow
不会进入填充或边距区域(当然,除非后面有更多内容)。
潜在问题 #2
潜在问题 #1 的问题在于它似乎在 flex 或网格格式上下文之外崩溃了。例如,在标准 block 布局中,最后一个边距似乎没有折叠。所以也许 overflow
被允许覆盖边距/填充,不管它在规范中是怎么说的。
div {
height: 150px;
overflow: auto;
width: 600px;
background: orange;
white-space: nowrap;
}
span {
background: blue;
color: #fff;
padding: 50px;
margin: 0 30px;
display: inline-block;
}
<div class="container">
<span>Item 1</span>
<span>Item 2</span>
<span>Item 3</span>
<span>Item 4</span>
</div>
因此,问题可能与“过度约束”的元素有关。
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)
所以,根据 CSS Visual Formatting Model ,元素可能会“过度约束”,因此右边距会被丢弃。
潜在的解决方法
代替边距或填充,在最后一个元素上使用右边框:
li:last-child {
border-right: 30px solid orange;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
height: 100px; /* adjusted for demo */
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>
另一种解决方案使用伪元素代替边距或填充。
flex 容器上的伪元素呈现为 flex 元素。容器中的第一项是 ::before
,最后一项是 ::after
。
ul::after {
content: "";
flex: 0 0 30px;
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
display: flex;
height: 100px; /* adjusted for demo */
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>
关于html - flexbox/网格布局中的最后边距/填充折叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45681599/