ChatGPT解决这个技术问题 Extra ChatGPT

绝对定位忽略父级的填充

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

所以我想要这个:

https://i.stack.imgur.com/PNk2V.png

但我得到了这个:

https://i.stack.imgur.com/ADkGU.png

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

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

为什么不将内部 div 的左/右/下更改为 style="background-color: gray; position: absolute; left: 10px; right: 10px; bottom: 10px;"
是的,我想到了这一点,但它很快就变成了一个令人头疼的维护问题,因为每个孩子都必须有自己的一套补偿来解决这个问题。如果他们只是尊重父母的填充,那么你可以在父母中设置一次,而不用担心所有的孩子。
如上所述,如果您使用(相对定位)父级的填充值作为(绝对定位)子级的 left:right:,您的问题就解决了。我正在添加这个 b/c,这是其他有同样问题的人可能正在寻找的答案。
这里有类似的问题:jsfiddle.net/5n4By/6。页脚尊重其父级的左侧填充,但它在右侧溢出。你会期望它能够尊重正确的填充以及保持一致......

C
Community

首先,让我们看看为什么会这样。

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

这是 relevant part of the CSS specification

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

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

在绝对定位的 div 周围添加一个额外的相对定位的 div(没有填充)。新的 div 将尊重其父级的填充,然后绝对定位的 div 将填充它。当然,缺点是您只是为了演示目的而弄乱了 HTML。在绝对定位的元素上重复填充(或添加)。这里的缺点是您必须重复 CSS 中的值,如果您直接编写 CSS,这很脆弱。但是,如果您使用的是 SASS 或 LESS 等预处理工具,则可以通过使用变量来避免该问题。这是我个人使用的方法。


为什么这是 position: absolute 的默认值?令人惊讶的是,包含框是填充框,但它一定是有原因的,就像我确信(没有 box-sizingwidth & height 不包括内边距或边框。
只是一个补充:这些都不受父级或子级的 box-sizing 属性的影响。这是因为这会影响 sizing,如宽度/高度,但不会影响包含框,尽管我承认如果它同时影响两者会更有意义。
这是很好的信息,但它是错误的答案。正确的答案是 Winter 的下面......使用 padding: inherit 并且您的 Absolute 元素将获得它需要的填充。不知道为什么这比正确答案有更多的赞成票......:P
@NotaGuruAtAll:如果绝对定位的 div 不需要任何自己的填充,padding: inherit 效果很好,并且我已经添加了对该技术的提及。但是,它不太灵活,因为您不能向绝对定位的 div 添加任何额外的填充(即您不能说 padding: inherit + 5px)。这就是为什么我更喜欢我在这里提到的技术。
如果您只是在寻找子元素以尊重父元素的填充,则 position:absolute 子元素上的填充继承确实有效。但是,如果您希望将 additional 填充添加到子元素上,则必须在代码中检查填充的比率。仅使用 CSS 没有干净的方法。
W
Winter

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

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

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

此外,我将 box-sizing: border-box; 用于所涉及的元素。

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


我结合了这个答案和@NewSpender 的答案。在我的特殊情况下,绝对定位的 div 一直忽略填充,但受其父元素的限制。所以给绝对定位的 div 加上白色的粗边框模仿了我需要的填充。一个先决条件是您的背景必须是相同的颜色。
但是 OP 不希望孩子继承父母的填充。他希望孩子根据父母的填充进行偏移。
N
NewSpender

好吧,这可能不是最优雅的解决方案(语义上),但在某些情况下它会毫无缺点地工作:在父元素上使用透明边框代替填充。绝对定位的子元素将遵循边框,并且将呈现完全相同的内容(除非您使用父元素的边框进行样式设置)。


T
Touch

这是我最好的尝试。我添加了另一个 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>

编辑:

我认为你想做的事情是做不到的。绝对位置意味着你要给它必须遵守的坐标。如果父级有 5px 的填充怎么办。而且您绝对将孩子放在顶部:-5px;左:-5px。如何同时尊重父母和你?

我的解决方案

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


谢谢,我很欣赏这篇文章,但这仍然是解决真正问题的方法。我真正想知道的是,您是否可以让孩子尊重父元素的填充。如果事实证明答案是否定的,我会给你代表。
如果您绝对定位它们,那么它们将不会尊重其父元素。他们会尊重你。出于同样的原因,如果你没有绝对定位它们,那么你就不能真正使用像 bottom: 10px 这样的东西,因为它们尊重它们的父元素。但是你想做什么,我猜会为矛盾腾出空间,因此,它会在浏览器上有所不同。我认为只有解决方法才能做到。
绝对定位确实尊重父级,这是它使用的坐标系。当您说顶部 0px 时,这意味着距父级顶部 0px。问题是它是否应该考虑父母的填充。如果父级的内边距为 5px,并且您给子级 top: -5px,则如果父级的内边距被尊重,它将与父级齐平,如果没有,则在父级之上 5px。
N
Niloct

在父 div 中使用边距而不是填充:http://blog.vjeux.com/2012/css/css-absolute-position-taking-into-account-padding.html


请注意,背景(颜色)不会像填充一样应用于边距
此外,百分比垂直填充计算为宽度的百分比,而不是高度,这与边距(或边框)的计算不同。
a
asankasri

使用额外级别的 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>

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


b
bhavya_w

1.) 你不能在父级上使用大边框——如果你想有一个特定的边框 2.) 你不能添加边距——如果你的父级是其他容器的一部分并且你希望你的父级占据全部那个祖父母的宽度。

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

在你的情况下:

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

ß
ßãlãjî

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

.box{ 背景:红色;位置:相对;内边距:30px;宽度:500 像素;高度:200px; box-sizing:边框框; }

左上角
右上
center
左下
右下


G
Giga

我会这样设置孩子的宽度:

.child {position: absolute; width: calc(100% - padding);}

公式中的Padding是左右父级的padding之和。我承认它可能不是很优雅,但在我的例子中,一个具有覆盖功能的 div 是有效的。