利用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; --widthChild: 100px; --heightChild: 100px; width: var(--widthChild); height: var(--heightChild); top: calc(50% - calc(var(--widthChild) / 2)); left: calc(50% - calc(var(--heightChild) / 2)); }
|
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; } .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; grid-column: 2 / span 1; }
|
十五、网格 + margin
1 2 3 4 5 6
| .father { display: grid; } .child { margin: auto; }
|
总结
1.让元素居中的方法,最通用的是采用flex
布局
2.知道自身宽高的情况下,可使用margin-left
和margin-top
为负值的方法
3.不知道自身元素宽高的情况下,可使用transform: translate
或top、bottom、right、left = 0
的方法