方法 | 居中元素定宽高固定 |
---|---|
absolute + 负margin | 是 |
absolute + margin auto | 是 |
absolute + calc | 是 |
absolute + transform | no |
writing-mode | no |
lineheight | no |
table | no |
css-table | no |
flex | no |
grid | no |
公共代码
/* 公共代码 */
.parent{
border: 1px solid red;
width: 400px;
height: 400px;
}
.child{
background: green;
}
.child.size{
width: 200px;
height: 200px;
}
/* 公共代码 */
absolute + 负margin
绝对定位的百分比是相对于父元素的宽高,通过这个特性可以让子元素的居中显示,但是绝对定位是基于子元素的左上角,期望的效果是子元素的中心居中显示,
为了解决这个问题,可以借助外边距的负值,负的外边距可以让元素向相反方向定位,通过指定子元素的外边距为子元素宽度一半的负值,就可以让子元素居中了,代码如下:
HTML代码
<div class="parent">
<div class="child size">hhhhh</div>
</div>
/* 引用公共代码 */
/* 定位代码 */
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
left: 50%;
margin-left: -100px;
margin-top: -100px;
}
缺点是需要知道子元素的宽高
absolute + margin auto
这种方式要求居中元素的宽高固定
这种方式通过设置各个方向的距离都是0,此时再将margin设置为auto,就可以各个方向上居中
HTML代码
<div class="parent">
<div class="child size">hhhhh</div>
</div>
CSS代码如下:
/* 引用公共代码 */
/* 定位代码 */
.parent{
position: relative;
}
.child{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
缺点: 需要知道子元素的宽高
absolute + calc
CSS3有了计算属性,top的百分比是基于元素的左上角,那么再减去宽度的一半就好了,
HTML代码
<div class="parent">
<div class="child size">hhhhh</div>
</div>
CSS代码如下:
/* 引用公共代码 */
/* 定位代码 */
.parent{
position: relative;
}
.child{
position: absolute;
top: calc(50% - 100px);
left: calc(50% - 100px);
}
依赖calc的兼容性,缺点是需要知道子元素的宽高
<span id="at"></span>
absolute + transform
还是绝对定位,但不需要子元素固定宽高,所以不需要size类
HTML:
<div class="parent">
<div class="child">hhh</div>
</div>
修复绝对定位的问题,可以使用css3新增的transform,transform的translate属性可以设置百分比,相对于自身的宽和高,讲translate设置为50%,就可以居中了
CSS:
.parent{
position: relative;
}
.child{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
writing-mode
writing-mode可以改变文字的显示方向,
HTML:
<div class="child1">水平方向</div>
<div class="child2">垂直方向</div>
CSS:
.child2{
writing-mode: vertical-lr;
}
显示效果:
水平方向
垂
直
方
向
所有水平方向上的CSS属性,都会变为垂直向上的属性,比如==text-align==,通过==writing-mode==和==text-align==就可以做到水平和垂直方向居中
HTML:
<div class="parent">'
<div class="parent-inner">
<div class="child">hhhh</div>
</div>
</div>
CSS:
.parent{
writing-mode: vertical-lr;
text-align: center;
}
.parent-inner{
writing-mode: horizontal-tb;
display: inline-block;
text-align: center;
width: 100%;
}
.child{
display: inline-block;
margin: auto;
text-align: left;
}
lineheight
利用行内元素居中属性可以做到水平垂直居中,
HTML:
<div class="parent">
<div class="child">hhhhh</div>
</div>
把child设置为行内元素,通过==text-align==就可以做到水平居中,还可以通过==vertical-align==在垂直方向做到居中
CSS:
.parent{
line-height: 400px;
text-align: center;
font-size: 0px;
}
.child{
font-size: 16px;
display: inline-block;]
vertical-align: middle;
line-height: initial;
text-align: left;
}
table
table DEMO
table也能实现水平垂直居中,但会增加很多冗余代码
HTML:
<table>
<tbody>
<tr>
<td class="parent">
<div class="child">hhhhh</div>
</td>
</tr>
</tbody>
</table>
CSS:
.parent{
text-align: center;
}
.child{
display: inline-block;
}
代码太冗余,而且不是table的正确用法
css-table
css新增的table属性,可以让我们把普通元素,变为table元素的显示效果,通过这个特性也可以实现水平垂直居中
HTML:
<div class="parent">
<div class="child">hhhhhh</div>
</div>
通过CSS属性,可以让div显示得和table一样
CSS:
.parent{
display: table-cell;
text-align: center;
vertical-align: middle;
}
.child{
display: inline-block;
}
flex
flex一个现代的布局方案,几行代码就可以水平垂直居中了
HTML:
<div class="parent">
<div class="child">hhhhhh</div>
</div>
CSS:
.parent{
display: flex;
justify-content: center;
align-items: center;
}
grid
css新出的网格布局,直接上代码,
HTML:
<div class="parent">
<div class="child">hhhhhh</div>
</div>
CSS:
.parent{
display: grid;
}
.child{
align-self: center;
justify-self: center;
}
总结
- PC端有兼容性要求,宽高固定,推荐absolute + 负margin
- PC端有兼容要求,宽高不固定,推荐css-table
- PC端无兼容性要求,推荐flex
- 移动端推荐使用flex