子元素上的边距移动父元素

发布于 2024-08-11 11:25:14 字数 536 浏览 3 评论 0原文

我有一个 divparent),其中包含另一个 divchild)。 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

离不开的别离 2024-08-18 11:25:14

DIV 内具有边距的子元素找到了替代方案,您还可以添加:

.parent { overflow: auto; }

或:

.parent { overflow: hidden; }

这可以防止边距折叠。边框和内边距的作用相同。
因此,您还可以使用以下方法来防止顶部边距塌陷:

.parent {
    padding-top: 1px;
    margin-top: -1px;
}

2021 更新:如果您愿意 放弃 IE11支持,您还可以使用新的CSS构造display: flow-root。有关块格式的完整详细信息,请参阅 MDN Web 文档上下文。


根据大众要求更新:
折叠边距的全部目的是处理文本内容。例如:

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>

由于浏览器会折叠边距,因此文本将按您的预期显示,并且

包装标记不会影响边距。每个元素确保其周围有间距,但间距不会加倍。

的边距不会相加,而是会滑入彼此(它们会折叠)。

    元素也会发生同样的情况。

遗憾的是,在现代设计中,当您明确想要一个容器时,这个想法可能会困扰您。用 CSS 来说,这称为新的块格式化上下文overflow 或 margin 技巧将为您提供这一点。

Found an alternative at Child elements with margins within DIVs You can also add:

.parent { overflow: auto; }

or:

.parent { overflow: hidden; }

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:

.parent {
    padding-top: 1px;
    margin-top: -1px;
}

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:

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>

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.

怀里藏娇 2024-08-18 11:25:14

这是正常行为(至少在浏览器实现中)。边距不会影响子级相对于其父级的位置,除非父级具有填充,在这种情况下,大多数浏览器会将子级的边距添加到父级的填充中。

为了获得您想要的行为,您需要:

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}

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:

.child {
    margin-top: 0;
}

.parent {
    padding-top: 10px;
}
没企图 2024-08-18 11:25:14

尽管所有答案都解决了问题,但它们都伴随着权衡/调整/妥协,例如

  • 浮动,您必须浮动元素
  • 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/

Although all of the answers fix the issue but they come with trade-offs/adjustments/compromises like

  • floats, You have to float elements
  • border-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 has margin-top in relative units.
  • padding-top, same effect as using border-top
  • overflow: hidden, Can't be used when parent should display overflowing content, like a drop down menu
  • overflow: 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

.parent::before {
  clear: both;
  content: "";
  display: table;
  margin-top: -1px;
  height: 0;
}

https://jsfiddle.net/hLgbyax5/1/

铃予 2024-08-18 11:25:14

给子元素添加样式 display:inline-block

add style display:inline-block to child element

南渊 2024-08-18 11:25:14

父元素不能为空,至少要在子元素之前放置  

the parent element has not to be empty at least put   before the child element.

我家小可爱 2024-08-18 11:25:14

这对我有用

.parent {
padding-top: 1px;
margin-top: -1px;
}

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

This is what worked for me

.parent {
padding-top: 1px;
margin-top: -1px;
}

.child {
margin-top:260px;
}

http://jsfiddle.net/97fzwuxh/

一袭白衣梦中忆 2024-08-18 11:25:14

为了防止“Div Parent”使用“div Child”的边距:

在父级中使用这些CSS:

  • Float
  • Padding
  • Border
  • Overflow

To prevent "Div parent" use margin of "div child":

In parent use these css:

  • Float
  • Padding
  • Border
  • Overflow
身边 2024-08-18 11:25:14

简洁的纯 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+。这适用于任何现代浏览器(请注意较新的 ::before,IE8 不支持它)。

上下文

如果元素的第一个子元素具有 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: hide; 确保您永远不会看到修复。

您可能需要添加 line-height: 0px;max-height: 0px; 以确保在古老的 IE 浏览器中高度实际上为零(我不确定)。如果它不起作用,您可以选择在旧版 IE 浏览器中添加

简而言之,您只需使用 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>

Neat CSS-only solution

Use the following code to prepend a contentless first-child to the unintentionally moving div:

.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}

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:

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

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.

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

Where position: relative; ensures correct positioning of the fix. And white-space: pre; makes you not having to add any content - like a white space - to the fix. And height: 0px;width: 0px;overflow: hidden; makes sure you'll never see the fix.

