绝对定位忽略父级的填充

Posted

技术标签:

【中文标题】绝对定位忽略父级的填充【英文标题】:Absolute positioning ignoring padding of parent 【发布时间】:2013-06-11 12:11:02 【问题描述】:

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

所以我想要这个:

但我明白了:

<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。页脚尊重其父级的左侧填充,但它在右侧溢出。您会期望它也能够遵守正确的填充以保持一致...... 【参考方案1】:

这是我最好的尝试。我添加了另一个 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 的内边距怎么办。你绝对将孩子定位在 top: -5px;左:-5px。如何同时尊重父母和你?

我的解决方案

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

【讨论】:

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

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

【讨论】:

【参考方案3】:

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

【讨论】:

请注意,背景(颜色)不会像填充一样应用于边距 另外,百分比垂直填充计算为宽度的百分比,而不是高度,这与边距(或边框)的计算不同。【参考方案4】:

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

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

在你的情况下:

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

【讨论】:

【参考方案5】:

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

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

这里是relevant part of the CSS specification:

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

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

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

    当然,缺点是您只是为了演示目的而弄乱了 HTML。

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

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

【讨论】:

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

您可以尝试的一件事是使用以下 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 不希望孩子继承父母的填充。他希望孩子根据父母的填充偏移。【参考方案7】:

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

【讨论】:

【参考方案8】:

在你的绝对位置添加 padding:inherit

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

【讨论】:

【参考方案9】:

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

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

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

【讨论】:

以上是关于绝对定位忽略父级的填充的主要内容,如果未能解决你的问题,请参考以下文章

前端3 浮动布局,固定定位,绝对定位,相对定位

相对定位与绝对定位的分析测试

盒子定位HTML

position属性中的绝对定位和相对定位

IE 8 绝对定位元素在其父剪辑问题之外

div用绝对值填充父级的剩余高度