前言
大家好,这里是藤原豆腐店,实现水平垂直居中是前端面试中经常会问的问题,下面我总结了常见的九种实现方法。
absolute + transform
该方法也适用于子元素是行内元素、行内块元素、块元素,适用性比较广。
实现原理是因为 position: absolute; 和 float 属性会隐式地改变元素的 display 类型(display: none;除外)。只要设置了 position: absolute; 和 float 属性中的一个,都会让元素以 display: inline-block; 的方式出现。
transform的translate属性可以设置百分比,其是相对于自身的宽和高,所以可以将translate设置为-50%,就可以做到居中了
xml
<style>
/* 定位代码 */
.wrap {
width: 400px;
height: 300px;
background-color: lightcoral;
position: relative;
}
.inner {
background-color: lightblue;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="wrap">
<span class="inner"></span>
</div>
只实现垂直居中的话
xml
<style>
/* 定位代码 */
.wrap {
position: relative;
}
.inner {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%);
}
</style>
<div class="wrap">
<span class="inner"></span>
</div>
absolute + margin负值
该方法也适用于子元素是行内元素、行内块元素、块元素,缺点是需要知道子元素的宽高, margin-left和margin-top的值分别负的是宽和高的一半
xml
<style>
.wrap {
width: 400px;
height: 300px;
background-color: lightcoral;
position: relative;//给父元素增加相对定位
}
.inner {
height: 100px;
width: 100px;
position: absolute;;
top: 50%;
left: 50%;
/* 以盒子左上角作为定位 */
/* 设置margin使其偏移 */
margin-left:-50px;
margin-top:-50px;
}
</style>
<div class="wrap">
<span class="inner"></span>
</div>
只设置垂直居中的话
xml
<style>
.wrap {
width: 400px;
height: 300px;
background-color: lightcoral;
position: relative;//给父元素增加相对定位
}
.inner {
height: 100px;
width: 100px;
position: absolute;;
top: 50%;
margin-top:-50px;//高度/2
}
</style>
<div class="wrap">
<span class="inner"></span>
</div>
absolute+calc
原理同上一样,利用calc计算好元素的left和top从而保证了元素的水平垂直居中
该方法也适用于子元素是行内元素,行内块元素,块元素,唯一的要求是子元素的高度和宽度已知
xml
<style>
.wrap{
width: 400px;
height: 300px;
background-color: lightcoral;
position: relative;
}
.inner{
background-color: lightblue;
position: absolute;
top: calc(50% - 40px);
left: calc(50% - 50px);
height: 80px;
width: 100px;
}
</style>
<div class="wrap">
<span class="inner"></span>
</div>
absolute + margin auto
块级元素的特性:能独自占据父级元素一行的,而不是一列。
- 如果不设置块级元素的 width 值,块级元素默认 width: 100%; 在水平方向上会铺满占据父级元素。
- 但是如果不设置 height,块级元素却不会自动占据父级元素的高度
对于块级元素通过margin:auto可以使元素水平方向居中
- 当我们设置了块级元素的宽度和 margin:auto; 表示块级元素除了本身的宽度,水平方向的剩余空间距离父元素左边和右边的 margin 自动分配,也就可以让元素水平居中。
但是在垂直方向上,块级元素不会自动扩充,它的外部尺寸没有自动充满父元素,也没有剩余空间可说。所以margin:auto不能实现垂直居中
- 但是当我们使用了绝对定位 absolute;top: 0; bottom: 0; 的时候,元素在垂直方向有了自动充满父元素的特点。这时使用 margin: auto; 就会告诉浏览器除去元素本身的高度,那么垂直方向上的剩余空间 margin-top 和 margin-bottom 都是 auto 的,也就是平分剩余空间,从而实现元素垂直方向的居中。
该方法也适用于子元素是行内元素、行内块元素、块元素,唯一的要求是子元素要有 高度 和 宽度 。不然子元素会完全填充父元素
xml
<style>
.wrap{
width: 400px;
height: 300px;
background-color: lightcoral;
position: relative;
}
.inner{
background-color: lightblue;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 80px;
width: 100px;
margin: auto;
text-align: center;
}
</style>
<div class="wrap">
<span class="inner">absolute + margin:auto</span>
</div>
line-height
对于行内元素
- 水平居中text-align:center就可以实现
- 垂直居中就是line-height的值与height的值相等即可
xml
<style>
.wrap{
width: 400px;
height: 300px;
line-height: 300px;
text-align: center;
background-color: lightcoral;
}
</style>
<div class="wrap">
<span>行内元素</span>
</div>
对于行内块元素
- 需要借助vertical-align设置为middle
- 同时子元素line-height需要重置为默认值
xml
<style>
.wrap{
width: 400px;
height: 300px;
line-height: 300px;
text-align: center;
background-color: lightcoral;
}
.inner{
height: 200px;
width: 200px;
display: inline-block;
background-color: lightblue;
vertical-align: middle;
font-size: 14px;
line-height: initial;/*将行高重置为默认值*/
}
</style>
<div class="wrap">
<div class="inner">display: inline-block;</div>
</div>
BFC+margin
如果父子元素的高度和宽度都是固定的话,可以直接利用 margin-top 和 margin-left 对子元素进行定位,从而实现居中。
同时利用 position: absolute;,让子元素成为一个 BFC,从而解决父子元素 margin collapsing 的问题。
xml
<style>
.container{
background-color: silver;
width: 400px;
height: 500px;
}
.content{
width: 200px;
height: 300px;
background-color: red;
margin-top: 100px;
margin-left: 100px;
position: absolute;
}
</style>
<body>
<div class="container">
<div class="content"></div>
</div>
</body>
使用flex
flex布局适用于子元素是行内元素、行内块元素、块元素,适用性比较广。
css
.wrap {
display: flex;
justify-content: center;
align-items: center;
}
使用display:table-cell
设置父元素 display:table-cell用于将元素显示为表格单元格
- 设置vertical-align: middle让行内元素或者行内块元素垂直居中
- 设置text-align: center让行内元素或者行内块元素水平居中
xml
<style>
.wrap{
width: 400px;
height: 300px;
background-color: lightcoral;
display: table-cell;
vertical-align: middle;
text-align: center;
}
.inner{
background-color: lightblue;
display: inline-block;
height: 110px;
width: 100px;
}
</style>
<div class="wrap">
<div class="inner">
</div>
</div>
使用grid
grid布局是比flex更强大的布局,通过它也是可以实现水平垂直居中
xml
<style>
.wrap{
display: grid;
justify-items: center;
align-items: center;
width: 400px;
height: 300px;
background-color: lightcoral;
}
.inner{
background-color: lightblue;
height: 110px;
width: 100px;
}
</style>
<div class="wrap">
<div class="inner"></div>
</div>