这是一道面试必考题!

这是一道面试必考题! 这是一道面试必考题!

最要的事情说三遍!

其实网上已经有了很多的该题教程,在这里只是想做个汇总,并且会将所有demo放在github上供大家直接使用,欢迎star

固定宽高的三种:

  • absolute + 负margin
  • absolute + margin auto
  • absolute + calc

自适应的七种:

  • absolute + transform
  • lineheight
  • writing-mode
  • table
  • css-table
  • flex
  • grid

10种实现方式预览,请点击

固定宽高

absolute + 负margin

实现原理:先absolute设置50%,然后负margin元素本身的一半宽高。

.demo {
position: relative;
}
.vc1 {
width:200px;
height:200px;
background-color: red;
position: absolute;
top:50%;
left:50%;
margin-top:-100px;
margin-left:-100px;
}

<div class="demo">
<div class="vc1"></div>
</div>

absolute + margin auto

实现原理:先absolute四个方向设置为0,然后设置margin为auto。

.demo {
position: relative;
}
.vc2 {
width:200px;
height:200px;
background-color: red;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

<div class="demo">
<div class="vc2"></div>
</div>

absolute + calc

实现原理:先absolute,然后top/left的值通过计算属性calc设置(50%-宽高/2)。

.demo {
position: relative;
}
.vc3 {
width:200px;
height:200px;
background-color: red;
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}

<div class="demo">
<div class="vc3"></div>
</div>

自适应

absolute + transform

实现原理:先absolute,然后top/left设置为50%,再利用translate位移拉回自身宽高的50%。

.demo {
position: relative;
}
.vc4 {
background-color: blue;
position: absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}

<div class="demo">
<div class="vc4"></div>
</div>

lineheight

实现原理:外层设置行高并且text-align为center,内层inline-block后,继承行高。

.demo5 {
width:100%;
height: 500px;
border:1px solid #ccc;
box-sizing: border-box;
color: #fff;
line-height: 500px;
text-align: center;
}
.vc5 {
display: inline-block;
background-color: blue;
vertical-align: middle;
line-height: initial;
text-align: left;
}

<div class="demo5">
<div class="vc5">lineheight</div>
</div>

writing-mode

实现原理:要分三层处理。第一层writing-mode为vertical-lr,文字竖放后居中做到垂直居中,第二层用horizontal-tb将文字转换回来,层级设置inline-block实现水平居中,最后一层inline-block且文字left。

.demo6 {
width:100%;
height: 500px;
border:1px solid #ccc;
box-sizing: border-box;
color: #fff;
writing-mode: vertical-lr;
text-align: center;
}
.demo6-inner {
writing-mode: horizontal-tb;
display: inline-block;
width: 100%;
}
.vc6 {
background-color: blue;
display: inline-block;
text-align: left;
}

<div class="demo6">
<div class="demo6-inner">
<div class="vc6">writing-mode</div>
</div>
</div>

table

实现原理:古老的table布局,利用td本身特性进行垂直居中。

.demo7 {
width:100%;
height: 500px;
border:1px solid #ccc;
box-sizing: border-box;
color: #fff;
text-align: center;
}
.vc7 {
display: inline-block;
background-color: blue;
}

<table cellpadding="0" cellspacing="0" class="demo7">
<tbody>
<tr>
<td>
<div class="vc7">table</div>
</td>
</tr>
</tbody>
</table>

css-table

实现原理:利用css的方式,将div的display转成table-cell,就可以模拟td的特性,(最外层style只是为了设置外层宽度方便查看可忽略)

.demo8 {
height: 500px;
border:1px solid #ccc;
color: #fff;
box-sizing: border-box;
display: table-cell;
text-align: center;
vertical-align: middle;
}
.vc8 {
display: inline-block;
background-color: blue;
}

<div style="display:table;width: 100%">
<div class="demo8">
<div class="vc8">css-table</div>
</div>
</div>

flex

实现原理:css3经典的flew布局。

.demo9 {
width:100%;
height: 500px;
border:1px solid #ccc;
box-sizing: border-box;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.vc9 {
background-color: blue;
}

<div class="demo9">
<div class="vc9">flex</div>
</div>

grid

实现原理:比较不常用的grid布局,可以通过子层的align-self和justify-self来做到垂直居中。

.demo10 {
width:100%;
height: 500px;
border:1px solid #ccc;
box-sizing: border-box;
color: #fff;
display: grid;
}
.vc10 {
align-self: center;
justify-self: center;
background-color: blue;
}

<div class="demo10">
<div class="vc10">grid</div>
</div>

此文原创,附上的BLOG和Github,欢迎star


推荐阅读:
相关文章