【问题标题】:Why does this CSS margin-top style not work?为什么这种 CSS margin-top 样式不起作用?
【发布时间】:2012-03-20 03:53:17
【问题描述】:

我尝试在另一个 div 中的 div 上添加边距值。除了最高值外,一切正常,它似乎被忽略了。但为什么呢?

我的预期:

我得到了什么:

代码:

#outer {
    	width: 500px; 
    	height: 200px; 
    	background: #FFCCCC;
    	margin: 50px auto 0 auto;
    	display: block;
}
#inner {
    	background: #FFCC33;
    	margin: 50px 50px 50px 50px;
    	padding: 10px;
    	display: block;
}
<div id="outer">
  <div id="inner">
  	Hello world!
  </div>
</div>

W3Schools 无法解释为什么 margin 会有这种行为。

【问题讨论】:

  • 你试过浮动里面的吗?
  • hum.. 使用float:left; 它可以工作......但为什么需要这样做。我不希望它漂浮。为什么左/右边距有效?
  • 欢迎来到有趣的 CSS 边距折叠算法世界!
  • W3Schools vs. W3CDocs...我认为我们有一个赢家。 :D
  • jsFiddle ,为下一个人节省 25 秒 jsfiddle.net/kLeu9

标签: html margin css


【解决方案1】:

您实际上看到#inner 元素的上边距collapse 进入#outer 元素的上边距,只留下#outer 边距完好无损(尽管未在您的图像中显示)。两个框的上边缘彼此齐平,因为它们的边距相等。

以下是 W3C 规范中的相关要点:

8.3.1 折叠边距

在 CSS 中,两个或多个框(可能是兄弟,也可能不是兄弟)的相邻边距可以组合成一个边距。以这种方式组合的边距称为collapse,而得到的组合边距称为collapsed margin

相邻的垂直边距折叠[...]

两个边距相邻当且仅当:

  • 两者都属于参与相同块格式化上下文的流入块级框
  • 没有线框,没有间隙,没有填充,没有边框将它们分开
  • 两者都属于垂直相邻的盒子边缘,即形成以下对之一:
    • 框的上边距及其第一个流入子元素的上边距

您可以执行以下任何操作来防止边距折叠:

上述选项阻止边距折叠的原因是:

  • 浮动框和任何其他框之间的边距不会折叠(即使浮动框与其流入的子级之间也不会折叠)。
  • 建立新块格式上下文的元素(例如浮动和具有“溢出”而不是“可见”的元素)的边距不会与其流入的子级一起折叠。
  • 内联块框的边距不会折叠(即使是它们的流入子框也不折叠)。

左右边距的行为符合您的预期,因为:

水平边距永远不会塌陷。

【讨论】:

  • 这个答案很震撼!只是要补充一点。您对 w3c 的引用说明了这一点,但我现在才意识到。因此,为了让其他人清楚,您也可以给#outer 一个边框。
  • 浮动中的链接好像坏了。
  • @episanty:当您链接到评论时会发生这种情况。取消链接。
  • 我知道 - 只是想让你知道。由于您启用了 ♦,我认为您可能想要恢复评论 - 或相应地更改您的帖子。顺便说一句,谢谢你的好答案。
【解决方案2】:

尝试在内部 div 上使用display: inline-block;

#outer {
    width:500px; 
    height:200px; 
    background:#FFCCCC;
    margin:50px auto 0 auto;
    display:block;
}
#inner {
    background:#FFCC33;
    margin:50px 50px 50px 50px;
    padding:10px;
    display:inline-block;
}

【讨论】:

  • 好答案。如果它解释了为什么此更改可以解决问题会更好。
  • 好吧,这太奇怪了!为什么这行得通?为什么它不能按预期工作的合乎逻辑的解释是什么。左边距/右边距在没有display:inline-block; 的情况下有效。使用display:inline-block; 时的另一个问题是,您在 div 上失去了 100% 的宽度。
  • 将其切换为 inline-block 会强制浏览器在应用 div 的放置和其他规则后重新评估其大小。
  • 针对我的问题试了一下,做了楼梯效果。
【解决方案3】:

@BoltClock 提到的内容非常可靠。 在这里,我只想为这个问题添加更多的解决方案。 检查这个w3c_collapsing margin。绿色部分是如何解决这个问题的潜在想法。

解决方案 1

浮动框和任何其他框之间的边距不会折叠(甚至在浮动框与其流入的子级之间也不折叠)。

这意味着我可以将float:left 添加到#outer#inner demo1

还要注意float 会使边距中的auto 无效。

解决方案 2

建立新块格式化上下文的元素(例如浮动和具有“溢出”而不是“可见”的元素)的边距不会与其流入的子元素一起折叠。

除了visible,让我们将overflow: hidden 放入#outer。而且这种方式看起来非常简单和体面。我喜欢。

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    overflow: hidden;
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

解决方案 3

