CSS常见布局以及解决方案

整理了一下常见的基础布局以及对应的不同的解决方案

水平居中

margin + 定宽
1
2
3
4
5
6
7
8
9
10
<div class="parent">
<div class="child">Demo</div>
</div>

<style>
.child {
width: 100px;
margin: 0 auto;
}

</style>

table + margin
1
2
3
4
5
6
7
8
9
10
11
12
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.child {
display: table;
margin: 0 auto;
}

</style>

absolute + margin-left
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
position: relative;
}

.child {
position: absolute;
left: 50%;
width: 100px;
margin-left: -50px;
}

</style>

flex + justify-content
1
2
3
4
5
6
7
8
9
10
11
12
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
display: flex;
justify-content: center;
}

</style>

垂直居中

table-cell + vertical-align
1
2
3
4
5
6
7
8
9
10
11
12
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
display: table-cell;
vertical-align: middle;
}

</style>

absolute + transform
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
position: relative;
}

.child {
position: absolute;
top: 50%;
transform: translateY(-50%);
}

</style>

flex + align-items
1
2
3
4
5
6
7
8
9
10
11
12
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
display: flex;
align-items: center;
}

</style>

水平垂直居中

absolute + transform
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
position: relative;
}

.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}

</style>

inline-block + text-align + table-cell + vertical-align
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
text-align: center;
vertical-align: middle;
display: table-cell;
}

.child {
display: inline-block;
}

</style>

flex + justify-content + align-items
1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="parent">
<div class="child">
Demo
</div>
</div>

<style>
.parent {
display: flex;
justify-content: center;
align-items: center;
}

</style>

一列定宽,一列自适应

float + margin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

<style>
.left {
float: left;
width: 100px;
}

.right {
margin-left: 100px;
}

</style>

float + overflow
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

<style>
.left {
float: left;
width: 100px;
}

.right {
overflow: hidden;
}

</style>

table
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

<style>
.parent {
display: table;
width: 100%;
table-layout: fixed;
}

.left {
display: table-cell;
width: 100px;
}

.right {
display: table-cell;
}

</style>

flex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="parent">
<div class="left">
<p>left</p>
</div>
<div class="right">
<p>right</p>
<p>right</p>
</div>
</div>

<style>
.parent {
display: flex;
}

.left {
width: 100px;
margin-left: 20px;
}

.right {
flex: 1;
}

</style>

等分布局

float
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
<div class="parent">
<div class="column">
<p>1</p>
</div>
<div class="column">
<p>2</p>
</div>
<div class="column">
<p>3</p>
</div>
<div class="column">
<p>4</p>
</div>
</div>

<style>
.parent {
margin-left: -20px;
}

.column {
float: left;
width: 25%;
padding-left: 20px;
box-sizing: border-box;
}

</style>

flex
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
<div class="parent">
<div class="column">
<p>1</p>
</div>
<div class="column">
<p>2</p>
</div>
<div class="column">
<p>3</p>
</div>
<div class="column">
<p>4</p>
</div>
</div>

<style>
.parent {
display: flex;
}

.column {
flex: 1;
}

.column+.column {
margin-left: 20px;
}

</style>

table
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
<div class="parent-fix">
<div class="parent">
<div class="column">
<p>1</p>
</div>
<div class="column">
<p>2</p>
</div>
<div class="column">
<p>3</p>
</div>
<div class="column">
<p>4</p>
</div>
</div>
</div>

<style>
.parent-fix {
margin-left: -20px;
}

.parent {
display: table;
width: 100%;
table-layout: fixed;
}

.column {
display: table-cell;
padding-left: 20px;
}

</style>

圣杯布局(三列布局, 两边固定宽度中间自适应)

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
<div class="bd">
<div class="main">
</div>
<div class="sub">
</div>
<div class="extra">
</div>
</div>

<style>
.main {
float: left;
width: 100%;
}

.sub {
float: left;
width: 190px;
margin-left: -100%;
position: relative;
left: -190px;
}

.extra {
float: left;
width: 230px;
margin-left: -230px;
position: relative;
right: -230px;
}

.bd {
padding: 0 230px 0 190px;
}

</style>

补充:

  • DOM元素的顺序不能改变
  • 当main内容部分比两边的子面板宽度小的时候,布局就会乱掉。可以通过设置main的min-width属性或使用双飞翼布局避免问题

双飞翼布局(同三列,圣杯布局改进版)

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
<div class="main-wrap column">
<div class="main">
#main
</div>
</div>
<div class="sub">
</div>
<div class="extra">
</div>

<style>
.main-wrap {
float: left;
width: 100%;
}

.sub {
float: left;
width: 190px;
margin-left: -100%;
}

.extra {
float: left;
width: 230px;
margin-left: -100%;
}

.main {
margin: 0 230px 0 190px;
}

</style>

以上为常见布局解决方案,传统主要用position, flex, table,float等属性去实现布局,另外就是flex相关一套弹性布局属性。还是觉得弹性布局的表达力更强,语法更直观实现更方便。另外在2017年末尾的今天,弹性布局的浏览器兼容问题也不算一个很大的问题了。