面试的时候,绝不能只说一种,绝不能说一种解决方案,绝不能停下你结结巴巴的嘴
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-height
与 height
,行高和高度一样高,天然就垂直方向居中了
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 种形式(史上最全)