居中问题(三) -- 水平垂直居中

鉴于实际需求,这里只列举了块级元素内的块级元素水平垂直居中,如果你想要实现块级元素内的行内元素或类行内元素居中,请参考前两篇的水平居中和垂直居中的博客

1 水平垂直居中

1.1 margin

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;
border: 1px solid transparent;
background: paleturquoise;
}
.in {
width: 100px;
height: 100px;
margin-top: 50px;
margin-left: 50px;
background: peachpuff;
}
</style>

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

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

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

1.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
24
25
26
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
position: relative;
background: paleturquoise;
}
.in {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px;
margin-left: -50px;
background: peachpuff;
}
</style>

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

优点:最常用的实现方式,兼容性好,可以同时实现水平和垂直居中
缺点:内盒子的宽高必须固定

1.3 定位 position–margin

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
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
position: relative;
background: paleturquoise;
}
.in {
/* width: 100px; */
width: fit-content;
height: 100px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background: peachpuff;
}
</style>

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

说明:定位方式的一种,我们都知道当定位的元素同时设置了top、right、bottom和left值时只有top和left起作用,但当加上margin:auto这点睛之笔后,你会发现这四个值都会起作用,而当这四个值都是0时就实现了我们现在的水平垂直居中了,怎么样?神不神奇

优点:兼容性好,可以同时实现水平垂直居中,且宽度无须固定
缺点:高度必须固定,否则将占父元素的100%

1.4 定位position结合transform

1.4.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
24
25
26
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
position: relative;
background: paleturquoise;
}
.in {
/* width: 100px; */
width: fit-content;
/* height: 100px;*/
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background: peachpuff;
}
</style>

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

说明:弥补了1.2中的缺点,内盒子宽高可以不固定,当内盒子宽高固定时,translate()括号中的值为负的内盒子宽/高的二分之一即可,即相当于1.2中的margin-left/top,而不论内盒子宽高是否固定,translate()括号中的值都可以是两个-50%。
注:transform方法,当计算结果含小数位时,会导致整个元素变模糊,解决方案是父级元素设置transform-style:preserve-3d;
具体关于CSS3的动画属性,我后续也会专门写一篇博客进行介绍,有兴趣的小伙伴,可以一起讨论讨论哦

优点:实现简单,宽高无须固定
缺点:transform是CSS3的新属性,所以兼容性比较差

1.4.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
23
24
25
<style>
html,body {
margin: 0;
padding: 0;
}
.wrap {
width: 200px;
height: 200px;
background: paleturquoise;
}
.in {
/* width: 100px; */
width: fit-content;
/* height: 100px;*/
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
background: peachpuff;
}
</style>

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

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

1.5 table-cell

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

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

优点:实现简单,内盒子宽高无须固定
缺点:table-cell会跟浮动、定位等属性相互冲突,并且不能设置margin属性

1.6 flex

1.6.1 align-items

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

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

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

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

1.6.2 align-self

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

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

说明:这个方法跟上一个很相似,唯一不一样的地方就在于上一个方法用align-items属性,而这个方法用的是align-self属性。简单说一下两个属性的区别:align-items属性是容器即外盒子的属性,意为容器内所有元素的交叉轴对齐方式;而align-self属性是内元素属性,意为本元素的交叉轴对齐方式

1.7 calc()

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;
border: 1px solid transparent;
background: paleturquoise;
}
.in {
width: 100px;
height: 100px;
margin: calc(50% - 50px) auto;
background: peachpuff;
}
</style>

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

说明:前面那个50%取值是父元素高度的50%,后面那个50px取值是本元素的高的一半,其实原理跟1.1的margin是相同的
注:不要质疑calc()就是一个CSS3属性,是用来指定长度的,比如可以给元素的width、height、border、margin、padding、font-size等属性设置动态值,但一定要注意calc()括号中的运算符前后一定要有空格!运算符前后一定要有空格!运算符前后一定要有空格!(重要的事情说三遍)

优点:当页面结构复杂无法用其它方式实现水平垂直居中时,你会非常喜欢这个属性的
缺点:CSS3新属性,兼容性还不是很好,而且在css中进行计算会降低页面性能

2 总结

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

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