居中问题(二) -- 垂直居中

1 行内元素内容居中

1
2
3
4
5
6
7
8
9
10
11
12
13
<style>
html,body {
margin: 0;
padding: 0;
}
span{
padding: 5px 8px;
float: left;
background: plum;
}
</style>

<span>请叫我小仙女</span>

说明:大多数行内元素不能设置宽高,只能由内容撑起,而若要实现上下左右有空隙则需设置padding,但是行内元素的padding只对左、右、下起作用,margin只对左、右起作用,所以对于行内元素若想让上述属性起作用,则需设置浮动或定位,而若要垂直方向居中则设置padding-top=padding-bottom即可

优点:简单、常用,可同时实现水平垂直居中,兼容性好
缺点:需要设置浮动或定位来辅助实现

2 块级元素中的行内元素或类行内元素居中

2.1 line-height

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap{
width: 200px;
height: 200px;
line-height: 200px;
background: paleturquoise;
}
span {
background: plum;
}
</style>

<div class="wrap">
<span>请叫我小仙女</span>
<img src="images/eg_cute.gif" alt="">
</div>

说明:外盒子设置line-height=height即可

优点:简单、常用,兼容性好
缺点:若需要居中的内容为多行则不适用

2.2 vertical-align

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap{
width: 200px;
height: 200px;
display: table-cell;
vertical-align: middle;
background: paleturquoise;
}
span {
background: plum;
}
</style>
</head>

<body>
<div class="wrap">
<span>请叫我小仙女请叫我小仙女请叫我小仙女</span>
</div>

说明:在没有其它属性辅助的情况下,只有table-cell属性的元素才可以使用vertical-align属性

优点:可同时适用于单行和多行内容
缺点:实现条件苛刻

2.3 flex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap{
width: 200px;
height: 200px;
display: flex;
align-items: center;
background: paleturquoise;
}
span {
background: plum;
}
</style>

<div class="wrap">
<span>请叫我小仙女小仙女小仙女小仙女</span>
</div>

优点:可同时适用于单行和多行内容
缺点:CSS3新属性,兼容性差

3 块级元素

3.1 margin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
border: 1px solid transparent;
background: paleturquoise;
}
.in {
height: 100px;
margin-top: 50px;
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

说明:.in的margin-top值为(.wrap的高度-.in的高度)/2;值得注意的是我在.wrap上添加了一个border: 1px solid transparent;属性,目的是为了解决边距重叠问题,关于边距重叠问题,我后续也会专门写一篇博客来详细介绍,有兴趣的小伙伴可以继续关注哦!

优点:最简单的实现方式,兼容各种浏览器
缺点:可扩展性低,内盒子的高度必须固定,且每当改变内外盒子的高度,margin-top的值都要重新计算

3.2 定位position

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
position: relative;
background: paleturquoise;
}
.in {
height: 100px;
position: absolute;
top: 50%;
margin-top: -50px;
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

优点:最常用的实现方式,兼容性好,可以在此基础上以同样方法添加left和margin-left实现水平垂直居中
缺点:内盒子的高度必须固定

3.3 定位position结合transform

3.3.1 absolute–transform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
position: relative;
background: paleturquoise;
}
.in {
/* height: 100px; */
position: absolute;
top: 50%;
transform: translateY(-50%);
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

注:transform方法,当计算结果含小数位时,会导致整个元素变模糊,解决方案是父级元素设置transform-style:preserve-3d;
优点:弥补了3.2中的缺点,内盒子高度可以不固定,当内盒子高度固定时,translateY()括号中的值为负的内盒子高的二分之一即可,即相当于3.2中的margin-top,而不论内盒子高度是否固定,translateY()括号中的值都可以是-50%
缺点:transform是CSS3的新属性,所以兼容性比较差

3.3.2 relative–transform

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
background: paleturquoise;
}
.in {
height: 100px;
position: relative;
top: 50%;
transform: translateY(-50%);
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

说明:这个方法与3.3.1极相似,不同之处在于,此法外盒子不定位,直接给内盒子采取相对定位relative,但一般不会这样使用,都是采用上面那种方法
注:transform方法,当计算结果含小数位时,会导致整个元素变模糊,解决方案是父级元素设置transform-style:preserve-3d;

3.4 :before结合inline-block结合vertical-align

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
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap{
width: 200px;
height: 200px;
background: paleturquoise;
}
.wrap::before{
content:"";
display:inline-block;
height:100%;
vertical-align:middle;
}

.in {
display: inline-block;
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

缺点:实现起来比较麻烦,所以很少用

3.5 flex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
display: flex;
align-items: center;
background: paleturquoise;
}
.in {
/* height: 100px; */
background: peachpuff;
}
</style>

<div class="wrap">
<div class="in">请叫我小仙女</div>
</div>

说明:align-items:center;意为交叉轴方向对齐方式:居中。主轴方向flex-direction默认为row即横向,则交叉轴即为纵向,也就是垂直方向
关于flex可以参考我的博客

优点:实现简单,内盒子高度无须固定
缺点:flex为CSS3新属性,兼容性差,且flex内的元素float、clear、vertical-align等样式全部失效

3.6 增加节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
background: paleturquoise;
}
.hide{
height: 50px;
}
.in {
height: 100px;
background: peachpuff;
}
</style>

<div class="wrap">
<div class="hide"></div>
<div class="in">请叫我小仙女</div>
</div>

说明:在内盒子前添加一个元素,并且设置高度为内外盒子高度差的二分之一,宽度默认100%即可,其实这种方法跟3.1原理是相同的,此处.hide的位置即为3.1中margin-top所占据的位置

优点:请原谅我从宏观上看并没有发现此方法的优点,但不代表这种方法没有用,或许在某些复杂或奇怪的页面结构中,其它方法都不适用,只能采用这种方法呢
缺点:需要增加元素节点,且内盒子高度必须固定

4 总结

关于垂直居中的方法就总结到这里了,如果小伙伴们还有其它方法,或者在具体的实践中遇到任何问题,都欢迎大家在评论区积极讨论,我也会一直关注的哦✌

坚持原创技术分享,您的支持将鼓励我继续创作!