原文地址: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等。
它是块级元素吗?
你可以给块级元素居中,给它的margin-left
和margin-right
为auto
(而且它有一个设定的width
,否则它就是全宽,不需要居中)。这通常是通过这样的速记来实现的。
.center-me {
margin: 0 auto;
}
无论你要居中的块级元素或父元素的宽度是多少,这都会起作用。
请注意,你不能将一个元素float
到中心。不过有一个技巧。
是否有一个以上的块级元素?
如果你有两个或更多的块级元素需要在一行中水平居中,那么你有可能会把它们做成不同的display
类型。这里有一个将它们做成inline-block
的例子和一个flexbox的例子。
除非你的意思是你有多个块级元素堆叠在一起,在这种情况下,自动边距技术仍然是好的。
垂直地
垂直居中在CSS中是比较棘手的。
是内联还是inline-*
元素(如文本或链接)?
是单行吗?
有时内联/文本元素可能会出现垂直居中的情况,只是因为它们的上方和下方有相等的padding。
.link {
padding-top: 30px;
padding-bottom: 30px;
}
如果由于某些原因,padding不是一个选项,而你又想把一些你知道不会被包裹的文本居中,那么有一个技巧是让line-height
与高度相等来center
文本。
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}
是多行吗?
上下等量的padding也可以给多行文字带来居中的效果,但如果这样不行,也许文字所在的元素可以是一个表格单元格,可以是字面意思,也可以是用CSS做成表格单元格的样子。在这种情况下,vertical-align属性处理了这个问题,与它通常处理一行元素对齐的情况不同。(更多关于这个问题。)
如果出了类似表格的东西,也许你可以使用flexbox?一个单一的flex-子代可以很容易地在flex-父代中居中。
.flex-center-vertically {
display: flex;
justify-content: center;
flex-direction: column;
height: 400px;
}
请记住,只有当父容器有固定高度(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;
}
是块级元素吗?
你知道元素的高度吗?
在网页布局中,不知道高度是相当常见的,原因很多:如果宽度发生变化,文字回流会改变高度。文本样式的变化会改变高度。文字数量的变化会改变高度。有固定长宽比的元素,比如图片,调整大小后会改变高度。等等。
但如果你知道高度,你可以像这样垂直居中。
.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; */
}
是未知高度的元素吗?
还是可以把它的高度往下撞一半后,再往上推一半,就可以居中了。
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
你关心元素是否拉伸了容器的高度吗?
如果你不在乎,你只需要里面的内容垂直居中,使用表格或CSS显示将元素做成表格就可以了。
可以使用flexbox吗?
没有什么大惊小怪的,在flexbox中这就简单多了。
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}
你也可以在子元素上使用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;
}
该元素的宽度和高度是否未知?
如果你不知道宽度和高度,你可以使用transform属性和两个方向50%的负翻译(它是基于元素的当前宽度/高度)来居中。
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
可以使用flexbox吗?
要使用flexbox在两个方向上居中,你需要使用两个居中属性。
.parent {
display: flex;
justify-content: center;
align-items: center;
}
你能用网格吗?
这只是一个小技巧(由Lance Janssen发来的),对于一个元素来说,几乎是可行的。
body, html {
height: 100%;
display: grid;
}
span { /* thing to center */
margin: auto;
}
结论
你完全可以在CSS中把东西居中。
通过www.DeepL.com/Translator (免费版)翻译