ChatGPT解决这个技术问题 Extra ChatGPT

为什么这种 CSS margin-top 样式不起作用?

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

https://i.stack.imgur.com/WFkp8.jpg

https://i.stack.imgur.com/I3xJz.jpg

代码:

#outer { 宽度:500px;高度:200px;背景:#FFCCCC;边距:50px 自动 0 自动;显示:块; } #inner { 背景:#FFCC33;边距:50px 50px 50px 50px;填充:10px;显示:块; }

你好,世界!

W3Schools 没有解释为什么 margin 会这样。

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

M
MegaMatt

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

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

8.3.1 折叠边距 在 CSS 中,两个或多个框(可能是或不是兄弟)的相邻边距可以组合成一个边距。以这种方式组合的边距称为折叠边距,由此产生的组合边距称为折叠边距。相邻的垂直边距折叠 [...]

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

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

浮动任何一个 div 元素 使任何一个 div 元素内联块 将#outer 的溢出设置为自动(或除可见之外的任何值)

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

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

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

水平边距永远不会塌陷。


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

尝试在内部 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 放置和其他规则应用后重新评估 div 的大小。
为我的问题尝试过,做了一个楼梯效果。
这是魔法!!!!! 2012年的答案救了我!!
Q
Qiang

@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;

}

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


y
yousoumar

不知道为什么您所拥有的不起作用,但您可以将 overflow: auto; 添加到外部 div


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

不完全确定为什么,但将内部 CSS 更改为

display: inline-block;

似乎工作。


y
yousoumar

如果您将任何 padding 添加到 #outer,它就会起作用。演示在这里:

#outer { 宽度:500px;高度:200px;背景:#FFCCC;边距:50px 自动 0 自动;显示:块;填充顶部:1px; } #inner { 背景:#FFCC33;边距:50px 50px 50px 50px;填充:10px;显示:块; }

你好,世界!


y
yousoumar

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

#outer { 宽度:500px;高度:200px;背景:#FFCCC;边距:50px 自动 0 自动;填充顶部:50px; } #inner { 背景:#FFCC33;边距:0px 50px 50px 50px;填充:10px; }

你好,世界!

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


A
Artemee Senin

创建新的块格式化上下文

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

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

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


y
yousoumar

尝试这个:

#outer { 宽度:500px;高度:200px;背景:#FFCCC;边距:50px 自动 0 自动;显示:表格; } #inner { 背景:#FFCC33;边距:50px 50px 50px 50px;填充:10px;显示:块; }

你好,世界!

祝你好运!


v
viditkothari

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


B
BoltClock

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;}

B
BoltClock

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

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

J
Jackie Santana

如果您遇到边距折叠问题,那么要解决此问题,您可以将 display: flow-root; 添加到父容器。

除此之外,如果 margin-top 被忽略,请尝试使用负值 margin-top,例如:margin-top: -2px;


M
Mithilesh Tipkari

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

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

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