CSS三栏布局方案

平时开发或者面试的时候,经常会遇到这样的场景,实现一个三栏布局,具体要求如下:

高度为100px,左右栏宽度固定为300px,中间栏宽度自适应。

有多种布局方案可以实现,这里一一探索。

浮动布局方案

实现思路:

通过让左右两栏固定宽度和浮动,并设置中间栏的左右外边距实现三栏自适应

这里还有一种实现思路,中间栏创建一个BFC同样可以实现自适应,原理是浮动不会影响BFC内的内容

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-浮动布局方案</title>
<style>
.left, .right, .main {
height: 100px;
}
.left {
width: 300px;
float: left;
background: red;
}
.right {
width: 300px;
float: right;
background: blue;
}
.main {
margin-left: 300px;
margin-right: 300px;
background: yellow;
}
</style>
</head>
<body>
<article>
<aside class="left">left</aside>
<aside class="right">right</aside>
<main class="main">main</main>
</article>
</body>
</html>

缺点:

  1. 内容展现顺序与DOM结构不一致,主体内容后加载,一定程度影响用户体验
  2. 当宽度缩小到不足以显示三栏时,右侧栏会被挤到下方

兼容性:

  1. PC端支持IE6+, Firefox 2+, Chrome 1+
  2. 移动端支持iOS Safari 1.0,Android browser 1.0

绝对定位布局方案

实现思路:

容器设置为相对定位,左右两栏分别用绝对定位,中间栏增加左右外边距实现自适应

还有一种思路, 左右两栏分别绝对定位在两侧,中间栏同样使用绝对定位,并设置左右的距离为300px

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
43
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-绝对定位方案</title>
<style>
.container {
position: relative;
}
.main, .left, .right {
height: 100px;
}
.main {
margin-left: 300px;
margin-right: 300px;
background: yellow;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 300px;
background: red;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 300px;
background: blue;
}
</style>
</head>
<body>
<article class="container">
<main class="main">main</main>
<aside class="left">left</aside>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. 父元素必须要定位(使用非static的定位方式)
  2. 宽度缩小到无法显示主体内容时,主体内容会被覆盖无法显示

优点:

  1. 内容可以优先加载

兼容性:

  1. PC端支持IE6+, Firefox 2+, Chrome 1+
  2. 移动端未知

Flex布局方案

实现思路:

设置容器为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
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-弹性盒布局方案</title>
<style>
.container {
display: flex;
}
.left, .main, .right {
height: 100px;
}
.left {
flex: 0 0 300px;
background: red;
}
.main {
flex: 1 1 auto;
background: yellow;
}
.right {
flex: 0 0 300px;
background: blue;
}
</style>
</head>
<body>
<article class="container">
<aside class="left">left</aside>
<main class="main">main</main>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. 无法兼容低版本的浏览器

优点:

  1. 代码简洁,DOM结构清晰
  2. 主流的实现方式

兼容性:

  1. PC端支持IE10及以上、Edge 12,chrome 21,firefox 28,safari 6.1(IE10为部分支持,其他浏览器版本为完全支持)
  2. 移动端支持iOS Safari 7, android browser 4.4
  3. 兼容性详情

网格布局方案

实现思路:

设置容器为grid,然后设置行高度为100px,设置三栏的宽度

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-网格布局方案</title>
<style>
.container {
display: grid;
grid-template-rows: 100px;
grid-template-columns: 300px 1fr 300px;
}
.left {
background: red;
}
.main {
background: yellow;
}
.right {
background: blue;
}
</style>
</head>
<body>
<article class="container">
<aside class="left">left</aside>
<main class="main">main</main>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. 兼容性相对弹性盒要差,不过目前绝大部分浏览器较新的版本已经支持

优点:

  1. 代码简洁,DOM结构清晰

兼容性:

  1. PC端支持IE10及以上、Edge 16,chrome 57,firefox 52,safari 10.1(IE10为部分支持,其他浏览器为完全支持的起始版本)
  2. 移动端支持iOS Safari 10.3, android browser 67
  3. 兼容性详情

表格布局方案

实现思路:

设置容器为table且宽度为100%,并设置子元素为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
25
26
27
28
29
30
31
32
33
34
35
36
37
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-表格布局方案</title>
<style>
.container {
display: table;
width: 100%;
}
.left, .main, .right {
display: table-cell;
height: 100px;
}
.left {
width: 300px;
background: red;
}
.main {
background: yellow;
}
.right {
width: 300px;
background: blue;
}
</style>
</head>
<body>
<article class="container">
<aside class="left">left</aside>
<main class="main">main</main>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. 非语义化

优点:

  1. 兼容浏览器版低

兼容性:

  1. PC支持IE8+, Firefox 3+, Chrome 4+, Safari 3.1+
  2. 移动端支持 iOS Safari 3.2, android browser 2.1
  3. 兼容性详情

圣杯布局

实现思路:

通过将左右两栏挂在容器的两侧,从而实现三栏布局,形状类似圣杯

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
43
44
45
46
47
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-圣杯布局方案</title>
<style>
.container {
margin-left: 300px;
margin-right: 300px;
overflow: hidden;
}
.main, .left, .right {
height: 100px;
}
.main {
float: left;
width: 100%;
background: yellow;
}
.left {
float: left;
margin-left: -100%;
width: 300px;
position: relative;
left: -300px;
background: red;
}
.right {
float: left;
margin-left: -300px;
width: 300px;
position: relative;
left: 300px;
background: blue;
}
</style>
</head>
<body>
<article class="container">
<main class="main">main</main>
<aside class="left">left</aside>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. 当中间栏宽度比左栏宽度小时,布局会发生混乱

优点:

  1. 支持内容优先加载

兼容性:

  1. 参考浮动布局方案

双飞翼布局方案

实现思路:

基于圣杯布局,引入一个容器来放置中间栏,并且设置中间栏的外边距,不需要使用相对定位

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
43
44
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>三栏布局-双飞翼布局方案</title>
<style>
.main .in, .left, .right {
height: 100px;
}
.main {
float: left;
width: 100%;
}
.main .in {
margin-left: 300px;
margin-right: 300px;
background: yellow;
}
.left {
float: left;
width: 300px;
margin-left: -100%;
background: red;
}
.right {
float: right;
width: 300px;
margin-left: -300px;
background: blue;
}
</style>
</head>
<body>
<article class="container">
<main class="main">
<div class="in">main</div>
</main>
<aside class="left">left</aside>
<aside class="right">right</aside>
</article>
</body>
</html>

缺点:

  1. DOM结构较复杂

优点:

  1. 支持内容优先加载
  2. 相对圣杯布局,宽度缩小,布局不会发生混乱

兼容性:

  1. 参考浮动布局方案

参考

您的支持将鼓励我继续创作!
0%