display:inline-block
声明display:inline-block将其变成行内块级元素,那么可用text-align和line-height声明水平垂直居中了,但是行内块级元素与匿名行内盒的基线对齐存在很大差异,所以需声明vertical-align:middle将其调整到垂直居中的位置,不过这也是近似垂直居中,父节点最后还需声明font-size:0消除该差异
.center-layout {
line-height: 400px;
text-align: center;
font-size: 0;
div {
display: inline-block;
vertical-align: middle;
}
}
display:table-cell
父节点声明display:table-cell模拟表格布局的垂直居中;子节点声明margin:0 auto使其水平居中
.center-layout {
display: table-cell;
vertical-align: middle;
div {
margin: 0 auto;
}
}
position
该方式也是最传统最稳定的水平垂直居中布局了,唯二的缺点就是声明属性稍多和必须已知宽高。要点是使用margin负值将节点拉回最中间,所以必须已知宽高才能计算margin负值,通常是margin-left和margin-top,可连写成margin:-(height/2) 0 0 -(width/2)
.center-layout {
position: relative;
div {
position: absolute;
left: 50%;
top: 50%;
margin: -50px 0 0 -50px;
}
}
自从CSS3的transform普及后,声明transform:translate(-50%,-50%)可代替margin负值了,这样就无需声明宽高和计算宽高的二分之一是多少,真正做到自适应水平垂直居中。
但是存在一个缺陷,若节点需额外使用transform,那么就比较麻烦了。将额外的transform合并到水平垂直居中的transform:translate(-50%,-50%)里,就会存在有一个比较棘手的变换顺序问题,在第12章变换与动画中会详细讲解。解决方式就是在节点外部套上一层
,把transform:translate(-50%,-50%)转嫁到
上,那么节点就能自由使用transform了
.center-layout {
position: relative;
div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
flex
.center-layout {
display: flex;
justify-content: center;
align-items: center;
}
当然还有一个隐藏的终极方式,也是史上最简方式。只需声明两个重要属性
.center-layout {
display: flex;
div {
margin: auto;
}
}