水平垂直居中绝对定位元素而不知道大小

8

我不确定是否仅使用CSS就可以实现,但我必须询问。

请在提供答案之前仔细阅读规格。谢谢!

我的标记:

<div class="wrapper">
    <img src="http://placehold.it/350x150">
    <p>Some text random size</p>
</div>

显然,如果.img元素是块级元素,.wrapper将具有与其相同的高度。 然后,我需要p元素在包装器内水平和垂直居中。我没有固定的宽度或高度。 所以,无论段落大小甚至图像大小如何,它都应该垂直和水平对齐,如此http://i.imgur.com/phiR48H.pnghttp://i.imgur.com/Xvdt42j.png所示。 如果我在段落上设置绝对位置,它将不能垂直对齐,因为我不知道段落高度就无法设置负边距。 我考虑过使用表格和单元格(vertical-align: middle;),但我只有一个单元格。有什么想法吗? 添加fiddle:http://jsfiddle.net/f3x7977z/ 提供的解决方案在IE8+中具有向后兼容性非常重要。
任何关于额外包装的建议,为了最终结果,都是受欢迎的!
5个回答

15

说明

将包装器的CSS属性position更改为relative,要居中的元素的属性更改为absolute

然后使用top: 50%left: 50%将元素定位在包装器中间。

接下来您会注意到该元素不完全居中,因为它自身的高度和宽度未被考虑计算。

所以我们使用transform: translate(-50%, -50%)属性进行修正,该属性使元素的高度减半并向上移动,使其宽度减半并向左移动。结果将是一个垂直和水平居中的元素。

由于我们需要考虑到IE8,因此我们将使用filter属性来实现与transform: translate相同的效果。

为了生成filter属性,使用了以下资源:IE的CSS3转换翻译器

示例

.box {
  margin: 10px;
  display: inline-block;
  position: relative;
}
.box span {
  position: absolute;
  top: 50%;
  left: 50%;
  background: #fff;
  box-shadow: 0 0 3px rgba(0, 0, 0, 1);
  padding: 5px;
}
.box.translate > span {
  transform: translate(-50%, -50%);
  -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, SizingMethod='auto expand')";
}
<div class="box translate">
  <img src="http://placehold.it/500x200" />
  <span>centered text</span>
</div>


Flex 不支持 IE8。而你的 .google 类具有宽度和高度。 - designarti
你是对的!Flex 只适用于现代浏览器!我会更新答案以考虑 IE8。你能检查一下现在是否可行吗?我的 Win10 下的 ietester 不正常工作。 - Romulo
谢谢!可能是正确的。等一下。 - designarti
我会将这作为正确答案。我以为这很简单,结果把我逼疯了!我编辑了你的答案,现在它正常工作 - http://jsfiddle.net/z7cpwrgs/1/。再次感谢! - designarti

7

如何垂直和水平居中多个绝对定位的子元素

其他已发布的答案已经解决了IE8的要求。这个答案为那些不关心IE8的人提供了一个干净高效的解决方案。

HTML(无更改)

<div class="wrapper">
    <img src="http://placehold.it/350x150"/>
    <p>My text, size unknowkn</p>
</div>

CSS

html, body { height: 100%; } /* necessary when using percentage heights within body
                                on non-absolutely positioned children (such as .wrapper)
                                https://dev59.com/51wZ5IYBdhLWcg3wM97Z#31728799 */ 
.wrapper { 
    height: 100%;
    width: 100%;
    position: relative; /* establish nearest positioned ancestor for abs. positioning */
}

img {
  position: absolute;
  left: 50%; /* positions img relative to container */
  top: 50%;  /* positions img relative to container */
  transform: translate(-50%, -50%); /* positions img relative to its height and width */
}

p {
  position: absolute;
  left: 50%;  /* positions p relative to container */
  top: 50%; /* positions p relative to container */
  transform: translate(-50%, -50%);  /* positions p relative to its height and width */
  margin: 0;
}

示例代码:http://jsfiddle.net/f3x7977z/7/


1

有一种更轻量级的解决方案。

  1. 从上方向下取外部元素的50%
  2. 将这50%的内部元素向上50%边距,使其位于外部元素底线的中心(请参见下面的fiddle)

.wrapper {
 position: absolute;
 top: 50%; left: 50%;
}
img { /* or a container with img and p */
 margin-top: -25%; margin-left: -50%;
}
<div class="wrapper">
    <img src="http://placehold.it/350x150">
    <p>Some text random size</p>
</div>


你将包装器绝对定位到了body上,但实际情况并非如此。 - designarti

1

检查 这个解决方案

HTML

<div class="wrapper">
    <img src="http://placehold.it/350x150"/>
    <span></span>
    <p>My text, size unknowkn</p>
</div>

CSS

.wrapper
{
    position: relative;
}

p
{
     position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 50%;
    height: 30%;
    margin: auto;
}

我的段落不应该有宽度或高度。 - designarti
@designarti 我可以使用display:inline-block吗? - Alex
@designarti 请查看 这个方案 - Alex
很抱歉,它看起来不正确。请检查提供的图片。 - designarti
1
这个非常好用,最简单和最好的解决方案,这一定是被接受的答案。适用于所有浏览器,甚至IE 8到10。 - Clain Dsilva
显示剩余3条评论

-1
不要使用那个解决方案,你应该使用这个。
.wrapper {
    position: absolute;
    top: 50%; left: 50%;
}
img { 
    margin-top: -25%; margin-left: -25%;
}

是的,但您正在使用主体的宽度和高度作为参考(相对于主体的绝对位置)。这不是一般情况。 - designarti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接