[CSS翻译]CSS中的居中:完整指南

124 阅读5分钟

原文地址:css-tricks.com/centering-c…

原文作者:css-tricks.com/author/chri…

发布时间:2020年2月19日

在CSS中居中的东西是CSS抱怨的表象。为什么一定要这么难呢?他们在嘲笑。我认为问题不在于它很难做,而在于有这么多不同的方法,根据不同的情况,很难知道该达到哪一种。

所以我们把它做成决策树,希望能让它变得更简单。

我需要以...为中心

水平方向

是内联元素还是inline-*元素(如文本或链接)?

你可以在块级父元素内,将内联元素水平居中,只需使用:

.center-children {
  text-align: center;
}

这将适用于inline、inline-block、inline-table、inline-flex等。

codepen.io/chriscoyier…

它是块级元素吗?

你可以给块级元素居中,给它的margin-leftmargin-rightauto(而且它有一个设定的width,否则它就是全宽,不需要居中)。这通常是通过这样的速记来实现的。

.center-me {
  margin: 0 auto;
}

无论你要居中的块级元素或父元素的宽度是多少,这都会起作用。

codepen.io/chriscoyier…

请注意,你不能将一个元素float到中心。不过有一个技巧

是否有一个以上的块级元素?

如果你有两个或更多的块级元素需要在一行中水平居中,那么你有可能会把它们做成不同的display类型。这里有一个将它们做成inline-block的例子和一个flexbox的例子。

codepen.io/chriscoyier…

除非你的意思是你有多个块级元素堆叠在一起,在这种情况下,自动边距技术仍然是好的。

codepen.io/chriscoyier…

垂直地

垂直居中在CSS中是比较棘手的。

是内联还是inline-*元素(如文本或链接)?

是单行吗?

有时内联/文本元素可能会出现垂直居中的情况,只是因为它们的上方和下方有相等的padding。

.link {
  padding-top: 30px;
  padding-bottom: 30px;
}

codepen.io/chriscoyier…

如果由于某些原因,padding不是一个选项,而你又想把一些你知道不会被包裹的文本居中,那么有一个技巧是让line-height与高度相等来center文本。

.center-text-trick {
  height: 100px;
  line-height: 100px;
  white-space: nowrap;
}

是多行吗?

上下等量的padding也可以给多行文字带来居中的效果,但如果这样不行,也许文字所在的元素可以是一个表格单元格,可以是字面意思,也可以是用CSS做成表格单元格的样子。在这种情况下,vertical-align属性处理了这个问题,与它通常处理一行元素对齐的情况不同。(更多关于这个问题。)

codepen.io/chriscoyier…

如果出了类似表格的东西,也许你可以使用flexbox?一个单一的flex-子代可以很容易地在flex-父代中居中。

.flex-center-vertically {
  display: flex;
  justify-content: center;
  flex-direction: column;
  height: 400px;
}

codepen.io/chriscoyier…

请记住,只有当父容器有固定高度(px、%等)时,才真正有意义,这就是为什么这里的容器有高度。

如果这两种技术都没有了,你可以采用 "ghost element "技术,在容器内放置一个全高的伪元素,文本与之垂直对齐。

.ghost-center {
  position: relative;
}
.ghost-center::before {
  content: " ";
  display: inline-block;
  height: 100%;
  width: 1%;
  vertical-align: middle;
}
.ghost-center p {
  display: inline-block;
  vertical-align: middle;
}

codepen.io/chriscoyier…

是块级元素吗?

你知道元素的高度吗?

在网页布局中,不知道高度是相当常见的,原因很多:如果宽度发生变化,文字回流会改变高度。文本样式的变化会改变高度。文字数量的变化会改变高度。有固定长宽比的元素,比如图片,调整大小后会改变高度。等等。

但如果你知道高度,你可以像这样垂直居中。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  height: 100px;
  margin-top: -50px; /* account for padding and border if not using box-sizing: border-box; */
}

codepen.io/chriscoyier…

是未知高度的元素吗?

还是可以把它的高度往下撞一半后,再往上推一半,就可以居中了。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

codepen.io/chriscoyier…

你关心元素是否拉伸了容器的高度吗?

如果你不在乎,你只需要里面的内容垂直居中,使用表格或CSS显示将元素做成表格就可以了。

codepen.io/chriscoyier…

可以使用flexbox吗?

没有什么大惊小怪的,在flexbox中这就简单多了。

.parent {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

codepen.io/chriscoyier…

你也可以在子元素上使用margin: auto; 在flexbox中获得居中。

水平方向和垂直方向

你可以以任何方式结合上面的技术来获得完美的中心元素。但我发现这一般分为三个阵营。

元素的宽度和高度是固定的吗?

使用相当于该宽度和高度一半的负边距,在你将其绝对定位在50%/50%之后,将使其居中,并提供强大的跨浏览器支持。

.parent {
  position: relative;
}

.child {
  width: 300px;
  height: 100px;
  padding: 20px;

  position: absolute;
  top: 50%;
  left: 50%;

  margin: -70px 0 0 -170px;
}

codepen.io/chriscoyier…

该元素的宽度和高度是否未知?

如果你不知道宽度和高度,你可以使用transform属性和两个方向50%的负翻译(它是基于元素的当前宽度/高度)来居中。

.parent {
  position: relative;
}
.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

codepen.io/chriscoyier…

可以使用flexbox吗?

要使用flexbox在两个方向上居中,你需要使用两个居中属性。

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

codepen.io/chriscoyier…

你能用网格吗?

这只是一个小技巧(由Lance Janssen发来的),对于一个元素来说,几乎是可行的。

body, html {
  height: 100%;
  display: grid;
}
span { /* thing to center */
  margin: auto;
}

codepen.io/chriscoyier…

结论

你完全可以在CSS中把东西居中。


通过www.DeepL.com/Translator (免费版)翻译