利用CSS实现元素的水平并垂直居中是一个非常常见的面试问题,以下将列出部分常用方法。

一、基础代码

为使示例更清晰,编写如下基础代码:

基础HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div class="father">
<div class="child">Hello World</div>
</div>
</body>
</html>

基础CSS

1
2
3
4
5
6
7
8
9
10
11
.father {
border: 1px solid blue;
width: 300px;
height: 300px;
}

.child {
width: 100px;
height: 100px;
background: aqua;
}

居中实现

一、绝对定位 + margin

1
2
3
4
5
6
7
8
9
10
.father {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}

二、绝对定位 + calc

本方法实际上与方法一一致,优点是无需手动计算,缺点是可能存在兼容性问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.father {
position: relative;
}
.child {
/*position: absolute;*/
/*top: calc(50% - 50px);*/
/*left: calc(50% - 50px);*/

/*或者*/
position: absolute;
--widthChild: 100px;
--heightChild: 100px;
width: var(--widthChild);
height: var(--heightChild);
top: calc(50% - calc(var(--widthChild) / 2));
left: calc(50% - calc(var(--heightChild) / 2));
}

三、绝对定位 + transform

1
2
3
4
5
6
7
8
9
.father {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

四、绝对定位 + margin(auto)

1
2
3
4
5
6
7
8
9
10
11
.father {
position: relative;
}
.child {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

五、text-align

仅适用于文本

1
2
3
4
5
6
7
8
9
10
11
12
.father {
line-height: 300px;
text-align: center;
font-size: 0;
}
.child {
font-size: 16px;
display: inline-block;
vertical-align: middle;
line-height: initial;
text-align: left;
}

六、table-cell布局

1
2
3
4
5
6
7
8
.father {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child {
display: inline-block;
}

七、flex布局

最常用、最简单的方法,IE浏览器有一定的兼容性问题。

1
2
3
4
5
.father {
display: flex;
justify-content: center;
align-items: center;
}

八、Grid布局

1
2
3
4
5
6
7
.father {
display: grid;
}
.child {
align-self: center;
justify-self: center;
}

九、writing-mode + text-align

仅适用于文字

1
2
3
4
5
6
7
8
9
.father {
writing-mode: vertical-lr;
text-align: center;
}
.child {
writing-mode: horizontal-tb;
display: inline-block;
margin: 0 calc(50% - 50px);
}

十、伪元素 + calc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.father::before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-left: -5px; /*content宽度*/
}
.child {
--widthChild: 100px;
width: var(--widthChild);
display: inline-block;
vertical-align: middle;
margin-left: calc(calc(50% - calc(var(--widthChild) / 2)));
}

十一、flex + margin

1
2
3
4
5
6
.father {
display: flex;
}
.child {
margin: auto;
}

十二、flex + align-self + margin

1
2
3
4
5
6
7
.father {
display: flex;
}
.child {
align-self: center;
margin: 0 auto;
}

十三、网格 + 伪元素 + margin

1
2
3
4
5
6
7
8
9
10
11
.father {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(3, 1fr);
}
.father::before,.father::after {
content: '';
}
.child {
margin: 0 auto;
}

十四、纯网格

1
2
3
4
5
6
7
8
9
.father {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
}
.child {
grid-row: 2 / span 1; /*也可以使用2/3*/
grid-column: 2 / span 1; /*也可以使用2/3*/
}

十五、网格 + margin

1
2
3
4
5
6
.father {
display: grid;
}
.child {
margin: auto;
}

总结

1.让元素居中的方法,最通用的是采用flex布局
2.知道自身宽高的情况下,可使用margin-leftmargin-top为负值的方法
3.不知道自身元素宽高的情况下,可使用transform: translatetop、bottom、right、left = 0的方法