curTain

水平居中 + 垂直居中 + 水平垂直居中

前期准备

下文的所有 css 都是基于如下 html 结构:

1
2
3
<div class="parent">
<div class="son">son</div>
</div>

go–go–go—-

1. 水平居中

1.1 使用 margin: 0 auto

形成原理:

  1. 元素为块级元素
  2. 元素需要设置宽度
  3. margin: 0 auto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
}
.son{
font-size: 38px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
margin: 0 auto;
}

运行结果:

1.2 使用 text-align:center

形成原理:

  1. 子元素为行内元素(可以使用 display: inline-block 实现转换)
  2. 父元素设置 text-align:center
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
text-align: center;
}
.son{
font-size: 38px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
display: inline-block;
}

1.3 使用 flex 布局

形成原理:

  1. 父元素使用 flex 布局
  2. 父元素设置 justify-content: center
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
display: flex;
justify-content: center;
}
.son{
font-size: 38px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
}

1.4 使用 absolute + transform

形成原理:

  1. 子元素绝对定位 position: absolute;
  2. 以父元素宽度为基准向右偏移 50%,设置 left: 50%;
  3. 基于自己的宽度向左偏移 50%,设置:transform: translate( -50%, 0 );

存在问题:

因为使用了绝对定位,元素脱离文档流,父元素捕获不到子元素高度导致父元素高度塌陷…

如果子元素是动态高度,则只能通过 js 获取子元素高度,再设置父元素高度.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
}
.son{
font-size: 38px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
position: absolute;
left: 50%;
transform: translate( -50%, 0 );
}

运行结果:

1.5 使用 absolute + 负margin

形成原理:

  1. 子元素绝对定位 position: absolute;
  2. 以父元素宽度为基准向右偏移 50%,设置 left: 50%;
  3. 需要设置固定宽度
  4. 使用负 margin ,基于自己的宽度向左偏移 50% 宽度,margin-left: -0.5 * width;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
}
.son{
font-size: 38px;
line-height: 81px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
position: absolute;
left: 50%;
margin-left: -150px;
}

1.6 使用 absolute + width + margin

形成原理:

  1. 子元素绝对定位 position: absolute;
  2. 设置子元素宽度
  3. 设置左右偏移为 0,left:0; right:0;
  4. 设置 margin 上下为 0,左右自适应占满整行. margin: 0 auto;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
}
.son{
font-size: 38px;
line-height: 81px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
}

1.7 水平居中总结

总共使用了 6 总方法,还有一种没有使用,就是使用 grid 实现,

三种使用绝对定位,但是绝对定位会导致父元素高度塌陷,需谨慎使用(其实也不算了…哈哈哈)

最推荐 flex 实现,兼容性优良,实现简单可靠.

2. 垂直居中

2.1 行内元素的实现

行内元素 –> 使用 line-height: height 实现

实现原理:

  1. 父元素固定高度,并设置行高为高度值:line-height: height
  2. 子元素必须是行内元素(可以使用 display: inline-block 实现转换)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
height: 800px;
line-height: 800px;
}
.son{
font-size: 50px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
display: inline-block;
}

2.2 使用 flex 布局

实现原理:

  1. 父元素使用 flex 布局
  2. 父元素设置 align-items: center;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
height: 600px;
display: flex;
align-items: center;
}
.son{
font-size: 50px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
}

2.3 使用 position:absolute

三种方式,

  1. absolute + transform
  2. absolute + -margin
  3. absolute + margin: auto 0

2.4 总结

垂直居中还有表格、grid 和 vertical-align 可以实现。

推荐使用 flex 布局实现,简单易理解.

3. 水平垂直居中

3.1 使用 absolute + margin

实现原理:

  1. 父元素使用定位(除了 static 定位都行)
  2. 子元素使用绝对定位
  3. 上下左右偏移为 0
  4. 设置 margin: auto 占满整个父元素,居中
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
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
height: 600px;
position: relative;
}
.son{
font-size: 50px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}

3.2 使用 absolute + transform

  1. 父元素使用定位(除了 static 定位都行)
  2. 子元素使用绝对定位
  3. 上左各偏移基于父元素的 50%
  4. 使用 transform 再拉回多的偏移 transform: translate( -50%, -50% );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
*{
padding: 0;
margin: 0;
}
.parent{
background-color: #ccc;
padding: 20px;
height: 600px;
position: relative;
}
.son{
font-size: 50px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
transform: translate( -50%, -50% );
}

3.2 使用 absolute + -margin

原理同上,需要知道子元素的高度,

负 margin 的值等于高度的一半

3.3 使用 flex 布局

实现原理:

  1. 父元素使用 flex 布局
  2. 设置属性水平居中:justify-content: center;
  3. 设置属性垂直居中:align-items: center;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*{
padding: 0;
margin: 0;
}
.parent{
background-color: rgb(117, 117, 117);
padding: 20px;
height: 600px;
display: flex;
justify-content: center;
align-items: center;
}
.son{
font-size: 50px;
line-height: 100px;
color: #ccc;
background-color: aquamarine;
text-align: center;
width: 300px;
height: 100px;
}

4. 总结

个人最喜欢 flex 布局.推荐多使用 flex 布局.

加油!!

5. 参考材料

16种方法实现水平居中垂直居中

CSS实现文本,DIV垂直居中

一劳永逸的搞定 flex 布局


 评论