这是一种水平居中绝对定位元素的有效方法吗?

时间:2013-04-22 01:37:20

标签: css positioning css-position centering

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

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

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 ......但它似乎也是一个巨大的,肮脏的,不好的定位黑客,可能会分崩离析在任何时候的接缝。

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

3 个答案:

答案 0 :(得分:3)

考虑到你的两个容器.outer.inner绝对定位的约束,那么你所做的不仅是正确的,而且,它也是唯一的方法 何时未指定父容器的宽度。

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

供参考,您需要查看:

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

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

在你的jsFiddle示例中,你需要意识到两个<div>的包含块是视口或根元素。您尚未通过指定topbottom属性来说明垂直展示位置。此外,由于绝对定位的元素是不流动的,它们的固有高度不会影响计算包含块的高度,并且在某些应用中,这是使该方法无法修改而无法使用的因素。

此外,如果您要将示例代码包装在相对定位的包装器<div>中,并且应用了固定宽度,则子元素仍将正确居中,如此演示所示:{{3 (请记住,您可能需要在包装器元素中允许足够的高度。)

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

您的问题已经触及了CSS视觉格式化模型的基本但重要的基础。

<强>除了

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

关于负边距

虽然负边距确实起作用并且在大多数现代浏览器中都是一致的,但CSS 2.1规范并没有说明应该如何实现负边距。从理论上讲,负边距可能会在一些仍然符合CSS规范的用户代理中崩溃。

答案 1 :(得分:0)

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

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

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

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

答案 2 :(得分:-1)

这是我最好的选择

将您的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>