父级和子级尺寸计算
有人可以帮我理解为什么#child 与#parent 的大小不同吗?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
</head>
<body>
<div id='parent' style='border: 1px solid black'>
<div id='child' style='background-color: #888888'>
<p>Here is some content</p>
<div id='grandchild' style='margin-bottom: 1em'>
<p>A little more content</p>
</div>
</div>
</div>
</body>
</html>
Can someone help me understand why #child is not the same size as #parent?
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
</head>
<body>
<div id='parent' style='border: 1px solid black'>
<div id='child' style='background-color: #888888'>
<p>Here is some content</p>
<div id='grandchild' style='margin-bottom: 1em'>
<p>A little more content</p>
</div>
</div>
</div>
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正在发生的事情是这样的:
保证金崩溃。 Jeroen 的回答向我指出了折叠边距的 W3C 盒子模型规范 ,这让我很头疼,并且没有完全回答边界问题(这是奥德首先指出的)。然后我找到了 这篇文章 并将解决方案拼凑在一起(我说的是顶部边距,但这个完全相同的解决方案适用于底部边距)。
当两个[块级]元素的垂直边距接触时,使用较大的边距,并丢弃较小的边距。
代码中的所有内容都被视为块级元素,包括
和
标记。
在其父
元素内的默认
margin-top
为 8px。第一个
标记的默认
margin-top
为 16 像素。边距折叠不限于同级标签,因此
标签开始检查其父标签的位置和边距。
#child
元素的margin-top
为 0。上边距接触
# child
上边距,因此它们折叠为单个 16px 边距 (16 > 0)。标记的 16 像素边距“推过”并充当
#child
标记的边距。中的 16px 边距仍在检查其正上方的边距。接下来是
#parent
标签,它的margin-top也为0。但是,
#parent上的1px边框
阻止继续前进。
不会再遇到上面的任何边距,因为它触及 1px 边框。因此折叠停止在
#parent
的顶部边框内。渲染 16 像素的上边距,下面是 0 像素边距折叠的
#child
标签。这就是为什么
#parent
框比#child
框高 32 像素:边距“崩溃”,直到碰到某些东西那不是边距(1px 边框)。那么,如果
#parent
上的 1px 边框没有阻止折叠,会发生什么呢?按照上面的步骤 1-7 进行操作。
的上边距进入
#parent
元素的 0px 上边距。同样,是较大的边距(16 vs 0),因此折叠继续向上。
的上边距命中
标记。
的默认上边距为 8 像素。
标签更大,因此现在
标签“继承”了 16px 上边距,而 8px 被丢弃。
上边距到达
标记。由于
是根元素,因此折叠在此停止。
标记以 16 像素的上边距呈现,
#parent
、#child
和则以 16 像素的上边距呈现。
元素全部渲染在下面;紧贴在
#parent
框中,因为边距穿过它。我花了这么长时间才弄清楚的原因与我直到今天才听说折叠边距的原因相同:Firebug 没有清楚地描述折叠边距。在 Firebug 中,
标记仍然显示它保留 16 像素的上边距。这是真实的。但是,没有迹象表明发生了任何折叠 -
标记仍然报告 8px 顶部边框,即使它已被丢弃。
我很高兴现在知道了这一点;它澄清了我对页面布局的许多困惑。
编辑:
我引用的文章确实值得一读。它不仅为我提供了答案所需的信息,还详细说明了在 IE7 中,
标记如何不参与边框折叠。这解释了很多。
Here's what's going on:
Margin Collapsing. Jeroen's answer pointed me to the W3C box model specs for collapsing margins, which gave me a headache, and didn't quite answer the question of the border (which Oded first pointed out). Then I found this article and pieced the solution together (I'm talking about just the top margins, but this exact same solution applies to the bottom margins).
When two [block-level] elements' vertical margins are touching, the larger margin is used and the smaller margin is discarded.
Everything in your code is considered a block-level element, including the
<html>
and<body>
tags.The
<body>
has a defaultmargin-top
of 8px inside its parent<html>
element.The first
<p>
tag has a defaultmargin-top
of 16px.Margin collapsing isn't confined to siblings, so the
<p>
tag starts to check against its parent tag's position and margins.The
#child
element has amargin-top
of 0. The<p>
top margin is touching the#child
top margin, so they collapse to a single 16px margin (16 > 0). The<p>
tag's 16px margin "pushes through" and acts as a margin for the#child
tag.The 16px margin from
<p>
is still checking for margins directly above it. Next up would be the#parent
tag, which also has a margin-top of 0.BUT, The 1px border on
#parent
prevents<p>
from going any further.<p>
isn't going to run into any more margins above it, because it's touching the 1px border. So the collapsing stops inside the top border of#parent
.The 16px top-margin is rendered, and underneath is the
#child
tag whose 0px margin was collapsed.That's why the
#parent
box is 32px taller than the#child
box: The<p>
margins "crashed through" until they hit something that wasn't a margin (the 1px border). So, what happens if the 1px border on#parent
hadn't been there to stop the collapsing?Follow steps 1-7 above.
<p>
's top margin runs into the#parent
element's 0px top margin. Again,<p>
is the bigger margin (16 vs 0), so the collapsing continues upward.<p>
's top margin hits the<body>
tag. The<body>
has a default top margin of 8px. The<p>
tag is bigger, so now the<body>
tag has "inherited" the 16px top margin, and the 8px is discarded.The
<p>
top margin reaches the<html>
tag. Since<html>
is the root element, the collapsing stops here. The<body>
tag renders with a 16px top margin, and the#parent
,#child
, and<p>
elements all render beneath;<p>
is snug inside the#parent
box because the margin crashed through it.The reason why this took me so long to figure out is the same reason I hadn't heard of collapsing margins until today: Firebug doesn't clearly depict collapsing margins. In Firebug, the
<p>
tag still shows that it's holding the 16px top margin. This is true. However, there's no indication that any collapsing has taken place--the<body>
tag still reports an 8px top border, even though it's been discarded.I'm glad I know this now; it clarifies much confusion I've had about page layouts.
Edit:
The article I referenced is really worth the read. Not only did it give me the info I needed for the answer, it also details how in IE7, the
<body>
tag doesn't participate in border collapsing. That explains a lot.由于
p
上的标准边距和#grandchild
上的bottom-margin
。它们以body
的标准边距折叠。您可以重置
body
、p
等的边距,并使用 paddings 而不是 margins 来避免这种情况;填充物不会塌陷。Because of the standard margins on the
p
and thebottom-margin
on#grandchild
. They collapse with the standard margin of thebody
.You can reset the margins on
body
,p
, etc. and use paddings instead of margins to avoid that; paddings don´t collapse.因为你的父 div 周围有 1px 的边框,而子 div 没有。
这会为父 div 的宽度和高度添加 2 个像素。
Because your parent div has a border of 1px around itself, and the child doesn't.
This adds 2 pixels to the width and height of the parent div.