为什么这种CSS margin-top风格不起作用?

时间:2012-03-01 16:17:34

标签: html margin css

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

我的期望:
What I expected with margin:50px 50px 50px 50px;

我得到了什么:
What I get with margin:50px 50px 50px 50px;

代码:

#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没有解释为什么保证金会以这种方式行事。

13 个答案:

答案 0 :(得分:417)

您实际上看到#inner元素collapse的上边距位于#outer元素的上边缘,只保留#outer边距(尽管不是显示在你的图像中)。两个盒子的顶部边缘相互齐平,因为它们的边缘是相等的。

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

  

8.3.1折叠边距

     

在CSS中,两个或多个框(可能是也可能不是兄弟)的相邻边距可以组合形成单个边距。以这种方式组合的边距称为折叠,结果合并边距称为折叠边距

     

相邻的垂直边距会崩溃 [...]

  

当且仅当:

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

执行以下任何操作的原因可以防止边距崩溃:

是因为:

  
      
  • 浮动框和任何其他框之间的边距不会崩溃(甚至在浮动及其流入子项之间也不会崩溃)。
  •   
  • 建立新的块格式化上下文的元素的边距(例如浮点数和'溢出'而不是'可见'的元素)不会因其流入的子节点而崩溃。
  •   
  • 内嵌块框的边距不会崩溃(即使是流入的子项也不会崩溃)。
  •   

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

  

水平边距永不崩溃。

答案 1 :(得分:81)

尝试在内部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;
}

答案 2 :(得分:18)

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

解决方案1 ​​

  

浮动框与任何其他框之间的边距不会崩溃(甚至在浮动及其流入子项之间也不会崩溃)。

这意味着我可以将-- drop table role; create table role ( id int not null auto_increment primary key, -- for kicks and if i screw up roleId int not null, -- i will manually provide it so i can see it parent int null, unique index (roleId) ); insert role(roleId,parent) values (1,null),(2,null),(3,2),(4,3),(5,3),(6,3),(7,4),(8,3),(9,6),(10,6),(11,10); -- if i want to delete roleId A then i need to delete anything with a parent=A (B) and all of B's lineage too -- drop procedure deleteParentDownwards; delimiter $$ create procedure deleteParentDownwards ( deleteMe int ) BEGIN -- deleteMe parameter means i am anywhere in hierarchy of role -- and i want me and all my offspring deleted (no orphaning of children or theirs) declare bDoneYet boolean default false; declare working_on int; declare theCount int; CREATE TABLE xxDeleteRoleHierarchyxx ( roleId int not null, processed int not null ); set bDoneYet=false; insert into xxDeleteRoleHierarchyxx (roleId,processed) select deleteMe,0; while (!bDoneYet) do select count(*) into theCount from xxDeleteRoleHierarchyxx where processed=0; if (theCount=0) then -- found em all set bDoneYet=true; else -- one not processed yet, insert its children for processing SELECT roleId INTO working_on FROM xxDeleteRoleHierarchyxx where processed=0 limit 1; insert into xxDeleteRoleHierarchyxx (roleId,processed) select roleId,0 from role where parent=working_on; -- mark the one we "processed for children" as processed update xxDeleteRoleHierarchyxx set processed=1 where roleId=working_on; end if; end while; delete from role where roleId in (select roleId from xxDeleteRoleHierarchyxx); drop table xxDeleteRoleHierarchyxx; END $$ call deleteParentDownwards(3); -- deletes many call deleteParentDownwards(6); -- deletes 4 (assuming line above was not called first!) 添加到float:left#outer demo1

另请注意,#inner会使保证金中的float无效。

解决方案2

  

建立新的块格式化上下文的元素的边距(例如浮点数和'溢出'而不是'可见'的元素)不会因其流入的子节点而崩溃。

除了auto之外,我们将visible放入overflow: hidden。这种方式看起来非常简单和体面。我喜欢它。

#outer

解决方案3

  

绝对定位框的边距不会崩溃(甚至不包括流入的子项)。

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

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

的正常流程

解决方案4

  

内联块方框的边距不会崩溃(即使是流入的子节点也不会崩溃)。

与@enderskill相同

解决方案5

  

流入块级元素的下边距总是与其下一个流内块级兄弟的上边缘坍塌,除非兄弟姐妹有间隙。

这与问题没什么关系,因为它是兄弟姐妹之间的崩溃边缘。它通常意味着顶部框有div而兄弟框有margin-bottom: 30px。它们之间的总差距为margin-top: 10px,而不是30px

解决方案6

  

如果元素没有顶部边框,没有顶部填充,并且孩子没有间隙,则流入块元素的上边距会与其第一个流入块级子元素的上边距折叠。

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

40px

此外,#outer{ width: 500px; height: 200px; background: #FFCCCC; margin: 50px auto; border-top: 1px solid red; } #inner { background: #FFCC33; height: 50px; margin: 50px; } 默认为块级别,因此您无需故意声明它。很抱歉,由于我的新手声誉,无法发布超过2个链接和图片。至少你知道下次看到类似问题时问题出在哪里。

答案 3 :(得分:12)

不确定为什么你的东西不起作用,但你可以添加

overflow: auto;

到外部div。

答案 4 :(得分:10)

如果您向#outer添加任何填充,则可以正常工作。

Demo

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

答案 5 :(得分:9)

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

display:inline-block;

似乎有用;

答案 6 :(得分:2)

不回答“为什么”(必须是具有崩溃余量的东西),但似乎最简单/最合理的方式来做你想要做的只是添加{{ 1}}到外部div

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

次要注意 - 除非您的代码中有其他内容告诉它不被阻止,否则不必将div设置为padding-top

答案 7 :(得分:2)

试试这个:

#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/

祝你好运

答案 8 :(得分:1)

我认为将 #inner div的位置属性设置为 relative 也可能有助于达到此效果。但无论如何,我尝试了在IE9和最新谷歌Chrome上的问题中粘贴的原始代码,他们已经给出了理想的效果而没有任何修改。

答案 9 :(得分:1)

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

答案 10 :(得分:0)

你有没有尝试过!重要的是它会迫使一切:

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

答案 11 :(得分:0)

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

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

由于inner1px div之间的outer的填充,inner div的利润不会崩溃。因此,从逻辑上讲,您将有1px多余的空间以及inner div的现有边距。

答案 12 :(得分:0)

创建新的块格式上下文

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

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

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