面试的时候,绝不能只说一种,绝不能说一种解决方案,绝不能停下你结结巴巴的嘴

CSS 方面问的最多的问题之一,我想分三种状况,程度居中、垂直居中和程度垂直居中来剖析

单单就程度垂直居中而言,大略有以下几种计划:

居中元素不定宽高

  • absolute + transform
  • flex 属性居中
  • flex + 子项 margin auto
  • grid 属性居中
  • grid + 子项 margin auto
  • grid + 子项属性居中
  • -webkit-box 属性居中
  • table-cell + text-align
  • line-height + text-align
  • writing-mode
  • table

仅居中元素定宽高实用:

  • 须知宽高 + absolute + 负 margin
  • 须知宽高 + absolute + calc
  • 须知宽高 + absolute + margin auto

局限性较大的全局居中

  • 须知宽高 + fixed + transform
  • 须知宽高 + fixed + 负 margin
  • 须知宽高 + fixed + calc
  • 须知宽高 + fixed + margin auto

程度居中

text-align: center

text-align: center;

需设置 display: inline-block 行内块元素

相对定位 + transform 位移

position: absolute;left: 50%;transform: translateX(-50%);

脱离文档流

宽度+ margin: 0 auto

width: 100px;margin: 0 auto;

这里阐明下,width:100px 必须是具体的数字,且这个居中是外层居中,宽度中的内容没有居中

垂直居中

相对定位 + transform 位移

position: absolute;top: 50%;transform: translateY(-50%);

与程度方向的居中一样,都是脱离文档流的做法

table-cell + vertical-align

display: table-cell;vertical-align: middle;

display: table-cell ,让其标签元素以表格单元格的模式出现,相似于 td 标签,

vertical-align: middle,用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直居中

程度垂直居中

相对居中 + transform 位移

<div class="father">  <div class="son">    123123  </div></div>
.father {  position: relative;}.son {  position: absolute;  left: 50%;  top: 50%;  transform: translate(-50%, -50%);}

flex 属性居中

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: flex;  justify-content: center;  align-items: center;}

flex + margin auto

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: flex;}.son {  margin: auto;}

grid 属性居中

<div class="father">123123</div>// 或者<div class="father">  <div class="son">    123123  </div></div>
.father {  display: grid;  justify-content: center;  align-items: center;}

grid 子项属性居中

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: grid;}.son {  align-self: center;  justify-self: center;}

grid + margin auto

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: grid;}.son {  margin: auto;}

grid 和 flex 很像,是 flex 的升级版,所以 grid 能做的事件更多

以上相对定位、flex、grid 对于程度垂直居中的做法,剩下再说居中比拟老的布局办法

-webkit-box 属性居中

这是一个曾经过期的布局,能够看看这篇文章 CSS3 display: flex 和 display: box 有什么区别?

网友一丝说:

flex 是 2012 年的语法,是当前的规范

box 是 2009 年的语法,曾经过期,须要加上对应前缀

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: -webkit-box;  -webkit-box-pack: center;  -webkit-box-align: center;}

table-cell + text-align

<div class="father">  <div class="son">    123123  </div></div>
.father {  display: table-cell;  vertical-align: middle;  text-align: center;}.son {  display: inline-block;}

line-height + text-align

<div class="father">  <div class="son">    123123  </div></div>
.father {  height: 200px;  line-height: 200px;  text-align: center;}

line-heightheight ,行高和高度一样高,天然就垂直方向居中了

writing-mode

<div class="father">  <div class="“son”">    <div class="“sonson”">      123123    </div>  </div></div>
.father {  writing-mode: tb-lr;  writing-mode: vertical-lr;  text-align: center;}.father .son {  writing-mode: lr-tb;  writing-mode: horizontal-tb;  text-align: center;  width: 100%;  display: inline-block;}.father9 .son .sonson {  display: inline-block;  text-align: initial;}

这个很冷闷,有人介绍过这种状况

table

<table>  <tbody>    <tr>      <td class="father">        <div class="son">          123123        </div>      </td>    </tr>  </tbody></table>
.father {  text-align: center;}

table 标签本人将它垂直居中了,text-align:center 后就是程度居中了

能够看 demo

元素有宽高的状况,又多了三种计划

须知宽高 + 相对居中 + margin 负边距

<div class="father">    <div class="son">        123123    </div></div>
.father {  position: relative;  height: 200px;}.son {  width: 100px;  height: 100px;  position: absolute;  top: 50%;  left: 50%;  margin: -50px 0 0 -50px;}

父元素必须要有个高度,这样能力撑开容器。子元素必须要有个宽高,能力计算出 margin 值

须知宽高 + 相对定位 + calc

<div class="father">  <div class="son">    123123  </div></div>
.father {  position: relative;  height: 200px;}.son {  width: 100px;  height: 100px;  position: absolute;  top: calc(50% - 50px);  left: calc(50% - 50px);}

与 margin 负边距一个情理,父元素须要设置一个高度。子元素必须要有高度,不必 margin,而用 CSS3 中的 calc,计算出要居中位移,兼容性须要反对 CSS3 属性

须知宽高 + 相对居中 + margin: auto

<div class="father">  <div class="son">    123123  </div></div>
.father {  position: relative;  height: 300px;}.son {  width: 100px;  height: 100px;  position: absolute;  top: 0;  left: 0;  right: 0;  bottom: 0;  margin: auto;}

同以上两种状况。

这三种须要定位形式来实现程度垂直居中的办法,须要设置父元素的高度(肯定要有,撑开画面),子元素须要设置宽高,前两种办法是为了算出它在父元素中的绝对地位,后一种办法是为了阐明子元素是个容器(如果不设置宽高,就是无)

其余办法

其实,程度垂直居中方面,如果面试官硬要问还有吗?还真的有,用 fixed 定位。但这个办法有缺点,尽管能实现程度垂直居中,但它是绝对于视口(viewport),而非父元素

办法就是以上用 absolute 实现的改成 fixed 即可

  • 须知宽高 + fixed + transform
  • 须知宽高 + fixed + 负 margin
  • 须知宽高 + fixed + calc
  • 须知宽高 + fixed + margin auto

这四种办法,都须要设置子元素的宽高

这里贴一下代码

<div class="father">  <div class="son">    123123  </div></div>
/* transform */.son {  width: 100px;  height: 100px;  position: fixed;  top: 50%;  left: 50%;  transform: translate(-50%, -50%);  background: blue;}/* 负 margin */.son {  width: 100px;  height: 100px;  position: fixed;  top: 50%;  left: 50%;  margin-left: -50px;  margin-top: -50px;  background: blue;}/* calc */.son {  width: 100px;  height: 100px;  position: fixed;  top: calc(50% - 50px);  left: calc(50% - 50px);  background: blue;}/* margin: auto */.son {  width: 100px;  height: 100px;  position: fixed;  top: 0;  left: 0;  bottom: 0;  right: 0;  margin: auto;  background: blue;}

总结

随着微软发表放弃 IE11,事实我的项目中齐全能够应用 flex 布局,grid 局部还不适配,然而当前必定会取代 flex。

尽管写了很多,然而本人工作中也不会应用 table 、writing-mode、-webkit-box 等过期的布局形式,写这篇文章,纯正是为了面试时被问到这种问题。

播种是 absolute 的居中要父子同心(父元素设置高度,子元素设置宽高),fixed 的居中只须要设置子元素的宽高。

线上 demo 查看

参考资料

  • 如何居中一个元素(终结版)
  • 给你一份具体的 CSS 布局指南,请查收
  • CSS 实现程度垂直居中的 1010 种形式(史上最全)