【问题标题】:Why does this CSS margin-top style not work?为什么这个 CSS margin-top 样式不起作用?
【发布时间】:2022-12-26 19:21:47
【问题描述】:

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

我期望的是:

我得到什么:

代码:

#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 会这样。

【问题讨论】:

  • 你试过漂浮里面的那个吗?
  • 嗯.. float:left; 它可以工作......但是为什么需要这个。我不想让它漂浮。为什么左/右边距有效?
  • 欢迎来到 CSS 边距折叠算法的有趣世界!
  • 你什么都不知道,琼恩·雪诺……
  • 我不记得什么时候 CSS 变得如此复杂。它只是为了显示元素,我看到很多人都在为它苦苦挣扎。学习它并不像你必须“研究”它。

标签: html margin css


【解决方案1】:

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

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

8.3.1 折叠边距

在 CSS 中,两个或多个框(可能是也可能不是兄弟)的相邻边距可以合并形成一个边距。据说以这种方式组合的边距坍塌,由此产生的组合保证金称为倒塌边距.

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

两个边距是毗邻当且仅当:

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

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

上述选项阻止边距崩溃的原因是:

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

左边距和右边距的行为与您预期的一样,因为:

水平边距永远不会塌陷。

【讨论】:

  • 这个答案太棒了!只是要补充一点。你对 w3c 的引用说明了这一点,但我现在才意识到。因此,为了让其他人清楚,您也可以给#outer 一个边框。
  • Floating 中的链接似乎已断开。
  • @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 的大小。
  • 针对我的问题进行了尝试,做出了楼梯效果。
  • 这是魔法!!!!! 2012 年的答案救救我!!
【解决方案3】:

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

解决方案 1

浮动框和任何其他框之间的边距不会折叠(即使是浮动框和它的流入子框之间)。

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

还要注意 float 会使保证金中的 auto 无效。

方案二

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

除了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

inline-block boxes 的边距不会折叠(即使是它们的 in-flow children)。

与@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】:

      如果将任何 padding 添加到 #outer,它就可以工作。演示在这里:

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

      【讨论】:

        【解决方案7】:

        不回答“为什么”(必须是边缘崩溃的东西),但似乎做你想做的事情的最简单/最合乎逻辑的方法就是将 padding-top 添加到外部 div:

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

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

        【讨论】:

          【解决方案8】:

          创建新的块格式化上下文

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

          将 overflow 属性的值更改为 auto 或使用 flexbox 将具有相同的效果。

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

          【讨论】:

            【解决方案9】:

            尝试这个:

            #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;
            }
            <div id="outer">
                <div id="inner">
                    Hello world!
                </div>
            </div>

            祝你好运!

            【讨论】:

              【解决方案10】:

              我想设置位置的财产#内分给相对的也可能有助于达到效果。但无论如何,我尝试了粘贴在 IE9 和最新谷歌浏览器问题中的原始代码,它们已经在没有任何修改的情况下提供了理想的效果。

              【讨论】:

                【解决方案11】:

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

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

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

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

                【讨论】:

                  【解决方案12】:

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

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

                  【讨论】:

                    【解决方案13】:

                    如果您有保证金崩溃问题,那么要解决此问题,您可以添加 display: flow-root; 到父容器。

                    除此之外,如果保证金顶部被忽略,试试保证金顶部具有负值,例如:margin-top: -2px;

                    【讨论】:

                      【解决方案14】:

                      只是为了快速修复,尝试将您的子元素包装到 div 元素中,如下所示 -

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

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

                      【讨论】:

                        猜你喜欢
                        • 2012-03-20
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-09-13
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多