css居中的10种写法(面试必考

css居中的10种写法(面试必考

十一月 12, 2018

github原文:https://github.com/yanhaijing/vertical-center

博客原文:https://yanhaijing.com/css/2018/01/17/horizontal-vertical-center/

css居中作为Web前端中无可避免的话题,在面试中也是常常出现,可以说是面试必考。
以下是从掘金中一篇文章看到的10种居中方法,可以给大家作为参考
(当然一个没什么人气的博客只是写给自己看的哈哈哈  不过说不定能被搜到呢

目录:

1
2
3
4
<!--公共代码(特殊排版会按具体情况列出)-->
<div class="wp">
<div class="box size">123123</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
/*公共代码*/
.wp {
border: 1px solid red;
width: 300px;
height: 300px;
}
.box {
background: green;
}
.box.size{
width: 100px;
height: 100px;
}

absolute + 负margin

绝对定位的百分比是相对于父元素的宽高,通过这个特性可以让子元素的居中显示,但绝对定位是基于子元素的左上角,期望的效果是子元素的中心居中显示。
为了修正这个问题,可以借助外边距的负值,负的外边距可以让元素向相反方向定位,通过指定子元素的外边距为子元素宽度一半的负值,就可以让子元素居中了,css代码如下

1
2
3
4
5
6
7
8
9
10
.wp {
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
margin-left: -50px;
margin-top: -50px;
}

这个方法较为简单,但必须知道父元素的宽高,所以比较繁琐。

absolute + margin auto

与上一个方法类似,同样是使用绝对定位。其余则是对各方向设为0,然后margin设为auto即可。

1
2
3
4
5
6
7
8
9
10
11
.wp {
position: relative;
}
.box {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

这个方法也是比较简单,同时不用知道父元素的宽高,但每次需要设置各个方向为0,不过这个只要设置一个通用布局就能解决,所以实际上不会太繁琐。

absolute + calc

这个方法是利用了css3的新特性——计算属性,这个方法类似absolute+负margin的方法,但这里不用定父元素的宽高(但要定子元素的),因为用了计算属性可以用百分比和具体数值来做计算。
这里的是用上和左方向的50%减去子元素的一半实现。
(顺便吐槽一下,之前写过一个网站没有发现计算属性这玩意儿,搞得脑阔疼,现在发现了简直豁然开朗发现新大陆啊!!!!

注!!这里有个小坑,calc中间的运算符前后一定一定一定一定要加空格!!!

1
2
3
4
5
6
7
8
.wp {
position: relative;
}
.box {
position: absolute;
top: calc(50% - 50px);
left: calc(50% - 50px);
}

看起来十分高大上的一种方法!也免去了父元素定宽高的尴尬,写起来简洁爆了有木有,但是不能写成通用布局,每次都要写一遍calc也是有点蛋疼。

absolute + transform

哈哈这里还是绝对布局,别介。
这个方法也不用定父元素宽高,也不用定子元素的宽高,这也是用了css3的新特性,不过是另外一个新特性——transform,而这里用的是transfrom的translate属性。
这里介绍一下translate属性,这个属性可以设置百分比,该属性是css3的2d转换属性。个人感觉如果是直接填具体数值的话,有点像margin属性,不知道有没有感觉错;而如果用百分比的话,这个百分比是相对自身的宽高作的百分比,而非父元素的,这里和margin就有了区别。里面的位置参数顺序是左、上
利用自身宽高百分比的原理,我们就容易理解了,top和left设为50%,然后两个参数都填-50%即可。原理也类似absolute+calc的方法,只不过这里连子元素的宽高都不用定了。

1
2
3
4
5
6
7
8
9
.wp {
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

这个方法完美排除定宽高的缺陷(不管是父还是子的),通用性也强,也可以作为通用布局使用,可以说通用性杠杠的了!唯一的不足是这种方法兼容性依赖translate2d的兼容性。

lineheight

这个方法是将子元素设置为行内元素,父元素只要将text-align设为center即可设为水平居中,然后子元素设置vertical-align为middle即可垂直居中。

1
2
3
4
5
6
7
8
9
10
11
12
.wp {
line-height: 300px;
text-align: center;
font-size: 0px;
}
.box {
font-size: 16px;
display: inline-block;
vertical-align: middle;
line-height: initial;
text-align: left; /* 修正文字 */
}

这种方法不太友善的地方是需要在子元素中将文字显示重置为想要的效果。

writing-mode

估计很多人也是一样,在我看到这篇文章的原博文之前,根本没见过writing-mode这个属性,别说是用来干什么的了,一头雾水。
简单来讲,writing-mode这个属性就是可以将父元素中包含的行内元素的显示方向和排列方向,即纵向、横向及从左到右、从右到左,具体详细可以看看css参考手册
而这其中最神奇的是,writing-mode不仅仅会影响显示和排列,甚至会影响到其css的作用方向,如width变成高度,text-align可以从水平居中变成垂直的居中!
值得注意的是,祖父元素的writing-mode会影响到孙元素的排列,因此要在该孙元素的父元素writing-mode属性。

1
2
3
4
5
<div class="wp">
<div class="wp-inner">
<div class="box">123123</div>
</div>
</div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.wp {
writing-mode: vertical-lr;
text-align: center;
}
.wp-inner {
writing-mode: horizontal-tb;
display: inline-block;
text-align: center;
width: 100%;
}
.box {
display: inline-block;
margin: auto;
text-align: left;
}

这种方法较为复杂和繁琐,我也好不容易才理解了这玩意儿,果真实在是不太适合新手啊,酌情使用吧。

table

曾经table被用来做页面布局,现在没人这么做了,但table也能够实现水平垂直居中,但是会增加很多冗余代码。

1
2
3
4
5
6
7
8
9
<table>
<tbody>
<tr>
<td class="wp">
<div class="box">123123</div>
</td>
</tr>
</tbody>
</table>

1
2
3
4
5
6
.wp {
text-align: center;
}
.box {
display: inline-block;
}

这个方法虽然理解起来简单,但就是太麻烦而且太冗余,看起来都蛋疼,而且不算是table的正常用法,实在不太推荐。

css-table

css-table是css中display的的新特性,可以让我们把普通元素,变为table元素的现实效果,通过这个特性也可以实现水平垂直居中。

1
2
3
4
5
6
7
8
.wp {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.box {
display: inline-block;
}

这个方法和table的原理一样,兼容性也ok,最重要的是没那么冗余,相比起table的方法,更推荐这种。

flex

flex作为现代布局方案,颠覆了过去的经验,实现居中也仅需给父元素添加短短几行代码,十分的高大上。

1
2
3
4
5
.wp {
display: flex;
justify-content: center;
align-items: center;
}

目前移动端已经兼容flex布局,高端大气上档次,推荐。

grid

css中display的新特性,grid栅格化布局,实现起来也是十分简易,理解起来也不难。

1
2
3
4
5
6
7
.wp {
display: grid;
}
.box {
align-self: center;
justify-self: center;
}

这个方法使用的grid布局虽然也实现了居中,但是对于兼容性方面来讲就不太ok了,比不了flex布局,所以还是推荐flex的方法多一点,不推荐这个。

总结

下面对比下各个方式的优缺点,肯定又双叒叕该有同学说回字的写法了,简单总结下:

  • PC端有兼容性要求,宽高固定,推荐absolute + 负margin
  • PC端有兼容要求,宽高不固定,推荐css-table
  • PC端无兼容性要求,推荐flex
  • 移动端推荐使用flex
    小贴士:关于flex的兼容性决方案,请看这里《移动端flex布局实战
方法 居中元素定宽高固定 PC兼容性 移动端兼容性
absolute + 负margin ie6+, chrome4+, firefox2+ 安卓2.3+, iOS6+
absolute + margin auto ie6+, chrome4+, firefox2+ 安卓2.3+, iOS6+
absolute + calc ie9+, chrome19+, firefox4+ 安卓4.4+, iOS6+
absolute + transform ie9+, chrome4+, firefox3.5+ 安卓3+, iOS6+
writing-mode ie6+, chrome4+, firefox3.5+ 安卓2.3+, iOS5.1+
lineheight ie6+, chrome4+, firefox2+ 安卓2.3+, iOS6+
table ie6+, chrome4+, firefox2+ 安卓2.3+, iOS6+
css-table ie8+, chrome4+, firefox2+ 安卓2.3+, iOS6+
flex ie10+, chrome4+, firefox2+ 安卓2.3+, iOS6+
grid ie10+, chrome57+, firefox52+ 安卓6+, iOS10.3+

另出个小题目:

1
2
<div class="red blue">123</div>
<div class="blue red">123</div>
1
2
3
4
5
6
.red {
color: red
}
.blue {
color: blue
}

实例答案点这里
答错的童鞋请自动去补一补css基础知识。
问两个div的颜色分别是什么,竟然只有40%的同学能够答对,这40%中还有很多同学不知道为什么,希望这些同学好好补习下CSS基础,下面给大家推荐几本CSS的书籍:

  • CSS设计指南(最好的入门书)
  • 图解CSS3(最好的CSS3入门)
  • CSS世界(CSS进阶)
  • CSS揭秘(CSS高手)
    喜欢看网络资料同学,可以看看MDN的这个CSS入门教程,强烈推荐,英语好的同学建议看英文版。
    不说了,其实cv了大半篇,这小题目我都答错了(捂脸,我要去补一补css基础知识了!!!!