我尝试在另一个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没有解释为什么保证金会以这种方式行事。
答案 0 :(得分:417)
您实际上看到#inner
元素collapse的上边距位于#outer
元素的上边缘,只保留#outer
边距(尽管不是显示在你的图像中)。两个盒子的顶部边缘相互齐平,因为它们的边缘是相等的。
以下是W3C规范的相关要点:
8.3.1折叠边距
在CSS中,两个或多个框(可能是也可能不是兄弟)的相邻边距可以组合形成单个边距。以这种方式组合的边距称为折叠,结果合并边距称为折叠边距。
相邻的垂直边距会崩溃 [...]
当且仅当:
时,两个边距相邻
- 都属于参与相同块格式化上下文的流内块级框
- 没有行框,没有间隙,没有填充,没有边框将它们分开
- 都属于垂直相邻的盒子边缘,即形成以下对中的一个:
- 盒子的上边距及其第一个流入的孩子的上边距
执行以下任何操作的原因可以防止边距崩溃:
div
个元素div
元素之一inline blocks overflow
of #outer
to auto
(或visible
以外的任何值)是因为:
- 浮动框和任何其他框之间的边距不会崩溃(甚至在浮动及其流入子项之间也不会崩溃)。
- 建立新的块格式化上下文的元素的边距(例如浮点数和'溢出'而不是'可见'的元素)不会因其流入的子节点而崩溃。
- 内嵌块框的边距不会崩溃(即使是流入的子项也不会崩溃)。
左右边距的行为符合您的预期,因为:
水平边距永不崩溃。
答案 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
添加任何填充,则可以正常工作。
#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 :
次要注意 - 除非您的代码中有其他内容告诉它不被阻止,否则不必将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;
}
祝你好运
答案 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>
由于inner
和1px
div之间的outer
的填充,inner
div的利润不会崩溃。因此,从逻辑上讲,您将有1px
多余的空间以及inner
div的现有边距。
答案 12 :(得分:0)
您可以在父元素上使用 display: flow-root
以防止在包含元素创建新的块格式上下文时边距折叠。
将 overflow 属性的值更改为 auto 或使用 flexbox 将具有相同的效果。