You might need to add line-height: 0px; or max-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):

<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>
潜移默化 2024-08-18 11:25:14

这是关于边距折叠

块的顶部底部边距有时会合并(折叠)为单个边距,其大小是各个边距中最大的(或只是其中之一,如果它们相等),这种行为称为边距崩溃

有多种解决方案,具体取决于具体情况。
一种解决方案是更改子级的显示模式。

.child {
  display: inline-block;
}

也很高兴知道。边距折叠不适用于 Flex 或 Grid 容器。

.parent {
  display: flex;
  flex-direction: column;
}

或者使用父级的 padding 而不是子级的 margin 。更改 overflowfloat 属性也可能有所帮助。或绝对位置。这取决于你的布局。

It's about Margin Collapsing.

The top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the individual margins (or just one of them, if they are equal), a behavior known as margin collapsing.

There are several solutions, depending on the individual case.
One solution is to change the display mode for the child.

.child {
  display: inline-block;
}

Also good to know. Margin collapsing is not applied on flex or gird container.

.parent {
  display: flex;
  flex-direction: column;
}

Or working with padding of parent instead of margin of childs. Changing overflow or float property could also help. Or position absolute. It depends on your layout.

错爱 2024-08-18 11:25:14

我发现,
在 .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.

很糊涂小朋友 2024-08-18 11:25:14

玩父母的展示

.parent{
     display: inline-block;
     width: 100%;
}

.parent{ display: flex; }

Play with display of parent

.parent{
     display: inline-block;
     width: 100%;
}

or

.parent{ display: flex; }
仲春光 2024-08-18 11:25:14

我也遇到了这个问题,但更喜欢防止负边距黑客攻击,所以我在它周围放置了一个

它有填充而不是边距。当然,这意味着更多的麻烦,但这可能是正确完成此操作的最干净的方法。

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.

怕倦 2024-08-18 11:25:14

有趣的是,我最喜欢的解决这个问题的方法还没有在这里提到:使用浮动。

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;

interestingly my favorite solution to this problem isn't yet mentioned here: using floats.

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

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; by float:left;

Spring初心 2024-08-18 11:25:14

如果合适的话,使用 top 代替 margin-top 是另一种可能的解决方案。

Using top instead of margin-top is another possible solution, if appropriate.

绿萝 2024-08-18 11:25:14

在我知道正确答案之前,我发现的另一个解决方案是向父元素添加透明边框

不过你的盒子会使用额外的像素......

.parent {
    border:1px solid transparent;
}

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...

.parent {
    border:1px solid transparent;
}
情域 2024-08-18 11:25:14

您可以通过向父元素添加带有 display: flex;:before 伪元素来解决此问题。

.parent:before {
  content: '';
  display: flex;
}

另一种方法是将父级的 display 属性设置为 flow-root

.parent {
  display: flow-root;
}

You can solve this by adding a :before pseudo element with display: flex; to the parent.

.parent:before {
  content: '';
  display: flex;
}

Another way is to set the display property of the parent to flow-root.

.parent {
  display: flow-root;
}
歌枕肩 2024-08-18 11:25:14

.child 中包含的元素的 margin 正在折叠。

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

在此示例中,p 从浏览器默认样式接收margin。浏览器默认font-size通常为16px。通过在 #child 上设置超过 16 像素的 margin-top,您开始注意到它的位置移动。

The margin of the elements contained within .child are collapsing.

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

In this example, p is receiving a margin from the browser default styles. Browser default font-size is typically 16px. By having a margin-top of more than 16px on #child you start to notice it's position move.

请远离我 2024-08-18 11:25:14

边框解决方案很好,但不是最好的,因为即使是透明的,它也会增加元素的总宽度,

但是负边框宽度呢?不起作用:(

但我们仍然可以通过 box-sizing 属性 来实现它
这迫使边框向负方向

.parent{
   border:5px solid transparent;
   box-sizing: border-box;
 }
.child{
   margin-top:5px; 
 }

注意,如果你想要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

.parent{
   border:5px solid transparent;
   box-sizing: border-box;
 }
.child{
   margin-top:5px; 
 }

Notice if you want 10px top margin you have to add only 5px margin because 5px border top still affecting and this reason to prevent collapsing issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文