Flexbox /网格布局中的上一个边距/填充折叠

Kev*_*son 26 html css css3 flexbox css-grid

我有一个项目列表,我试图安排到一个可滚动的水平布局与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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

Mic*_*l_B 41

潜在问题#1

最后一个保证金没有被折叠.它被忽略了.

overflow属性仅适用于内容.它不适用于填充或边距.

这是它在规范中所说的内容:

11.1.1溢出:overflow 属性

此属性指定块容器元素的内容在溢出元素框时是否被剪切.

现在让我们来看看CSS Box模型:

在此输入图像描述

来源:W3C

overflow属性限制为内容框区域.如果内容溢出其容器,则overflow应用.但是overflow没有进入填充或边缘区域(当然,除非有更多内容).


潜在的问题#2

潜在问题#1的问题在于它似乎在弹性或网格格式化上下文之外崩溃.例如,在标准块布局中,最后一个边距似乎不会崩溃.所以可能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;
}
Run Code Online (Sandbox Code Playgroud)
<div class="container">
    <span>Item 1</span>
    <span>Item 2</span>
    <span>Item 3</span>
    <span>Item 4</span>
</div>
Run Code Online (Sandbox Code Playgroud)

因此,问题可能与"过度约束"的元素有关.

10.3.3正常流程中的块级非替换元素

其他属性的已使用值必须包含以下约束:

margin-left+ border-left-width+ padding-left+ width+ padding-right+ border-right-width+ margin-right=包含块的宽度

如果width不是autoborder-left-width+ padding-left+ width+ padding-right+ border-right-width(加上任何 margin-leftmargin-right不是auto)大于包含块的宽度,则对于以下规则的任何automargin-left或者margin-right被视为零.

如果以上所有都具有除了之外的计算值auto,则该值被称为"过度约束",并且所使用的值之一必须与其计算值不同.如果direction 包含块的属性具有该值ltr,margin-right则忽略指定的值,并计算该值以使等式为true.如果值directionrtl,发生这种情况,margin-left而不是

(重点补充)

因此,根据CSS视觉格式模型,元素可能会"过度约束",因此,右边距会被抛弃.


潜在的解决方法

而不是边距或填充,在最后一个元素上使用右边:

li:last-child {
  border-right: 30px solid orange;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>
Run Code Online (Sandbox Code Playgroud)

另一种解决方案使用伪元素而不是边距或填充.

Flex容器上的伪元素呈现为弹性项目.容器中的第一项是::before最后一项::after.

ul::after {
  content: "";
  flex: 0 0 30px;
}
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
</ul>
Run Code Online (Sandbox Code Playgroud)


val*_*als 6

您的问题不是利润本身。它是滚动条,仅对元素的可见内容进行标注。

解决该问题的一种方法是创建一个占据边距的可见元素

此解决方案在最后一个子节点上使用伪指令来处理此问题

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;
  position: relative;
}
li:last-child:after {
  content: "";
  width: 30px;
  height: 1px;
  position: absolute;
  left: 100%;
  top: 0px;
}
Run Code Online (Sandbox Code Playgroud)
<div class"container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)


Mar*_*ude -2

查看解决方案。我删除white-spaceflex-basismargin,为您提供纯粹的弹性盒解决方案。

它依赖于flex-flow: row(水平)、justify-content: space-around(你的边距),仅此而已!由于 90px 的填充将框的总宽度设置为超过 600px(在代码片段中定义),因此更改width为。1200px

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-flow: row ;
  justify-content: space-around;
  height: 300px;
  overflow: auto;
  width: 1200px;
  background: orange;
}
ul li {
  background: blue;
  color: #fff;
  padding: 90px;
}
Run Code Online (Sandbox Code Playgroud)
<div class"container">
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
    <li>Item 4</li>
  </ul>
</div>
Run Code Online (Sandbox Code Playgroud)