CSS之水平和垂直居中的方法总结

做为一个前端,一个专业的前端,基础是决定你打造自己帝国大厦的根基。本篇系统总结一下CSS水平和垂直居中的方法。在页面样式开发过程中会经常遇到。

你可以首先了解一下块级元素(block element)和内联元素(inline element)。传送门

水平居中

常用的方法大约有以下4种

使用 text-aligh:center

1
2
3
4
5
6
7
8
<body style="text-align: center">
<div >
gg
</div>
<span>
fsdf
</span>
</body>

不管是块级元素(block element)还是内联元素(inline element),只要父标签有text-align: center样式,会自动居中。

使用 margin: 0 auto 与 width: 0px

1
2
3
4
5
6
7
8
9
10
<body>
<div style="margin: 0 auto;width: 1px">
JX
<span>jacks</span>
</div>
<span style="margin: 0 auto;width: 70px;display: block">
JX
<span>jacks</span>
</span>
</body>

我分别在块级元素内联元素上都加了这样的样式,只要在内联元素上加上display:block,就和块级元素是等同的效果。我这里设置了不同的宽度,看有什么影响。第一个div宽度只有1px,那么在div里面不同的元素内容超过这个,就会自动换行,可以实现同块级居中内联元素换行;第二种只要span宽度足够宽,里面的内联元素内容不超过这个宽度,就按顺序排列不会换行,可以实现同块级居中内联元素不换行,是不是挺好玩的。

上面两种方法看似效果一样,其实差别是很大的,第一种 text-aligh:center是div占据一行的空间是不会改变的,而是内容居中了,可能有点类似于padding:50%;第二种是div宽度变成了1px,两外边边缘距离(margin)自适应了,标签居中了,内容按顺序排列。所以你是想标签居中,还是标签的内容居中,是可以做出不同选择的。

使用相对定位与边距调整

这种方法,一般需要程序员事先做好相对位置计算,进行细微调整即可。当然你也可以使用position:absolute;绝对定位,它是相对页面窗口,相对来多比较死板,不够灵活,如果你需要的效果就是定死在窗口某个地方,也可以使用该属性,为了更灵活满足页面的交互性,推荐使用相对定位来实现。

1
2
3
4
5
6
7
8
9
10
<body>
<div style="position: relative;left: 50%">
JX
<span>jacks</span>
</div>
<span style="position: relative;right: 50%">
JX
<span>jacks</span>
</span>
</body>

left:百分比需要一个相对参照物,直接使用,没有任何效果,所以给div一个position: relative;的属性。参照物是父元素。有人说用left:50%;是不是也可以用right:50%。如果你的元素的正常起始位置是在最右边,就是可以的。怎么解释呢?
position: relative;也可以理解为目前元素不加任何样式初始位置做出相对位置改变,我们知道页面排版都是从最左边依次向右边排列,从上外下换行;那么第一个元素就是网页最左上角,相对位置的right:50%就到屏幕的左外面去了,就看不到了;当然一个元素的位置会受到父元素样式影响调整,所以为什么又说是相对父元素。被父元素调整到右上角,right:50%就对了。另外补充一句,left和right的移动,并不是像前面的调整内容位置填充内外边距,而是移动了‘画布’位置。具体讲解可以参考CSS之position位置总结

以上的方法已经完全可以兼容所有浏览器了,也不存在CSS hack问题。传送门

自适应居中

这里只讲到居中自适应,因为自适应的内容不只是居中,对不同大小的屏幕,自适应的排版这里不做详细说明。
思路是做一个弹性布局,当一个元素处于一个容器中时我们只想让它居中并不设定一个具体的宽度。这样的设计可以使用元素属性margin来设置的,实际中是改变了父元素内的容器大小,相当于空间被压缩了(外边距);padding属性也是可以实现的,实际中是改变了容器内元素距离父元素距离(内边距),相当与把元素排斥(或者推向)靠内。

1
2
3
4
5
6
7
8
9
10
<body style="padding: 0px 10%;text-align: center">
<div>
JX
<span>jacks</span>
</div>
<span>
JX
<span>jacks</span>
</span>
</body>

我们只要padding:0px 50%就可以把容器内元素左右排斥到中间,有趣的是超过50%会把容器撑大,能想像到吧。但是在实际排版时候,容器包裹着内容,我们把内容居中即可,当窗口大小变动的时候,容器大小会按比例自适应,然后内容再居中在变化后的容器中间。

注意理解内容居中标签容器居中的概念

垂直居中

这里总结出6种方法,根据实际情况筛选

使用line-height

1
2
3
4
5
6
7
8
9
10
11
<body style="line-height: 100px">
<div>
JX
<span>jacks</span>
<div>我会受影响</div>
</div>
<span>
JX
<span>jacks</span>
</span>
</body>

body中每个子节点,都会获取上下高度为100px的属性,内容再垂直居中,这里注意的是span是内联元素,长宽只会受到内容多少的影响,并不会被width或者height属性影响。最后建议加上overflow: hidden;属性

优点是:

  1. 对内联元素和块级元素都适用
  2. 兼容所有第五代的浏览器,兼容高

缺点:

  1. 会影响所有单独一行的块级元素(从上面例子可以看出)
  2. 内容有限只能一行垂直居中
  3. 对非文字,例如图片和对象,支持太不友好

使用padding: 24px 0

1
2
3
4
5
6
7
8
9
10
<body style="padding: 24px 0">
<div>
JX
<span>jacks</span>
</div>
<span>
JX
<span>jacks</span>
</span>
</body>

