三栏布局

问题:假设容器的高度默认100px,请写出三栏布局,其中左栏、右栏的宽度各为300px,中间的宽度自适应。

方法

浮动

左侧设置左浮动,右侧设置右浮动即可,中间会自动地自适应。

绝对定位

左侧设置为绝对定位, left:0px。右侧设置为绝对定位, right:0px。中间设置为绝对定位,left 和right 都为300px,即可。中间的宽度会自适应。

使用article标签作为容器,包裹左、中、右三个部分。

Flexbox布局

flex:1即为flex-grow:1,经常用作自适应布局,将父容器设置display:flex,侧边栏大小固定后,将内容区flex:1,内容区则会自动放大占满剩余空间。

表格布局 table

设置整个容器的宽度为100%,设置三个部分均为表格,然后左边的单元格为 300px,右边的单元格为 300px,即可。中间的单元格会自适应。

网格布局 grid

设置容器为网格布局display: grid,宽度为100% 设置网格为三列,并设置每列的宽度grid-template-columns: 300px auto 300px

效果

5mDMKs.gif

代码

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面布局</title>
<style>
html *{
padding: 0;
margin: 0;
}
.layout article div{
height: 100px;
}
.layout{
margin-top: 20px;
}
/* 1.浮动 */
/* .layout.float表示交集选择器,空格表示后代选择器 */
.layout.float .left{
float: left;
width: 300px;
background: red;
}
.layout.float .right{
float: right;
width: 300px;
background: blue;
}
.layout.float .center{
background: green;
}
/* 2.绝对定位 */
.layout.absolute{
margin-top: 100px;
}
.layout.absolute .left{
position: absolute;
left: 0;
width: 300px;
background: red;
}
/* 【重要】中间的区域,左侧定位300px,右侧定位为300px,即可完成。宽度会自适应 */
.layout.absolute .center{
position: absolute;
left: 300px;
right: 300px;
background: green;
}
.layout.absolute .right{
position: absolute;
right: 0;
width: 300px;
background: blue;
}
/* 3.flex */
/* 绝对布局导致脱离文档流,因此上边距300px是从方法一中还在文档流的元素开始算 */
.layout.flex{
margin-top: 230px;
}
.layout.flex .left-center-right{
display: flex;
}
.layout.flex .left {
width: 300px;
background: red;
}

.layout.flex .center {
flex: 1;
background: green;
}

.layout.flex .right {
width: 300px;
background: blue;
}
/* 4.表格 */
/* 重要:设置容器为表格布局,宽度为100% */
.layout.table .left-center-right{
width: 100%;
display: table;
}
/* 重要:设置三个模块为表格里的单元*/
.layout.table .left-center-right div{
display: table-cell;
}
.layout.table .left{
width: 300px;
background: red;
}
.layout.table .center {
background: green;
}

.layout.table .right {
width: 300px;
background: blue;
}
/* 5.网格 */
/* 重要:设置容器为网格布局,宽度为100% */
/* 设置网格为三列,并设置每列的宽度。即可。 */
.layout.grid .left-center-right{
display: grid;
width: 100%;
/* grid-template-rows: 100px; */
grid-template-columns: 300px auto 300px;
}
.layout.grid .left {
background: red;
}
.layout.grid .center {
background: green;
}
.layout.grid .right {
background: blue;
}
</style>
</head>
<body>
<!-- 方法一:浮动 -->
<!--
元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,
所以元素下边的还在文档流中的元素会自动向上移动
-->
<!-- 输入 section.layout.float,即可生成 -->
<section class="layout float">
<!-- 用article标签包裹左、中、右三个部分 -->
<article class="left-center-right">
<div class="left">
left
</div>
<div class="right">
right
</div>
<div class="center">
<h1>浮动</h1>
center
</div>
</article>
<!-- 方法二:绝对定位 -->
</section>
<section class="layout absolute">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>绝对定位</h1>
center
</div>
<div class="right">
right
</div>
</article>
</section>
<!-- 方法三:flex -->
<section class="layout flex">
<article class="left-center-right">
<div class="left">
我是 left
</div>
<div class="center">
<h1>flex布局</h1>
我是 center
</div>
<div class="right">
我是 right
</div>
</article>
</section>
<!-- 方法四、表格 -->
<section class="layout table">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>表格布局</h1>
center
</div>
<div class="right">
right
</div>
</article>
</section>
<!-- 方法五、网格 -->
<section class="layout grid">
<article class="left-center-right">
<div class="left">
left
</div>
<div class="center">
<h1>网格布局</h1>
center
</div>
<div class="right">
right
</div>

</article>
</section>
</body>
</html>

延伸

五种方法的对比

  • 五种方法的优缺点

  • 考虑中间模块的高度问题

  • 兼容性问题:实际开发中,哪个最实用?

方法1:浮动:

  • 优点:兼容性较好。

  • 缺点:浮动是脱离文档流的,如果处理不好,会带来很多问题。有些时候需要清除浮动,需要很好的处理浮动周边元素的关系。

方法:2:绝对定位

  • 优点:快捷。

  • 缺点:布局脱离文档流,意味着下面的子元素也要脱离文档流,导致这个方案的有效性是比较差的。

方法3:flex 布局

  • 优点:比较完美的解决了浮动和绝对定位的问题。在移动端比较常用
  • 缺点:兼容性比较差,不兼容IE8及以下的版本。因为这个是CSS3中新增的display的属性值。

方法4:表格布局

  • 优点:表格布局在很多场景中很实用,兼容性非常好。因为IE8不支持 flex,此时可以尝试表格布局。

  • 缺点:因为三个部分都当成了单元格来对待,此时,如果中间的部分变高了,其会部分也会被迫调整高度(即使其余部分单独设置了高度)。但是,在很多场景下,我们并不需要两侧的高度增高。

方法5:网格布局

  • CSS3中引入的布局,很好用。代码量简化了很多。

如果题目中去掉高度已知

问题:题目中,如果去掉高度已知,我们往中间的模块里塞很多内容,让中间的模块撑开。会发生什么变化?

5my7i6.gif

页面布局的变通

三栏布局

  • 左右宽度固定,中间自适应
  • 上下高度固定,中间自适应

两栏布局

  • 左宽度固定,右自适应
  • 右宽度固定,左自适应
  • 上宽度固定,下自适应
  • 下宽度固定,上自适应