CSS居中是CSS应用中的一个典型代表,很多人抱怨它,为什么这么难?但是我认为这个问题并不是很难,而是因为有很多方式可以实现它。
1. 水平居中
1.1 行内元素或者inline-*元素(比如text或者link)
使用以下代码在块级父元素内将行内元素水平居中:
.center-children {
text-align: center;
} // 写在块级父元素CSS中
对inline, inline-block, inline-table, inline-flex等也是有效的
1.2 块级元素
设置块级元素的margin-left和margin-right为auto来居中,块级元素本身要具有固定的宽度,否则将占满整个屏幕,不需要居中。
.center-me {
margin: 0 auto;
width: 300px; // 设置块级元素宽度
}
无论居中的块级元素或父级元素的宽度如何,都可以使用。
请注意,不能将元素浮动到中心(使用float)
1.3 多个块级元素
如果有两个或多个需要在水平方向上居中放置的块级元素,则最好为它们提供不同的显示类型(display type)。
HTML
<main class="inline-block-center">
<div>块级元素1</div>
<div>块级元素2 可以选择展示更多的内容, ‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>
<div>块级元素3</div>
</main>
<main class="flex-center">
<div>块级元素1</div>
<div>块级元素2 可以选择展示更多的内容,‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>
<div>块级元素3</div>
</main>
CSS
main {
background: white;
margin: 20px 0;
padding: 10px;
}
main div {
background: black;
color: white;
padding: 15px;
max-width: 125px;
margin: 5px;
}
.inline-block-center {
text-align: center;
}
.inline-block-center div {
display: inline-block;
text-align: left;
}
.flex-center {
display: flex;
justify-content: center;
}
除非要把多个块级元素相互堆叠,否则自动边距(auto margin)技术仍然可以使用。
HTML
<main>
<div>块级元素1 独自占一行</div>
<div>块级元素2 可以选择展示更多的内容, ‘还记得昨天,那个夏天‘(歌词来凑数[狗头])</div>
<div>块级元素3 独自占一行</div>
</main>
CSS
main {
background: white;
margin: 20px 0;
padding: 10px;
}
main div {
background: black;
margin: 0 auto;
color: white;
padding: 15px;
margin: 5px auto;
}
main div:nth-child(1) {
width: 200px;
}
main div:nth-child(2) {
width: 400px;
}
main div:nth-child(3) {
width: 125px;
}
2. 垂直居中
2.1.行内元素或者inline-*元素(比如text或者link)
<1>单独一行
有时inline或者text元素可以垂直居中显示,只是因为它们的padding-top和padding-bottom相同。
.link {
padding-top: 30px;
padding-bottom: 30px;
}
如果出于某些原因,无法选择padding属性,并且想要将一些不需要换行(wrap)的文本(text)居中,可以选择把行高(line-height)设置为与元素高度相同,使文本居中。
.center-text-trick {
height: 100px;
line-height: 100px;
white-space: nowrap;
}
<2>多行
padding-top和padding-bottom相同也可以使多行的文本居中。
但是如果padding相同的方法行不通,则文本可能是一个表格单元中,无论这个表格单元是还是通过CSS创建的。
在这种情况下,使用vertical-align属性可以处理此问题,这与通常处理行中需要对齐元素时,使用的对齐方式不同。
HTML
<table>
<tr>
<td>
在实际表格单元格中将多行文字垂直居中。
</td>
</tr>
</table>
<div class="center-table">
<p>在CSS创建的表格布局中的多行文本垂直居中。</p>
</div>
CSS
table {
background: white;
width: 240px;
border-collapse: separate;
margin: 20px;
height: 250px;
}
table td {
background: black;
color: white;
padding: 20px;
border: 10px solid white;
/* default is vertical-align: middle; */
}
.center-table {
display: table;
height: 250px;
background: white;
width: 240px;
margin: 20px;
}
.center-table p {
display: table-cell;
margin: 0;
background: black;
color: white;
padding: 20px;
border: 10px solid white;
vertical-align: middle;
}
如果出现类似表格的,可以使用flexbox。 可以很容易地使单个flex-child居中在flex-parent中。
HTML
<div class="flex-center">
<p>在flexbox容器中将多行文本垂直居中。</p>
</div>
CSS
div {
background: white;
width: 240px;
margin: 20px;
}
.flex-center {
background: black;
color: white;
border: 10px solid white;
display: flex;
flex-direction: column;
justify-content: center;
height: 200px; resize: vertical;
overflow: auto;
}
.flex-center p {
margin: 0;
padding: 20px;
}
请记住,只有父容器的高度固定(px,%等)才真正重要。
如果这两些方法都不可行,则可以采用“ghost element”,其中将满高的伪元素(height: 100%)放置在容器内,并使文本与之垂直对齐。
HTML
<div class="ghost-center">
<p>在容器中垂直居中放置多行文本。 以幽灵伪元素(ghost pseudo element)为中心</p>
</div>
CSS
div {
background: white;
width: 240px;
height: 200px;
margin: 20px;
color: white;
resize: vertical;
overflow: auto;
padding: 20px;
}
.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;
width: 190px;
margin: 0;
padding: 20px;
background: black;
}
2.2块级元素
<1>知道元素高度
知道元素高度,可以像这样垂直居中:
.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; */
}
HTML
<main> <div> 我是一个具有固定高度的块级元素,在我的父元素中垂直居中。 </div> </main>
CSS
main { background: white; height: 300px; margin: 20px; width: 300px; position: relative; resize: vertical; overflow: auto;}main div { position: absolute; top: 50%; left: 20px; right: 20px; height: 100px; margin-top: -70px; background: black; color: white; padding: 20px;}
<2>不知道元素高度
不知道网页布局中的高度是很常见的。
原因有很多,例如
- 如果宽度改变,文本重排可以改变高度。
- 文本样式的变化可以改变高度。
- 文本量的变化可以改变高度。
- 具有固定纵横比的元素(如图像)可以在调整大小时改变高度。
仍然可以通过在将其向下一半后将其向上推到一半高度来将其居中:
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<3>元素是否拉伸了容器的高度
如果不关心元素是否拉伸了容器的高度,只需要垂直居中的内容,使用表格或 CSS 显示将元素变成表格就可以了。
HTML
<main>
<div>
我是一个高度未知的块级元素,在我的父元素中垂直居中。
</div>
</main>
CSS
main {
background: white;
height: 300px;
margin: 20px;
width: 300px;
position: relative;
padding: 20px;
display: table;
}
main div {
background: black;
color: white;
padding: 20px;
display: table-cell;
vertical-align: middle;
}
<4>使用flexbox
flexbox 中要容易得多
.parent {
display: flex;
flex-direction: column;
justify-content: center;
}
3.水平垂直居中
可以以任何方式组合上述方案以获得水平垂直居中。 发现这通常分为三个方案:
3.1 元素有固定的宽高
使用等于该宽度和高度一半的负边距,在将其绝对定位在 50% / 50% 后,将使其居中并具有强大的跨浏览器支持:
.parent {
position: relative;
}
.child {
width: 300px;
height: 100px;
padding: 20px;
position: absolute;
top: 50%;
left: 50%;
margin: -70px 0 0 -170px;
}
HTML
<main> <div> 我是一个块级元素,具有固定的高度和宽度,在我的父元素中垂直居中。 </div> </main>
CSS
main {
position: relative;
background: white;
height: 200px;
width: 60%;
margin: 0 auto;
padding: 20px;
resize: both;
overflow: auto;
}
main div {
background: black;
color: white;
width: 200px;
height: 100px;
margin: -70px 0 0 -120px;
position: absolute;
top: 50%;
left: 50%;
padding: 20px;
}
3.2 元素没有固定的宽高
如果不知道宽度或高度,可以使用 transform 属性和在两个方向上 50% 的负平移(它基于元素的当前宽度/高度)到中心:
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
3.3使用flexbox
要使用 flexbox 在两个方向上居中,需要使用两个居中属性:
.parent {
display: flex;
justify-content: center;
align-items: center;
}
4.4 使用grid
这只是一个小技巧,几乎适用于一个元素:
body, html {
height: 100%;
display: grid;
}
span { /* thing to center */
margin: auto;
}
HTML
<div class="center-me"> 我是中心 </div>
CSS
body, html {
height: 100%;
display: grid;
}
.center-me {
margin: auto;
}