【问题标题】:Is this a valid way of horizontally centering absolute-positioned elements?这是将绝对定位元素水平居中的有效方法吗?
【发布时间】:2013-04-14 19:52:11
【问题描述】:

我想要一种可重用的方法来将绝对定位的固定宽度元素在其容器中水平居中,并且我想要可重用的代码(例如,没有负像素边距)。

我偶然发现了一个完美的组合:

http://jsfiddle.net/aaronadams/Mquha/

<div class="outer center">
    <div class="inner center"></div>
</div>
.outer {
    position: absolute;
    width: 400px; height: 400px;
    background: #999;
}

.inner {
    position: absolute;
    width: 200px; height: 400px;
    background: #666;
}

.center {
    left: 0; right: 0;
    margin-left: auto; margin-right: auto;
}

它很干净,它(相对)容易理解,它似乎可以在 IE 8+、Chrome、Firefox、Safari 中运行……但它也似乎是一个巨大的、肮脏的、不好的定位黑客,可能会崩溃随时在接缝处。

我找不到任何文档来说明这种定位行为是正确还是不正确。它是哪一个?适合生产,还是完全不可靠?

【问题讨论】:

  • 天哪!它也适用于垂直居中!! o_O
  • 看起来不错,只要您不是在寻找 流畅的布局
  • 我看不出这与使用相对定位 + 负边距有什么不同(除了这看起来像更多代码的事实)。无论哪种方式,您都必须知道元素的大小。由于您已经知道它的大小,将其除以 2 似乎不是问题。
  • @cimmanon 在此方法中,边距由渲染引擎自动计算。这比手动计算更可靠,因为手动计算会引入更多可能出错的地方。
  • @laconbass 嗯,你是对的! jsfiddle.net/aaronadams/rkD7h 多亏了 Marc Audet 在下面的回答,我实际上知道在哪里寻找文档,而且果然,这也是一个记录在案的行为:w3.org/TR/CSS2/visudet.html#abs-non-replaced-height 很棒的发现。

标签: css positioning css-position centering


【解决方案1】:

鉴于您的两个容器.outer.inner 是绝对定位的,那么您所做的不仅是正确的,而且也是唯一的方法 当没有指定父容器的宽度时。

您的解决方案完全符合 CSS 2.1 规范,它非常可靠。

供参考,您需要查看:

http://www.w3.org/TR/CSS2/visudet.html#abs-non-replaced-width

指定如何计算绝对定位元素的宽度。

在您的 jsFiddle 示例中,您需要意识到两个 &lt;div&gt; 的包含块是视口或根元素。您还没有通过指定topbottom 属性来说明垂直放置。此外,由于绝对定位的元素是外流的,因此它们的固有高度不会影响计算包含块的高度,并且在某些应用程序中,这是一个因素会使这种方法在不修改的情况下无法使用。

此外,如果您将示例代码包装在相对定位的包装器&lt;div&gt; 中,并且应用了固定宽度,那么子元素仍将正确居中,如此演示所示:http://jsfiddle.net/audetwebdesign/aNS5j/(保持请记住,您可能需要在包装元素中留出足够的高度。)

但是,正如前面在评论中指出的那样,如果包含块的宽度(我的演示中的视口或包装器元素)小于您的子元素的宽度(在您的示例中为 400px),那么居中将不再起作用,但是根据 CSS 规范,这仍然是正确的行为。

您的问题涉及 CSS 视觉格式化模型如何工作的一个基本但重要的基础。

一边

如果不对.inner 元素使用绝对定位,您仍然可以获得相同的效果,在这种情况下,margin: 0 auto 就足够了。在稍微简洁的 CSS 声明中节省成本。

关于负边距

尽管负边距确实有效并且在大多数现代浏览器中始终如一地实现,但 CSS 2.1 规范并没有说明应该如何实现负边距。理论上,负边距可能会在某些仍符合 CSS 规范的用户代理中失效。

【讨论】:

  • 谢谢!这正是我一直在寻找的答案:行为记录。我自己找不到(那些官方的 W3C 文档对我来说有点不知所措)。显然,这仍然需要在大量浏览器中进行测试,但在我生活的世界中,它可能会大大节省时间和线路。
  • @AaronAdams 很高兴能提供帮助,这是一个很好的问题,因为它引发了很多有见地的 cmets。 W3C 文档很难阅读,好像它们是由数学家和律师共同编写的,但它们导致了符合标准的浏览器,这使我们的行业能够以合理的方式发展。祝你好运!
【解决方案2】:

我一直发现,一旦您进入position:absolute; 池,您就放弃了一个优雅的解决方案。遗憾的是,在很多情况下,绝对定位是解决问题的唯一方法。

据我所知,行业标准使用负边距,正如您所提到的:http://jsfiddle.net/Mquha/3/

再一次,这感觉很脏,而且:不可重复使用。

我已经研究了你建议的方法,你的方法似乎是一个相当现代的发现,我有点惊讶它甚至可以工作。无论如何,它比负边距方法容易得多,并且似乎被所有主要浏览器支持,就像你说的那样。 我正在采用您将来提出的方法,仍然不完美,但至少它比使用负边距更脏。我只能建议您在使用绝对定位时也这样做。

【讨论】:

  • 为什么你认为绝对定位不优雅?
  • 仅当内容比视口或周围内容小时,绝对定位才能正常工作。
  • 我个人认为它不优雅,因为当你使用它时,大多数时候你都在破坏页面的流动。 @cimmonon,绝对定位的大小几乎总是可以预测的,因此得名绝对定位。我想知道我的回答有什么值得反对的地方。
【解决方案3】:

这是我最好的选择

把你的css改成

#outer {
    position: absolute;
    width: 400px; height: 400px;
    background: #999;
}

#inner {
    position: absolute;
    width: 200px; height: 400px;
    background: #666;
}

.center {
    margin-left: auto; margin-right: auto;
}

还有你的 html 到

<div id="outer center" class="center">
    <div id="inner center" class="center"></div>
</div>

【讨论】:

  • 问题的解决方案确实有效,问题是是否适合生产使用
猜你喜欢
  • 1970-01-01
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 2020-10-08
  • 2016-03-04
  • 1970-01-01
相关资源
最近更新 更多