左边距不适用于浮动后的 overflow:auto 元素

left margin not working on overflow:auto element following the float

我目前正在尝试创建一个两列布局,其中左列是浮动的,右列通过形成新的块格式化上下文来限制浮动。这样可行。后来,我尝试在左栏和右栏的内容之间放置一些可见的space。如果我在右列上设置左填充,它就可以工作。我还尝试用右列的左边距替换左边的填充,并认为它们会产生相同的效果。然而,令我惊讶的是,左边距根本不起作用

我用下面的代码重现了这个问题。请注意中间的示例,在右列上设置左边距并没有真正将其推离左列

* {
  margin: 0;
  padding: 0;
}

.container {
  height: 50px;
  line-height: 50px;
  width: 500px;
}

.container + .container {
  margin-top: 20px
}

.left {
  float: left;
  width: 150px;
  height: 100%;
  background: orange;
  text-align: center;
}

.right {
  overflow: auto;
  background: skyblue;
  height: 100%;
}

.with-padding {
  padding-left: 30px;
}

.with-margin {
  margin-left: 30px;
}
<div class="container">
  <div class="left">left column, floated</div>
  <div class="right with-padding">
    <p>left padding works</p>
  </div>
</div>

<div class="container">
  <div class="left">left column, floated</div>
  <div class="right with-margin">
    <p>left margin dost not work</p>
  </div>
</div>

<div class="container">
  <div class="left">left column, floated</div>
  <div class="right">
    <div class="with-margin">
      <p>left margin works on the wrapper div</p>
    </div>
  </div>
</div>

我确实在互联网上搜索过这个主题,但没有找到太多相关信息。我怀疑这可能与块格式化上下文 (BFC) 的概念有关。如果我没理解错的话,margin 表示目标框的外边缘和包含 BFC 的内边界之间的距离。

如果我们在一个本身形成自己的 BFC 的盒子上设置边距,那么边距不应该起作用吗?所以在第三个示例中,我将文本放入一个额外的包装器中并在该包装器上设置边距,看起来左边距再次起作用。不过,这只是我的猜测。

这里的关键点在于

The border box of ... an element in the normal flow that establishes a new block formatting context (such as an element with overflow other than visible) must not overlap the margin box of any floats ...

CSS 2.2 Section 9.5 Floats

所以这样一个 BFC 的边界框外的边距可以(在你的第二种情况下)与浮动重叠,但边界框内的填充不能。