子元素上的边距移动父元素
我有一个 div
(parent),其中包含另一个 div
(child)。 Parent 是 body
中的第一个元素,没有特定的 CSS 样式。当我设置时,
.child
{
margin-top: 10px;
}
最终结果是我的孩子的顶部仍然与父母对齐。我的父母不是向下移动 10 像素,而是向下移动 10 像素。
我的 DOCTYPE
设置为 XHTML Transitional
。
我在这里缺少什么?
编辑 1
我的父级需要有严格定义的尺寸,因为它有一个背景,必须从上到下显示在其下方(像素完美)。因此,在其上设置垂直边距是不行的。
编辑2
此行为在 FF、IE 和 CR 上都是相同的。
I have a div
(parent) that contains another div
(child). Parent is the first element in body
with no particular CSS style. When I set
.child
{
margin-top: 10px;
}
The end result is that top of my child is still aligned with parent. Instead of child being shifted for 10px downwards, my parent moves 10px down.
My DOCTYPE
is set to XHTML Transitional
.
What am I missing here?
edit 1
My parent needs to have strictly defined dimensions because it has a background that has to be displayed under it from top to bottom (pixel perfect). So setting vertical margins on it is a no go.
edit 2
This behaviour is the same on FF, IE as well as CR.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
在 DIV 内具有边距的子元素找到了替代方案,您还可以添加:
或:
这可以防止边距折叠。边框和内边距的作用相同。
因此,您还可以使用以下方法来防止顶部边距塌陷:
2021 更新:如果您愿意 放弃 IE11支持,您还可以使用新的CSS构造
display: flow-root
。有关块格式的完整详细信息,请参阅 MDN Web 文档上下文。根据大众要求更新:
折叠边距的全部目的是处理文本内容。例如:
由于浏览器会折叠边距,因此文本将按您的预期显示,并且
包装标记不会影响边距。每个元素确保其周围有间距,但间距不会加倍。
和
的边距不会相加,而是会滑入彼此(它们会折叠)。
和
元素也会发生同样的情况。
遗憾的是,在现代设计中,当您明确想要一个容器时,这个想法可能会困扰您。用 CSS 来说,这称为新的块格式化上下文。
overflow
或 margin 技巧将为您提供这一点。Found an alternative at Child elements with margins within DIVs You can also add:
or:
This prevents the margins to collapse. Border and padding do the same.
Hence, you can also use the following to prevent a top-margin collapse:
2021 update: if you're willing to drop IE11 support you can also use the new CSS construct
display: flow-root
. See MDN Web Docs for the whole details on block formatting contexts.Update by popular request:
The whole point of collapsing margins is handling textual content. For example:
Because the browser collapses margins, the text would appear as you'd expect, and the
<div>
wrapper tags don't influence the margins. Each element ensures it has spacing around it, but spacing won't be doubled. The margins of the<h2>
and<p>
won't add up, but slide into each other (they collapse). The same happens for the<p>
and<ul>
element.Sadly, with modern designs this idea can bite you when you explicitly want a container. This is called a new block formatting context in CSS speak. The
overflow
or margin trick will give you that.这是正常行为(至少在浏览器实现中)。边距不会影响子级相对于其父级的位置,除非父级具有填充,在这种情况下,大多数浏览器会将子级的边距添加到父级的填充中。
为了获得您想要的行为,您需要:
This is normal behaviour (among browser implementations at least). Margin does not affect the child's position in relation to its parent, unless the parent has padding, in which case most browsers will then add the child's margin to the parent's padding.
To get the behaviour you want, you need:
尽管所有答案都解决了问题,但它们都伴随着权衡/调整/妥协,例如
浮动
,您必须浮动元素border-top
,这会将父元素向下推至少 1px,然后应通过向父元素本身引入-1px
边距来进行调整。当父级已经具有相对单位的margin-top
时,这可能会产生问题。padding-top
,与使用border-top
效果相同overflow:hidden
,当父级应显示溢出内容时不能使用,例如下拉菜单overflow: auto
,为具有(故意)溢出内容(如阴影或工具提示的三角形)的父元素引入滚动条该问题可以通过使用 CSS3 伪元素来解决,如下所示
https://jsfiddle.net/hLgbyax5/1/
Although all of the answers fix the issue but they come with trade-offs/adjustments/compromises like
floats
, You have to float elementsborder-top
, This pushes the parent at least 1px downwards which should then be adjusted with introducing-1px
margin to the parent element itself. This can create problems when parent already hasmargin-top
in relative units.padding-top
, same effect as usingborder-top
overflow: hidden
, Can't be used when parent should display overflowing content, like a drop down menuoverflow: auto
, Introduces scrollbars for parent element that has (intentionally) overflowing content (like shadows or tool tip's triangle)The issue can be resolved by using CSS3 pseudo elements as follows
https://jsfiddle.net/hLgbyax5/1/
给子元素添加样式
display:inline-block
add style
display:inline-block
to child element父元素不能为空,至少要在子元素之前放置
。
the parent element has not to be empty at least put
before the child element.
这对我有用
http://jsfiddle.net/97fzwuxh/
This is what worked for me
http://jsfiddle.net/97fzwuxh/
为了防止“Div Parent”使用“div Child”的边距:
在父级中使用这些CSS:
To prevent "Div parent" use margin of "div child":
In parent use these css:
简洁的纯 CSS 解决方案
使用以下代码将无内容的第一个子元素添加到无意移动的 div 之前:
此方法的优点是您不需要更改任何现有元素的 CSS,因此对设计的影响最小。接下来,添加的元素是伪元素,它不在 DOM 树中。
对伪元素的支持很广泛:Firefox 3+、Safari 3+、Chrome 3+、Opera 10+ 和 IE 8+。这适用于任何现代浏览器(请注意较新的
::before
,IE8 不支持它)。上下文
如果元素的第一个子元素具有
margin-top
,则父元素将调整其位置,作为折叠冗余边距的一种方式。为什么?就是这样。考虑到以下问题:
您可以通过添加一个包含内容的子项来修复它,例如一个简单的空间。但我们都讨厌为纯设计问题添加空间。因此,请使用
white-space
属性来伪造内容。其中
position:relative;
确保修复的正确定位。而且white-space: pre;
使您无需在修复中添加任何内容(例如空格)。height: 0px;width: 0px;overflow: hide;
确保您永远不会看到修复。您可能需要添加
line-height: 0px;
或max-height: 0px;
以确保在古老的 IE 浏览器中高度实际上为零(我不确定)。如果它不起作用,您可以选择在旧版 IE 浏览器中添加。
简而言之,您只需使用 CSS 即可完成所有这些操作(这样就无需将实际的子级添加到 HTML DOM 树中):
Neat CSS-only solution
Use the following code to prepend a contentless first-child to the unintentionally moving div:
The advantage of this method is that you do not need to change the CSS of any existing element, and therefore has minimal impact on design. Next to this, the element that is added is a pseudo-element, which is not in the DOM-tree.
Support for pseudo-elements is wide-spread: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+, and IE 8+. This will work in any modern browser (be careful with the newer
::before
, which is not supported in IE8).Context
If the first child of an element has a
margin-top
, the parent will adjust its position as a way of collapsing redundant margins. Why? It's just like that.Given the following problem:
You can fix it by adding a child with content, such as a simple space. But we all hate to add spaces for what is a design-only issue. Therefore, use the
white-space
property to fake content.Where
position: relative;
ensures correct positioning of the fix. Andwhite-space: pre;
makes you not having to add any content - like a white space - to the fix. Andheight: 0px;width: 0px;overflow: hidden;
makes sure you'll never see the fix.You might need to add
line-height: 0px;
ormax-height: 0px;
to ensure the height is actually zero in ancient IE browsers (I'm unsure). And optionally you could add<!--dummy-->
to it in old IE browsers, if it does not work.In short, you can do all this with only CSS (which removes the need to add an actual child to the HTML DOM-tree):
这是关于边距折叠。
有多种解决方案,具体取决于具体情况。
一种解决方案是更改子级的显示模式。
也很高兴知道。边距折叠不适用于 Flex 或 Grid 容器。
或者使用父级的
padding
而不是子级的margin
。更改overflow
或float
属性也可能有所帮助。或绝对位置。这取决于你的布局。It's about Margin Collapsing.
There are several solutions, depending on the individual case.
One solution is to change the display mode for the child.
Also good to know. Margin collapsing is not applied on flex or gird container.
Or working with
padding
of parent instead ofmargin
of childs. Changingoverflow
orfloat
property could also help. Orposition
absolute. It depends on your layout.我发现,
在 .css 内部 >如果将 div 元素的 display 属性 设置为 inline-block ,则可以解决问题。保证金将按预期发挥作用。
I find out that,
inside of your .css >if you set the display property of a div element to inline-block it fixes the problem. and margin will work as is expected.
玩父母的展示
或
Play with display of parent
or
我也遇到了这个问题,但更喜欢防止负边距黑客攻击,所以我在它周围放置了一个
,
它有填充而不是边距。当然,这意味着更多的麻烦,但这可能是正确完成此操作的最干净的方法。
I had this problem too but preferred to prevent negative margins hacks, so I put a
<div class="supercontainer"></div>
around it all which has paddings instead of margins. Of course this means more divitis but it's probably the cleanest way to do get this done properly.
有趣的是,我最喜欢的解决这个问题的方法还没有在这里提到:使用浮动。
html:
css:
在这里查看: http://codepen.io/anon/pen/Iphol
请注意,如果您需要父级的动态高度,它也必须浮动,因此只需将
height:100px;
替换为float:left;
interestingly my favorite solution to this problem isn't yet mentioned here: using floats.
html:
css:
see it here: http://codepen.io/anon/pen/Iphol
note that in case you need dynamic height on the parent, it also has to float, so simply replace
height:100px;
byfloat:left;
如果合适的话,使用
top
代替margin-top
是另一种可能的解决方案。Using
top
instead ofmargin-top
is another possible solution, if appropriate.在我知道正确答案之前,我发现的另一个解决方案是向父元素添加透明边框。
不过你的盒子会使用额外的像素......
An alternative solution I found before I knew the correct answer was to add a transparent border to the parent element.
Your box will use extra pixels though...
您可以通过向父元素添加带有
display: flex;
的:before
伪元素来解决此问题。另一种方法是将父级的
display
属性设置为flow-root
。You can solve this by adding a
:before
pseudo element withdisplay: flex;
to the parent.Another way is to set the
display
property of the parent toflow-root
..child
中包含的元素的margin
正在折叠。在此示例中,
p
从浏览器默认样式接收margin
。浏览器默认font-size
通常为16px。通过在#child
上设置超过 16 像素的margin-top
,您开始注意到它的位置移动。The
margin
of the elements contained within.child
are collapsing.In this example,
p
is receiving amargin
from the browser default styles. Browser defaultfont-size
is typically 16px. By having amargin-top
of more than 16px on#child
you start to notice it's position move.边框解决方案很好,但不是最好的,因为即使是透明的,它也会增加元素的总宽度,
但是负边框宽度呢?不起作用:(
但我们仍然可以通过
box-sizing 属性
来实现它这迫使边框向负方向
注意,如果你想要
10px上边距
,你必须只添加5px边距
,因为5px边框
顶部仍然影响和这个原因是为了防止崩溃问题。The border solution is good but not the best because it increase the element total width even when being transparent
but what about negative border width ? not working :(
but still we can achieve it with
box-sizing property
which forcing the border to the negative direction
Notice if you want
10px top margin
you have to add only5px margin
because5px border
top still affecting and this reason to prevent collapsing issue.