前言
让一个元素水平垂直居中在实际开发中经常遇到,在面试中也基本算是必考题,下面介绍几个常用的方法。
方法一:Flex
Flex 布局是目前非常常用的一种布局方式,使用它实现水平垂直居中是最常见也最容易理解的。代码如下:
<main id="outer-1">
<div id="inner-1">inner</div>
</main>
#outer-1 {
width: 120px;
height: 80px;
background-color: lightcyan;
display: flex;
justify-content: center; /* 关键代码 */
align-items: center; /* 关键代码 */
}
#inner-1 {
background-color: lightskyblue;
}
方法二:Grid
Grid 布局是 CSS 3 新推出的一种非常强大的布局方式,但许多人担心它的兼容性,不过不用过于担心,大部分主流现代浏览器,包括最新版本的 Chrome、Firefox、Edge、Safari 等,都已经完全支持 Grid 布局。
<main id="outer-2">
<div id="inner-2">inner</div>
</main
#outer-2 {
width: 120px;
height: 80px;
background-color: lightcyan;
display: grid;
place-items: center; /* 关键代码 */
}
#inner-2 {
background-color: lightskyblue;
}
方法三:绝对定位配合 translate 位移
先将元素定位到父元素上下左右 50% 的位置,也就是中心点的位置,但子元素本身不在中心点,所以需要进行位移,位移自身的宽高的一半即可。
<main id="outer-3">
<div id="inner-3">inner</div>
</main>
#outer-3 {
width: 120px;
height: 80px;
background-color: lightcyan;
position: relative; /* 关键代码 */
}
#inner-3 {
background-color: lightskyblue;
position: absolute; /* 关键代码 */
top: 50%; /* 关键代码 */
left: 50%; /* 关键代码 */
transform: translate(-50%, -50%); /* 关键代码 */
}
方法四:绝对定位配合自动 margin
此方法需要子元素确定宽高,不然会将父元素铺满。确定宽高后,将四个方向都设置为 0 ,margin 设置为 auto 即可实现。虽然代码较多,但也比较容易理解。也是比较常见的方式。
<main id="outer-4">
<div id="inner-4">inner</div>
</main
#outer-4 {
width: 120px;
height: 80px;
background-color: lightcyan;
position: relative;
}
#inner-4 {
background-color: lightskyblue;
width: 60px; /* 子元素需要确定宽高 */
height: 40px;
position: absolute; /* 关键代码 */
top: 0; /* 关键代码 */
right: 0; /* 关键代码 */
bottom: 0; /* 关键代码 */
left: 0; /* 关键代码 */
margin: auto; /* 关键代码 */
}
方法五:绝对定位配合 margin 位移
此方法原理和方法三类似(先将元素定位到父元素中心点的位置,然后位移自身的宽高的一半即可),但由于 margin 无法计算自身的宽高,所以需要子元素确定宽高才能进行位移。
<main id="outer-5">
<div id="inner-5">inner</div>
</main>
#outer-5 {
width: 120px;
height: 80px;
background-color: lightcyan;
position: relative;
}
#inner-5 {
background-color: lightskyblue;
width: 60px; /* 子元素需要确定宽高 */
height: 40px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -20px; /* 减去自身高度的一半 */
margin-left: -30px; /* 减去自身宽度的一半 */
}
方法六:绝对定位
此方法和方法五思想一致。只不过是在定位到父元素中心点的同时减去自身宽高的一半实现水平垂直居中。
<main id="outer-6">
<div id="inner-6">inner</div>
</main>
#outer-6 {
width: 120px;
height: 80px;
background-color: lightcyan;
position: relative;
}
#inner-6 {
width: 60px; /* 子元素需要确定宽高 */
height: 40px;
position: absolute;
top: calc(50% - 20px); /* 减去自身高度的一半 */
left: calc(50% - 30px); /* 减去自身宽度的一半 */
background-color: lightskyblue;
}
方法七:子元素变为行内元素,使用文本的方式进行居中
⚠ 此方法有兼容性问题。
原理很简单,先将子元素变为行内元素,然后利用 text-align 和 line-height 实现子元素的居中。但由于 html 各版本的标准不同,浏览器对此方法的实现也有所不同,此方法仅在 HTML5 下才能生效。所以 html 头部需要添加 <!DOCTYPE html> 标签。
<main id="outer-7">
<div id="inner-7">inner</div>
</main>
#outer-7 {
width: 120px;
height: 80px;
background-color: lightcyan;
text-align: center;
line-height: 80px; /* 与高度同高 */
font-size: 0px;
}
#inner-7 {
background-color: lightskyblue;
display: inline-block;
font-size: 16px;
line-height: initial;
vertical-align: middle;
}
方法八:利用表格
⚠ 此方法在 flex 和 grid 布局下无效。
原理和方法七类似。万能的 CSS 可以直接将元素改变为单元格而无需使用 table 标签,然后再使用文本的方式进行居中即可。
<main id="outer-8">
<div id="inner-8">inner</div>
</main>
#outer-8 {
width: 120px;
height: 80px;
background-color: lightcyan;
display: table-cell; /* 关键代码 */
vertical-align: middle; /* 关键代码 */
text-align: center; /* 关键代码 */
}
#inner-8 {
background-color: lightskyblue;
display: inline-block; /* 关键代码 */
}
最后
其实网上还有一些神通广大的网友的方法能够实现,但由于代码量的问题或者副作用的问题较多,就不再赘述,本文介绍的以上几种方法按照顺序依次推荐。
参考文档: