提问人:Robert Koritnik 提问时间:11/19/2009 最后编辑:Robert Koritnik 更新时间:1/23/2023 访问量:232896
子元素上的边距移动父元素
Margin on child element moves parent element
问:
我有一个(父级)包含另一个(子级)。Parent 是第一个没有特定 CSS 样式的元素。当我设置div
div
body
.child
{
margin-top: 10px;
}
最终结果是,我的孩子的顶部仍然与父母保持一致。我的父母没有向下移动 10px,而是向下移动 10px。
My 设置为 。DOCTYPE
XHTML Transitional
我在这里错过了什么?
编辑 1
我的父母需要严格定义的尺寸,因为它的背景必须从上到下显示(像素完美)。因此,在其上设置垂直边距是不行的。
编辑 2
此行为在 FF、IE 和 CR 上是相同的。
答:
这是正常行为(至少在浏览器实现中)。边距不会影响子项相对于其父项的位置,除非父项有填充,在这种情况下,大多数浏览器会将子项的边距添加到父项的填充中。
要获得所需的行为,您需要:
.child {
margin-top: 0;
}
.parent {
padding-top: 10px;
}
评论
.parent {border: solid 1px;}
其中包含的元素正在坍塌。margin
.child
<html>
<style type="text/css" media="screen">
#parent {background:#dadada;}
#child {background:red; margin-top:17px;}
</style>
<body>
<div id="parent">
<p>&</p>
<div id="child">
<p>&</p>
</div>
</div>
</body>
</html>
在此示例中,正在接收来自浏览器的默认样式。浏览器默认值通常为 16px。通过超过 16px 的设置,您开始注意到它的位置移动。p
margin
font-size
margin-top
#child
在 DIV 中具有边距的子元素中找到替代项 您还可以添加:
.parent { overflow: auto; }
艺术
.parent { overflow: hidden; }
这样可以防止边距塌陷。边框和填充也是如此。 因此,您还可以使用以下方法来防止顶部边距崩溃:
.parent {
padding-top: 1px;
margin-top: -1px;
}
2021 年更新:如果您愿意放弃对 IE11 的支持,您还可以使用新的 CSS 结构。有关块格式化上下文的全部详细信息,请参阅 MDN Web Docs。display: flow-root
根据大众要求更新:折叠边距的全部意义在于处理文本内容。例如:
h1, h2, p, ul {
margin-top: 1em;
margin-bottom: 1em;
outline: 1px dashed blue;
}
div { outline: 1px solid red; }
<h1>Title!</h1>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
</div>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
<ul>
<li>list item</li>
</ul>
</div>
由于浏览器折叠了边距,因此文本将按预期显示,并且包装器标记不会影响边距。每个元素确保其周围有间距,但间距不会加倍。和的边距不会相加,而是相互滑动(它们折叠)。and 元素也会发生同样的情况。<div>
<h2>
<p>
<p>
<ul>
可悲的是,在现代设计中,当你明确想要一个容器时,这个想法可能会让你咬人。这在 CSS 中称为新的块格式上下文。或保证金技巧会给你这个。overflow
评论
<h2>
<p>
<ul>
margin: 5px 10px;
margin: 5px 5px;
display: flow-root
我也有这个问题,但更愿意防止负利润率黑客攻击,所以我放了一个
<div class="supercontainer"></div>
在它周围,所有这些都有填充而不是边距。当然,这意味着更多的divitis,但这可能是正确完成这项工作的最干净的方法。
父元素不能为空,至少要放在子元素之前。
评论
有趣的是,我最喜欢的这个问题的解决方案还没有在这里提到:使用浮点数。
html格式:
<div class="parent">
<div class="child"></div>
</div>
css:
.parent{width:100px; height:100px;}
.child{float:left; margin-top:20px; width:50px; height:50px;}
在这里看到它: http://codepen.io/anon/pen/Iphol
请注意,如果您需要在父级上动态高度,它也必须浮动,因此只需替换为height:100px;
float:left;
这就是对我有用的东西
.parent {
padding-top: 1px;
margin-top: -1px;
}
.child {
margin-top:260px;
}
如果适用,使用 instead 是另一种可能的解决方案。top
margin-top
在我知道正确答案之前,我找到的另一种解决方案是向父元素添加透明边框。
不过,您的盒子将使用额外的像素......
.parent {
border:1px solid transparent;
}
为子元素添加样式display:inline-block
尽管所有答案都解决了问题,但它们需要权衡/调整/妥协,例如
floats
,你必须浮动元素border-top
,这会将父元素向下推至少 1px,然后应通过向父元素本身引入边距进行调整。当父级已经具有相对单位时,这可能会产生问题。-1px
margin-top
padding-top
,效果与使用border-top
overflow: hidden
,当父级应显示溢出的内容(如下拉菜单)时不能使用overflow: auto
,为具有(有意)溢出内容(如阴影或工具提示的三角形)的父元素引入滚动条
该问题可以通过使用 CSS3 伪元素来解决,如下所示
.parent::before {
clear: both;
content: "";
display: table;
margin-top: -1px;
height: 0;
}
https://jsfiddle.net/hLgbyax5/1/
评论
margin-top: -1px
似乎没有必要。但我喜欢这个。
margin-top: -1px
height: 0
.parent:after...
我发现, 在 .css > 中,如果将 div 元素的 display 属性设置为 inline-block,则可以解决问题。保证金将按预期工作。
简洁的纯 CSS 解决方案
使用以下代码将无内容的第一个子项预置到无意中移动的 div 之前:
.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
这种方法的优点是不需要更改任何现有元素的 CSS,因此对设计的影响最小。在此旁边,添加的元素是一个伪元素,它不在 DOM 树中。
对伪元素的支持很普遍:Firefox 3+、Safari 3+、Chrome 3+、Opera 10+ 和 IE 8+。这适用于任何现代浏览器(请注意较新的浏览器,IE8 不支持)。::before
上下文
如果元素的第一个子元素具有 ,则父元素将调整其位置,以折叠冗余边距。为什么?就是这样。margin-top
鉴于以下问题:
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
</style>
<div class="parent"><!--This div moves 40px too-->
<div class="child">Hello world!</div>
</div>
您可以通过添加包含内容(例如简单空格)的子项来解决此问题。但我们都讨厌为仅设计问题添加空间。因此,请使用该属性来伪造内容。white-space
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.fix {position: relative;white-space: pre;height: 0px;width: 0px;overflow: hidden;}
</style>
<div class="parent"><!--This div won't move anymore-->
<div class="fix"></div>
<div class="child">Hello world!</div>
</div>
确保固定装置的正确定位。并且使您不必在修复中添加任何内容(例如空白)。并确保您永远不会看到修复程序。position: relative;
white-space: pre;
height: 0px;width: 0px;overflow: hidden;
您可能需要添加或确保在古代 IE 浏览器中高度实际上为零(我不确定)。或者,如果它不起作用,您可以在旧的 IE 浏览器中添加它。line-height: 0px;
max-height: 0px;
<!--dummy-->
简而言之,您只需使用 CSS 即可完成所有这些操作(无需向 HTML DOM 树添加实际的子项):
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
</style>
<div class="parent"><!--This div won't move anymore-->
<div class="child">Hello world!</div>
</div>
评论
overflow: hidden;
要防止“Div parent”使用“div child”的边距: 在 parent 中使用以下 css:
- 浮
- 填充
- 边境
- 溢出
播放父项的显示
.parent{
display: inline-block;
width: 100%;
}
或
.parent{ display: flex; }
您可以通过向父元素添加伪元素来解决此问题。:before
display: flex;
.parent:before {
content: '';
display: flex;
}
另一种方法是将父级的属性设置为 。display
flow-root
.parent {
display: flow-root;
}
边框解决方案很好,但不是最好的,因为即使在透明的情况下,它也会增加元素的总宽度
但是负边框宽度呢?不工作:(
但我们仍然可以实现它,迫使边界走向负面方向box-sizing property
.parent{
border:5px solid transparent;
box-sizing: border-box;
}
.child{
margin-top:5px;
}
请注意,如果您想要,则必须添加,因为顶部仍然影响,这是防止崩溃问题的原因。10px top margin
5px margin
5px border
这是关于保证金崩溃的。
块的上边距和下边距有时会合并(折叠)成一个边距,其大小是单个边距中最大的一个边距(如果它们相等,则仅是其中一个边距),这种行为称为边距折叠。
根据具体情况,有几种解决方案。 一种解决方案是更改孩子的显示模式。
.child {
display: inline-block;
}
也很高兴知道。边距折叠不适用于 flex 或 gird 容器。
.parent {
display: flex;
flex-direction: column;
}
或者与父母而不是孩子一起工作。更改或属性也可能有所帮助。或者绝对。这取决于您的布局。padding
margin
overflow
float
position
评论