html - float 元素旁边的 margin-top 产生意外结果

标签 html css css-float

我遇到这样的布局问题:

.wrapper {
  clear: both;
  background-color: #ccc;
}

.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  margin-left: 100px;
  background: lightgreen;
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

<div class="wrapper">
  <div class="top">
    <div class="box">top</div>
  </div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

.main.side 元素需要对齐。正如您在上面的代码片段中看到的,一切都很好,除非 .top 元素没有高度,在这种情况下 margin-top 规则会导致它们倾斜。以下所有方法都“修复”了该问题,但每个方法都有一个缺点:

  • .wrapper添加边框(我也许可以接受透明边框,但我真的不喜欢这个,因为它感觉像是一个肮脏的黑客,我宁愿不添加边框.由于某种原因,边框的宽度需要至少为 1px,否则不起作用)

.wrapper {
  clear: both;
  background-color: #ccc;
  border: 1px solid #000;
}

.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  margin-left: 100px;
  background: lightgreen;
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

  • overflow:hidden 添加到 .wrapper(这会隐藏某些元素的一部分,并导致其他元素落在错误的位置)
  • overflow: auto 添加到 .wrapper(这会在某些情况下添加滚动条)

最后两个在我的代码片段中并不明显,但在现实世界的应用程序中它们会导致如上所述的问题 here .

我强烈怀疑该问题与 Why doesn't the height of a container element increase if it contains floated elements? 有关和 CSS container doesn't stretch to accommodate floats但我已经尝试了很多这些建议,但似乎都没有完全解决问题 - 也许是因为我的一个 div 是 float 的,而另一个不是。

由于这是大型应用程序的一部分,我不想大幅更改布局,只需使用一些 css 来保持 .main.side 对齐无论这些元素之前的内容如何。

最佳答案

您可以将主要元素设置为inline-block并使用calc来设置宽度。这不会对您的布局产生太大影响,您将得到正确的输出:

.main {
  width:calc(100% - 100px);
  display:inline-block;
  background: lightgreen;
}

完整代码:

.wrapper {
  background-color: #ccc;
  clear: both;
}
.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  width:calc(100% - 100px);
  display:inline-block;
  background: lightgreen;
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

<div class="wrapper">
  <div class="top">
    <div class="box">top</div>
  </div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>


另一个hacky想法是确保你的顶部元素永远不为空:

.top:empty {
  font-size:0;
}
.top:empty::before {
  content: "\80"; /* a random character */
}

完整代码

.wrapper {
  background-color: #ccc;
  clear: both;
}

.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  margin-left: 100px;
  background: lightgreen;
}

.top:empty {
  font-size:0;
}
.top:empty::before {
  content: "\80"; /* a random character */
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

<div class="wrapper">
  <div class="top">
    <div class="box">top</div>
  </div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>


您也可以考虑相同的技巧,但在主包装器上使用伪元素:

.wrapper::before {
  content: "\80"; /* a random character */
  display:block;
  font-size:0;
}

完整代码

.wrapper {
  background-color: #ccc;
  clear: both;
}

.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  margin-left: 100px;
  background: lightgreen;
}

.wrapper::before {
  content: "\80"; /* a random character */
  display:block;
  font-size:0;
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

<div class="wrapper">
  <div class="top">
    <div class="box">top</div>
  </div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>


您还可以使包装器 inline-block 的宽度等于 100%,它的行为几乎与 block 元素相同:

.wrapper {
  background-color: #ccc;
  display:inline-block;
  width:100%;
  vertical-align:top; /* avoid some unwanted white space issue*/
}

.wrapper+.wrapper {
  margin-top: 50px;
}

.side,
.main {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  margin-top: 20px;
}

.box {
  padding: 10px;
}

.top {
  background: yellow;
}

.side {
  width: 100px;
  float: left;
  background: lightblue;
}

.main {
  margin-left: 100px;
  background: lightgreen;
}
<div class="wrapper">
  <div class="top"></div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>

<div class="wrapper">
  <div class="top">
    <div class="box">top</div>
  </div>
  <div class="side">side</div>
  <div class="main">main</div>
</div>


作为解释,您面临着 the specification 中描述的边距崩溃问题。 :

Two margins are adjoining if and only if:

  • both belong to in-flow block-level boxes that participate in the same block formatting context
  • no line boxes, no clearance, no padding and no border separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
  • both belong to vertically-adjacent box edges, i.e. form one of:
    • top margin of a box and top margin of its first in-flow child

关于html - float 元素旁边的 margin-top 产生意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59330478/

相关文章:

html - 如何将移动设备上的所有共享按钮集中到一行?

javascript - jquery(tab系统)计算高度并将高度添加到div

css - item多行时如何在同一行显示字段标签和字段项?

javascript - 如何制作顶部带有 Logo 标题的网格?

css - div 标签的高度属性不允许菜单栏的子菜单

javascript - 打印时保留内联 CSS

html - Flexbox 无法在 Firefox 中正常工作

android - 在android中的电子邮件正文中发送带有数据库表的Html电子邮件

jquery - 使用 jquery 动画切换 2 个 float Div

css - div 边框不尊重 float ,而 div 内容尊重 float