在未知中居中

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 价值 200 美元的免费信用额度!

在网页设计中,居中元素时,您拥有的关于要居中元素及其父元素的信息越多,它就越容易。 那么,如果您什么都不知道呢? 它仍然可以做到。

不太难:已知子元素

如果您知道要居中元素及其父元素的高度和宽度(并且这些尺寸不会改变,即非流体宽度环境),则将元素居中的一个万无一失的方法就是使用像素值对其进行绝对定位,使其看起来完美居中。

假设您知道要居中元素的精确宽度和高度,但父元素的高度和宽度可能会改变

您对要居中的元素进行绝对定位,并将顶部和左侧的值设置为 50%,并将顶边距和左边距设置为元素高度和宽度的负的一半。 这有点绕口,所以 查看这里

更难:未知子元素

难点在于您不知道要居中元素的尺寸。

我们知道什么? 什么都不知道! 我们什么时候知道? 现在就知道了!

最粗俗的处理方法就是直接使用表格

<table style="width: 100%;">
  <tr>
     <td style="text-align: center; vertical-align: middle;">
          Unknown stuff to be centered.
     </td>
  </tr>
</table>

如果您担心语义问题,可以尝试将其与您的内容相匹配。

<div class="something-semantic">
   <div class="something-else-semantic">
       Unknown stuff to be centered.
   </div>
</div>

并获得与表格相同的结果,例如

.something-semantic {
  display: table;
  width: 100%;
}
.something-else-semantic {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

CSS 表格可能适合您。 或者可能不适合。 表格的渲染方式与普通块级 div 稍有不同。 例如,100% 宽度。 表格只会扩展到其内部内容所需的宽度,而块级元素默认情况下会自动扩展到其父元素的宽度。 此外,如果您需要该 div 中的其他内容进行定位或以其他方式不作为表格单元格,那么上帝保佑您。

Michał Czernow 向我写信,介绍了一种非常巧妙的替代方法,它可以实现相同的效果。 如果我们在父元素内部设置一个“幽灵”元素,高度为 100%,然后我们对该元素和要居中的元素执行vertical-align: middle,我们就能获得相同的效果。

看到我们做了什么吗?

那么,幽灵元素需要是一个非语义元素吗? 不需要,它可以是一个伪元素。

/* This parent can be any width and height */
.block {
  text-align: center;

  /* May want to do this if there is risk the container may be narrower than the element inside */
  white-space: nowrap;
}
 
/* The ghost, nudged to maintain perfect centering */
.block:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

/* The element to be centered, can also be of any width and height */ 
.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
}
View Demo

我想告诉您,幽灵元素技术要好得多,应该成为未来各个时代的首选居中技术。 但实际上,它与表格技巧几乎相同。 该方法的浏览器支持几乎涵盖所有内容,包括 IE 8+。 IE 7 不支持伪元素。 但是它也不支持 CSS 表格,所以两者旗鼓相当。 如果需要 IE <= 7 支持,则需要使用<table>(或使用同样非语义的<span>或类似的元素作为幽灵元素)。

这些内容并非全新领域。 Gary Turner 在五年前就写过相关内容。 但是,我感谢 Michał 用伪元素实现了它,使其成为迄今为止最语义化的方法。

注意:0.25em 的回退调整有点不稳定。 为了完美实现它,您可以在父元素上设置 font-size: 0;,然后在内容容器内部将字体大小恢复。