CSS 忽略父级填充的绝对定位

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17115344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 23:13:19  来源:igfitidea点击:

Absolute positioning ignoring padding of parent

csspaddingcss-position

提问by d512

How do you make an absolute positioned element honor the padding of its parent? I want an inner div to stretch across the width of its parent and to be positioned at the bottom of that parent, basically a footer. But the child has to honor the padding of the parent and it's not doing that. The child is pressed right up against the edge of the parent.

如何使绝对定位元素尊重其父元素的填充?我想要一个内部 div 横跨其父级的宽度并定位在该父级的底部,基本上是一个页脚。但是孩子必须尊重父母的填充,而它并没有这样做。孩子被压在父母的边缘。

So I want this:

所以我想要这个:

enter image description here

在此处输入图片说明

but I'm getting this:

但我得到了这个:

enter image description here

在此处输入图片说明

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
      <div style="background-color: gray; position: absolute; left: 0px; right: 0px; bottom: 0px;">css sux</div>
    </div>
  </body>
</html>

I can make it happen with a margin around the inner div, but I'd prefer not to have to add that.

我可以通过内部 div 周围的边距来实现它,但我不想添加它。

回答by Kevin Christopher Henry

First, let's see whythis is happening.

首先,让我们看看为什么会发生这种情况。

The reason is that, surprisingly, when a box has position: absoluteits containing box is the parent's padding box (that is, the box around its padding). This is surprising because usually (that is, when using static or relative positioning) the containing box is the parent's contentbox.

原因是,令人惊讶的是,当一个框有position: absolute它的包含框时,它是父级的填充框(即围绕其填充的框)。这是令人惊讶的,因为通常(即,当使用静态或相对定位时)包含框是父的内容框。

Here is the relevant part of the CSS specification:

这是CSS 规范相关部分

In the case that the ancestor is an inline element, the containing block is the bounding box around the padding boxes of the first and the last inline boxes generated for that element.... Otherwise, the containing block is formed by the padding edge of the ancestor.

在祖先是内联元素的情况下,包含块是为该元素生成的第一个和最后一个内联框的填充框周围的边界框......否则,包含块由祖先。

The simplest approach—as suggested in Winter's answer—is to use padding: inheriton the absolutely positioned div. It only works, though, if you don't want the absolutely positioned divto have any additional padding of its own. I think the most general-purpose solutions (in that both elements can have their own independent padding) are:

正如 Winter 的回答中所建议的,最简单的方法是padding: inherit在绝对定位的div. 但是,它仅在您不希望绝对定位div有任何额外的填充时才有效。我认为最通用的解决方案(因为两个元素都可以有自己独立的填充)是:

  1. Add an extra relatively positioned div(with no padding) around the absolutely positioned div. That new divwill respect the padding of its parent, and the absolutely positioned divwill then fill it.

    The downside, of course, is that you're messing with the HTML simply for presentational purposes.

  2. Repeat the padding (or add to it) on the absolutely positioned element.

    The downside here is that you have to repeat the values in your CSS, which is brittle if you're writing the CSS directly. However, if you're using a pre-processing tool like SASSor LESSyou can avoid that problem by using a variable. This is the method I personally use.

  1. div在绝对定位的周围添加一个额外的相对定位(没有填充)div。那个新的div将尊重其父级的填充,然后绝对定位div将填充它。

    当然,不利的一面是您只是为了展示目的而弄乱了 HTML。

  2. 在绝对定位的元素上重复填充(或添加)。

    这里的缺点是你必须在你的 CSS 中重复这些值,如果你直接编写 CSS,这会很脆弱。但是,如果您使用的是预处理工具,SASS或者LESS您可以通过使用变量来避免该问题。这是我个人使用的方法。

回答by Winter

One thing you could try is using the following css:

您可以尝试的一件事是使用以下 css:

.child-element {
    padding-left: inherit;
    padding-right: inherit;
    position: absolute;
    left: 0;
    right: 0;
}

It lets the child element inherit the padding from the parent, then the child can be positioned to match the parents widht and padding.

它让子元素从父元素继承填充,然后可以定位子元素以匹配父元素的宽度和填充。

Also, I am using box-sizing: border-box;for the elements involved.