绝对定位框的边距不会折叠(即使是它们的流入子代)。

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: absolute; 
}
#inner{
    background: #FFCC33;
    height: 50px;
    margin: 50px;
}

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    position: relative; 
}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;
    position: absolute;
}

这两种方法会破坏div的正常流程

解决方案 4

内联块框的边距不会折叠(即使是它们的流入子代)。

与@enderskill 相同

解决方案 5

流入块级元素的下边距总是与其下一个流入块级同级元素的上边距折叠,除非该同级有间隙。

这与问题没有太大关系,因为它是兄弟姐妹之间的折叠边距。这通常意味着如果一个顶盒有margin-bottom: 30px,而一个同级框有margin-top: 10px。它们之间的总边距是30px,而不是40px

解决方案 6

如果元素没有上边框、没有上边距且子元素没有间隙,则流入块元素的上边距与其第一个流入块级子元素的上边距一起折叠。

这很有趣,我可以添加一个顶部边框线

#outer{
    width: 500px;
    height: 200px;
    background: #FFCCCC;
    margin: 50px auto;
    border-top: 1px solid red;

}
#inner {
    background: #FFCC33;
    height: 50px;
    margin: 50px;

}

而且&lt;div&gt; 默认是块级的,所以你不必故意声明它。抱歉,由于我的新手声誉,无法发布超过 2 个链接和图片。至少你下次看到类似的东西时就知道问题出在哪里了。

【讨论】:

    【解决方案4】:

    不知道为什么你有什么不起作用,但你可以添加

    overflow: auto;

    到外部 div。

    【讨论】:

    • 这个问题有很多不同的解决方案。谢谢!此答案与@BoltClock 的答案相结合,提供了有关此解决方案为何有效的良好信息。
    【解决方案5】:

    不完全确定原因,但将内部 CSS 更改为

    display: inline-block;
    

    似乎有效。

    【讨论】:

      【解决方案6】:

      如果您向#outer 添加任何填充,它会起作用。

      Demo

      #outer {
          width:500px; 
          height:200px; 
          background:#FFCCCC;
          margin:50px auto 0 auto;
          display:block;
          padding-top:1px;
      }
      

      【讨论】:

        【解决方案7】:

        不回答“为什么”(必须是带有折叠边距的东西),但似乎最简单/最合乎逻辑的方式来做你想做的事情就是添加@987654322 @到外部div

        http://jsfiddle.net/hpU5d/1/

        次要注意 - 没有必要将 div 设置为 display:block;,除非您的代码中有其他内容告诉它不要被阻止。

        【讨论】:

          【解决方案8】:

          试试这个:

          #outer {
              width:500px; 
              height:200px; 
              background:#FFCCCC;
              margin:50px auto 0 auto;
              display:table;
          }
          #inner {
              background:#FFCC33;
              margin:50px 50px 50px 50px;
              padding:10px;
              display:block;
          }​
          

          http://jsfiddle.net/7AXTf/

          祝你好运

          【讨论】:

            【解决方案9】:

            我想将 #inner div 的 position 属性设置为 relative 也可能有助于实现效果。但无论如何,我尝试了粘贴在 IE9 和最新 Google Chrome 上的问题中的原始代码,它们已经在没有任何修改的情况下提供了理想的效果。

            【讨论】:

              【解决方案10】:

              使用padding-top:50px作为外部 div。像这样的:

              #outer {
                  width:500px; 
                  height:200px; 
                  background:#FFCCCC;
                  margin:50px auto 0 auto;
                  display:table;}
              

              注意:填充会增加 div 的大小。在这种情况下,如果您的 div 的大小很重要,我的意思是它是否必须具有特定的高度。将高度降低 50px。:

              #outer {
                  width:500px; 
                  height:150px; 
                  background:#FFCCCC;
                  margin:50px auto 0 auto;
                  display:table;}
              

              【讨论】:

                【解决方案11】:

                创建新的块格式化上下文

                您可以在父元素上使用display: flow-root,以防止边距在包含元素创建新的块格式上下文时折叠。

                将overflow属性的值改为auto或者使用flexbox也会有同样的效果。

                https://codepen.io/rachelandrew/pen/VJXjEp

                【讨论】:

                  【解决方案12】:

                  你试过 !important 之前,它会强制一切:

                  margin:50px 50px 50px 50px !important;
                  

                  【讨论】:

                    【解决方案13】:

                    为了快速解决问题,尝试将您的子元素包装成这样的 div 元素 -

                    <div id="outer">
                       <div class="divadjust" style="padding-top: 1px">
                          <div id="inner">
                             Hello world!
                          </div>
                       </div>
                    </div>
                    

                    由于1pxouterinner div 之间的填充,inner div 的边距不会折叠。所以从逻辑上讲,您将拥有1px 额外空间以及inner div 的现有边距。

                    【讨论】:

                      猜你喜欢
                      • 2022-12-26
                      • 2016-09-13
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多