有一定基础的人会知道padding:24px 0其实是和padding:24px 0 24px 0等价的,就是上下两个内边距离24px。犹豫是调整的容器边距去垂直居中,就不会存在,内容只限制一行这种局限了。

优点是:

  1. 对内联元素和块级元素都适用
  2. 兼容所有第五代的浏览器,兼容高
  3. 对多行内容友好支持,例如图片垂直居中

缺点:

  1. 当设置高度的时候,容器是居中了,但是容器中的内容依然会在在容器的左上角,所以可能需要去掉这个高度,让其自适应内容的高度。

模拟表布局容器固定高度

有三个核心属性代码display: table-cell;vertical-align: middle;height: num px

1
2
3
4
5
6
7
8
9
10
<body style="display: table-cell;vertical-align: middle;height: 100px">
<div>
JX
<span>jacks</span>
</div>
<span>
JX
<span>jacks</span>
</span>
</body>

容器高度需要超过内容高度,超过的部分,即为上下偏离居中的距离。

优点是:

  1. 能很完美的呈现垂直居中

缺点:

  1. 它只适用于ie7以上(不包括ie7)浏览器的最新版本,如Mozilla,Firefox,Netscape 8,Opera和Safari和Chrome

利用vertical-align:middle

可以实现一行多列,不同高度元素自动居中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<style>
ul{
display:table;
margin:0;
padding:0;
list-style-type:none;
height:100px;
border:1px solid;
}
li{
display:table-cell;
vertical-align:middle;
}
</style>
<div class="a">
<ul>
<li>
<p style="
width:20px;
height:20px;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
background-color: #3d98e9;">
</p>
</li>
<li>
<div style="
width:20px;
height:20px;
-webkit-border-radius: 50px;
-moz-border-radius: 50px;
border-radius: 50px;
background-color: #3d98e9;">
</div>
</li>
<li>121</li>
<li>212</li>
<li>212</li>
<li>1212</li>
</ul>
</div>

以上还可以利用多个ul可以实现多行多列

使用相对定位

1
2
3
4
5
6
7
8
9
10
<body>
<div style="position:relative;top: 50%">
JX
<span>jacks</span>
</div>
<span style="position:relative;top: 50%;display: block">
JX
<span>jacks</span>
</span>
</body>

使用相对位置,和我们之前讲过的水平居中的原理是一样的,同样不推荐使用绝对定位。同样记住内联元素需要转块级元素

使用绝对定位

1
2
3
4
5
6
7
8
9
10
<body style="position:relative;left:50%">
<div style="position:absolute;top: 50%">
JX
<span>jacks</span>
</div>
<span style="position:absolute;top: 50%;display: block">
JX
<span>jacks</span>
</span>
</body>

如果硬要使用绝对定位,为了尽可能避免布局混乱,在其父元素上加上position:relative;,这是因为绝对定位会去寻找父元素是否为相对定位,若是那么绝对定位是会跟随其父元素的位置的。如上,很简单就同时实现了水平和垂直居中。值得注意的是绝对定位会覆盖,所以div和span 内容重合了。

以上两种皆有以下优缺点。
优点是:

  1. 灵活易用

缺点是:

  1. 在ie环境下有兼容问题,不能单独依靠相对位置来实现,有些ie版本可以,有些不支持,还有些只支持一部分,不多说了微软都放弃ie了

浮动“幽灵”填充法

多一个div填充物,来把你需要的内容推倒居中位置,也适用与水平居中(不觉得太麻烦和多余吗),这种做会多用一个div,无意义的透明填充物,数量多了后,会多多少少影响我的整体布局,你甚至会觉得没有结构化,而且需要你去计算内容的高度,操作不当,甚至会毁了你的原有布局,毕竟它是浮动的“幽灵”。建议少用。

1
2
3
4
5
6
7
8
9
10
11
<body >
<div style="float: left;height: 50%;width: 100%;margin-bottom: -40px;"></div>
<div style="clear: both;">
JX
<span>jacks</span>
</div>
<span style="clear: both;">
JX
<span>jacks</span>
</span>
</body>

关键有两点,第一点是浮动填充,第二点是margin-bottom: -Num px;,当透明填充物,下边界在居中位置时候,我们只需要把后面的内容缩进浮动块边缘上就居中了。

优点是

  1. 非常灵活,你可以随意调整

缺点是

  1. 需要计数内容高度
  2. 浮动布局,容易影响页面

自适应压缩法

这是一种很经典的方法,利用了margin:auto属性的特点,内联元素块级元素都适用。很适合用来做广告,活动,甚至图片等,显示在屏幕正中间的弹出层

1
2
3
4
5
6
7
8
9
10
<body style="position:relative;">
<div style="position:absolute;top: 0;bottom: 0;left: 0;right: 0;width: 0;height: 0;margin: auto">
JX
<span>jacks</span>
</div>
<span style="position:absolute;top: 0;bottom: 0;left: 0;right: 0;width: 0;height: 0;margin: auto">
JX
<span>jacks</span>
</span>
</body>

从代码中我们可以看到,我们设定了一个屏幕边界容积它会根据widthheight的大小来自动压缩容器大小。当然为0,内容起始位置就是屏幕的正中间。如有长宽,就是居中容器的左上角。这一点文中有多次,强调到。

当你看完这里,再加以融汇贯通,基本上可以应对所有的居中情况了。

0%