此外,我正在使用box-sizing: border-box;所涉及的元素。

I have not tested this in all browsers, but it seems to be working in Chrome, Firefox and IE10.

我没有在所有浏览器中测试过这个,但它似乎在 Chrome、Firefox 和 IE10 中工作。

回答by NewSpender

Well, this may not be the most elegant solution (semantically), but in some cases it'll work without any drawbacks: Instead of padding, use a transparent border on the parent element. The absolute positioned child elements will honor the border and it'll be rendered exactly the same (except you're using the border of the parent element for styling).

嗯,这可能不是最优雅的解决方案(语义上),但在某些情况下,它可以正常工作而没有任何缺点:在父元素上使用透明边框而不是填充。绝对定位的子元素将遵循边框,并且呈现完全相同(除非您使用父元素的边框进行样式设置)。

回答by Touch

Here is my best shot at it. I added another Div and made it red and changed you parent's height to 200px just to test it. The idea is the the child now becomes the grandchild and the parent becomes the grandparent. So the parent respects its parent. Hope you get my idea.

这是我最好的尝试。我添加了另一个 Div 并将其设置为红色并将您父母的高度更改为 200px 只是为了测试它。这个想法是孩子现在成为孙子,父母成为祖父母。所以父母尊重父母。希望你能明白我的想法。

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 200px;">
     <div style="background-color: red;  position: relative; height: 100%;">    
        <div style="background-color: gray; position: absolute; left: 0px; right: 0px;bottom: 0px;">css sux</div>
     </div>
    </div>
  </body>
</html>

Edit:

编辑:

I think what you are trying to do can't be done. Absolute position means that you are going to give it co-ordinates it must honor. What if the parent has a padding of 5px. And you absolutely position the child at top: -5px; left: -5px. How is it suppose to honor the parent and you at the same time??

我认为您尝试做的事情无法完成。绝对位置意味着你要给它必须尊重的坐标。如果父级的内边距为 5px 会怎样。并且您绝对将孩子定位在顶部:-5px;左:-5px。如何同时尊重父母和你?

My solution

我的解决方案

If you want it to honor the parent, don't absolutely position it then.

如果你想让它尊重父母,那么不要绝对定位它。

回答by bhavya_w

1.) you cannot use big border on parent -- in case you want to have a specific border

2.) you cannot add margin -- in case your parent is a part of some other container and you want your parent to take the full width of that grand parent.

1.) 你不能在父级上使用大边框——如果你想要一个特定的边框

2.) 你不能添加边距——如果你的父级是其他容器的一部分并且你希望你的父级占据全部那个祖父母的宽度。

The Only Solution that should be applicable is to wrap your children's in an another container so that your parent becomes the grandparent and then apply padding to the new children's Wrapper / Parent. Or you can directly apply padding to the children.

应该适用的唯一解决方案是将您的孩子包装在另一个容器中,以便您的父母成为祖父母,然后将填充应用于新孩子的包装/父母。或者您可以直接将填充应用于子项。

In your case:

在你的情况下:

.css-sux{
  padding: 0px 10px 10px 10px;
}

回答by asankasri

Could have easily done using an extra level of Div.

使用额外级别的 Div 可以轻松完成。

<div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
  <div style="position: absolute; left: 0px; right: 0px; bottom: 10px; padding:0px 10px;">
    <div style="background-color: gray;">css sux</div>
  </div>
</div>

Demo: https://jsfiddle.net/soxv3vr0/

演示:https: //jsfiddle.net/soxv3vr0/

回答by ??l?j?

add padding:inheritin your absolute position

添加填充:继承您的绝对位置

.box{
  background: red;
  position: relative;
  padding: 30px;
  width:500px;
  height:200px;
 box-sizing: border-box;
 

}
<div  class="box">

  <div style="position: absolute;left:0;top:0;padding: inherit">top left</div>
  <div style="position: absolute;right:0;top:0;padding: inherit">top right</div>
  <div style="text-align: center;padding: inherit">center</div>
  <div style="position: absolute;left:0;bottom:0;padding: inherit">bottom left</div>
  <div style="position: absolute;right:0;bottom:0;padding: inherit">bottom right</div>


</div>