Last margin / padding collapsing in flexbox / grid layout(flexbox/网格布局中的最后一个边距/填充折叠)
问题描述
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?
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>
Potential Problem #1
The last margin is not being collapsed. It's being ignored.
The overflow
property applies only to content. It doesn't apply to padding or margins.
Here's what it says in the spec:
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.
Now let's take a look at the CSS Box Model:
source: W3C
The overflow
property is limited to the content box area. If the content overflows its container, then overflow
applies. But overflow
doesn't enter into the padding or margin areas (unless, of course, there is more content that follows).
Potential Problem #2
The problem with Potential Problem #1 is that it appears to fall apart outside of a flex or grid formatting context. For example, in a standard block layout, the last margin doesn't appear to collapse. So maybe overflow
is permitted to cover margins / paddings, regardless of what it says in the spec.
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>
Hence, maybe the problem is instead related to elements that are "over-constrained".
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, elements may be "over-constrained" and, as a result, a right margin gets tossed out.
Potential Workarounds
Instead of margin or padding, use a right border on the last element:
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>
Another solution uses a pseudo-elements instead of margins or padding.
Pseudo-elements on a flex container are rendered as flex items. The first item in the container is ::before
and last item is ::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>
这篇关于flexbox/网格布局中的最后一个边距/填充折叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:flexbox/网格布局中的最后一个边距/填充折叠


- 是否可以将标志传递给 Gulp 以使其以不同的方式 2022-01-01
- 如何调试 CSS/Javascript 悬停问题 2022-01-01
- 使用 iframe URL 的 jQuery UI 对话框 2022-01-01
- 如何显示带有换行符的文本标签? 2022-01-01
- 如何向 ipc 渲染器发送添加回调 2022-01-01
- 从原点悬停时触发 translateY() 2022-01-01
- 在不使用循环的情况下查找数字数组中的一项 2022-01-01
- 我不能使用 json 使用 react 向我的 web api 发出 Post 请求 2022-01-01
- 为什么我的页面无法在 Github 上加载? 2022-01-01
- 为什么悬停在委托事件处理程序中不起作用? 2022-01-01