潜在问题 #1
最后一个边距没有被折叠。它被忽略了。
该overflow
属性仅适用于content。它不适用于填充或边距。
这是规范中所说的:
11.1.1 溢出:overflow
属性
此属性指定块容器元素的内容在溢出元素的框时是否被剪裁。
现在让我们看一下CSS 盒子模型:
来源:W3C
该overflow
属性仅限于内容框区域。如果内容溢出其容器,则overflow
应用。但overflow
不会进入填充或边距区域(当然,除非后面还有更多内容)。
潜在问题 #2
潜在问题 #1 的问题在于它似乎在 flex 或 grid 格式化上下文之外分崩离析。例如,在标准块布局中,最后一个边距似乎不会折叠。所以也许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 正常流程中的块级、非替换元素
在其他属性的使用值中必须保持以下约束:
margin-left
+ border-left-width
+ padding-left
+ width
+
padding-right
+ border-right-width
+ margin-right
= 包含块的宽度
如果width
is notauto
并且border-left-width
+ padding-left
+
width
+ padding-right
+ border-right-width
(加上任何
margin-left
or margin-right
that are not auto
)大于包含块的宽度,则对于以下规则, or的任何auto
值
都被视为零。margin-left
margin-right
如果以上所有的计算值都不auto
是 ,则这些值被称为“过度约束”,并且使用的值之一必须与其计算值不同。如果direction
包含块的属性ltr
值为 ,margin-right
则忽略 的指定值并计算该值以使等式成立。如果 的值为 ,则direction
发生rtl
这种情况margin-left
(重点补充)
因此,根据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>
另一种解决方案使用伪元素而不是边距或填充。
弹性容器上的伪元素被渲染为弹性项目。容器中的第一项是::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>