一文详解主流 CSS 布局
# 一文详解主流 CSS 布局
介绍水平居中布局、垂直居中布局、居中布局、两列布局、三列布局、圣杯布局、双飞翼布局等主流 css 布局。
# 一. 水平居中布局
水平居中布局主要有三种实现方式:
inline-block
+text-align
属性配合使用。table
+margin
属性配合使用。absolute
+transform
属性配合使用。
# 1. inline-block + text-align
原理:
text-align 属性:是为文本内容设置对齐方式。
left
:左对齐。center
:居中对齐。inline-block
:右对齐。
display属性:
block
:块级元素(width
和height
属性有效)。inline
:内联元素(text-align
属性有效,width
和height
属性无效)。inline-block
:行内块级元素(块级 + 内联)。
效果:
优缺点:
- 优点
- 浏览器兼容性比较好(IE6~9) 。
- 缺点
text-align
属性具有继承性,导致子级元素的文本也是居中显示的(见上图中的文字“水平居中”四个字)。
# 2. table + margin
原理:
display 属性:
table
和block
都可以,div 元素默认是 block 块级元素。
margin 属性(核心):外边距
auto
表示根据浏览器自动分配(等分左右外边距)。
效果:
优缺点:
- 优点
- 只需要对子级元素进行设置就可以实现水平方向居中布局效果。
- 缺点
- 如果子级元素脱离文档流(
float
或absolute
或fixed
),会导致margin
属性的值无效。
- 如果子级元素脱离文档流(
# 3. absolute + transform
这种方式比前两种要复杂些。
原理:
position 属性:
absolute
绝对定位,如果父级元素没有开启定位的话,当前元素是相对于页面定位的;反之当前元素是相对于父级元素定位的。relative
、absolute
、fixed
这三个值都是开启定位,position
的默认值static
表示不开启定位。relative
是不脱离文档流的,absolute
、fixed
都是脱离文档流的。
left 属性:
- 50%,设置子级元素相对于父级元素左边 50%。
transform 属性:
- 子级元素往左(往左是负值)移动它宽度的一半。
效果:
优缺点:
- 优点
- 无论父级元素是否脱离文档流,不影响子级元素水平居中效果(子级元素设置了绝对定位,父级元素开启了定位即已经脱离了文档流)。
- 缺点
transform
属性是 CSS3 中新增属性,浏览器支持情况不好。
# 二. 垂直居中布局
垂直居中布局主要有两种实现方式:
table-cell
+vertical-align
属性配合使用。absolute
+transform
属性配合使用。
# 1. table-cell + vertical-align
原理:
display 属性:
table
:设置当前元素为<table>
元素(表格)。table-cell
:设置当前元素为<td>
元素(单元格),单元格的内容可以有垂直和水平两种方向的对齐。
vertical-align 属性:用于设置文本内容的垂直方向对齐方式
top
:顶部对齐。middle
:居中对齐。bottom
:底部对齐。
效果:
优缺点:
- 优点
- 浏览器兼容性比较好(IE6~9)。
- 缺点
vertical-align
属性具有继承性,导致父级元素的文本也是居中显示的(见上图中的文字“垂直居中”四个字)。
# 2. absolute + transform
原理:
position 属性:
absolute
绝对定位,如果父级元素没有开启定位的话,当前元素是相对于页面定位的;反之当前元素是相对于父级元素定位的。relative
、absolute
、fixed
这三个值都是开启定位,position
的默认值static
表示不开启定位。relative
是不脱离文档流的,absolute
、fixed
都是脱离文档流的。
top 属性:
- 50%,设置子级元素相对于父级元素上边50%
transform 属性:
- 子级元素往上(往上是负值)移动它宽度的一半。
效果:
优缺点:
- 优点
- 父级元素是否脱离文档流,不影响子级元素垂直居中效果。
- 缺点
- transform 属性是 CSS3 中新增属性,浏览器支持情况不好。
# 三. 居中布局
居中布局实际上就是既要水平方向居中,也要垂直方向居中。
居中布局主要如下两种实现方式(整合水平居中和垂直居中的方案):
table
+margin
实现水平方向居中,table-cell
+vertical-align
实现垂直方向居中。absolute
+transform
实现水平方向和垂直方向居中。
# 1. table + margin & table-cell + vertical-align
原理:
整合水平居中和垂直居中的方案。
效果:
优缺点:
- 优点
- 浏览器兼容性比较好(IE6~9)。
- 缺点
- 只需要设置子元素的居中效果,但却同时修改了父元素的属性,不够干净。
# 2. absolute + transform
原理:
利用定位的方式来实现居中效果。
效果:
优缺点:
- 优点
- 在不考虑浏览器兼容性的情况下,优于上一种解决方案(目前老版本浏览器的市场占有率越来越低)。
- 缺点
- 只需要设置子元素的居中效果,但却同时修改了父元素的属性,不够干净。
transform
属性是 CSS3 中新增属性,浏览器支持情况不好。
# 四. 两列布局
两列布局是多列布局的一种,一般情况下是指一列(左列)确定宽度,另一列(右列)自适应(自动填满剩余所有空间)。
两列布局主要有三种实现方式:
float
+margin
属性配合使用。float
+overflow
属性配合使用。display
属性的table
相关值使用。
# 1. float + margin(不建议采用)
原理:
- width 属性:左列元素设置定宽,右列元素
div
默认是 100%。 - height 属性:需要设置高度,否则
div
元素默认高度是 0。 - margin-left 属性:右列元素是 100% 的宽度,左外边距需要和左列元素宽度相等。
效果:
优缺点:
- 优点
- 实现方式简单
- 缺点
- 自适应元素
margin
属性值与定宽元素的width
属性值保持一致(耦合性强)。 - 定宽元素浮动与自适应元素不浮动导致浏览器兼容性不好(老版本浏览器会在两个元素间有一个空白区)。
- 如果在自适应那一列中存在子集元素,并且使用了
clear: both;
清除浮动时,显示就会存在问题。
- 自适应元素
# 2. float + margin(优化版,但也不建议采用)
原理:
为自适应元素(右列)定义父级元素。
- float 属性:右列元素的父元素设置为浮动后,导致默认宽度为 0,需要设置宽度为 100%。
- margin-left 属性:右列元素的父元素设置
margin-left
为负值(向左移动)。 - position 属性:左列元素设置相对定位,让它的显示层级更高。
效果:
优缺点:
- 优点
- 解决了上一种方案的第 1 和第 3 个缺点。
- 缺点
- 给右列元素多增加了一个父级容器,且为了解决相关问题,又设置了很多相关的 css 内容,解决方案很复杂。
- 上一种方案的第 2 个缺点没有解决。
# 3. float + overflow
原理:
为自适应元素(右列)定义父级元素。
- overflow 属性:右列元素设置为溢出值隐藏,开启BFC模式(当前元素的内部环境与外界完全隔离)。
效果:
优缺点:
- 优点
- 实现方式简单。
- 上面两种解决方案中的问题在此解决方案中都没有。
- 缺点
overflow
属性不仅解决了两列布局问题,同时设置了内容溢出的情况(实际使用中我们可能不要隐藏溢出内容)。
# 4. 利用 display 属性的 table 相关值
原理:
对左右两列的父级元素进行设置(如果没有父级元素,需要新增一个)。
display 属性:table
值的特性:表格的单元格的宽度会自动分配(默认是 50% 等分,设置值后,另外的部分会自适应)。
table-layout 属性:设置为 fixed
,防止过长的内容撑破表格。
效果:
优缺点:
- 优点
- 浏览器兼容性比较好。
- 缺点
- 将所有元素的
display
属性设置为table
相关值,受到相应制约。
- 将所有元素的
# 五. 三列布局
三列布局是多列布局的一种,一般情况下是指三列中左边两列是确定的宽度,右边一列是自动填满剩余所有空间的一种布局效果。
三列布局比两列布局多了一列“定宽”,但实现起来并不比两列布局复杂多少。
三列布局主要有三种实现方式:
float
+margin
属性配合使用float
+overflow
属性配合使用display
属性的table
相关值使用
可见,三列布局的实现方式和两列布局基本上是类似的,下面举一个例子来演示。
# 1. float + margin
原理:
和两列布局的第一种解决方案类似。
效果:
# 2. 其他几种解决方案略
其他几种解决方案略。
可以举一反三,四列、五列布局都可以采用相同的方式来实现。
# 六. 圣杯布局
圣杯布局是一个完整页面的布局(一个较为复杂的页面可能会由各种布局方式组合而成,此处抽离出一个简单的模型),呈现一种三行三列的结构,一般“三列”多出现在第二行中,如下图所示:
圣杯布局是来源于该布局效果类似圣杯而得名。简单来说,就是指三行三列布局。
圣杯布局的实现方式:
由于 div
元素本来就是垂直方向排列的,所以不用作任何的设置,三个 div
标签就可以实现三行的效果了;
因此圣杯布局的核心就是中间主体部分的 左右定宽 + 中间自适应 的布局效果;
中间主题部分实现后,只需要在首尾增加两个 div
标签,即可实现圣杯布局。
原理:
- 思路
- parent(外面包裹一层)设置
margin-left
和margin-right
预留出两个定宽位置; - left 和 right 部分通过两次移动,移动到理想位置。
- parent(外面包裹一层)设置
- Tips
- 子级元素增加浮动,父级元素没有加浮动,父级元素会有高度坍塌的问题(高度为0),因此需要给父级元素设置
height
属性; div
元素默认宽度是父级元素的 100%,但设置为float
后,默认宽度变成了 0。- 由于三个元素都是浮动的,因此可以通过水平方向的移动(
margin-left
)移动到上一行; - 除了
margin-left
可以移动元素,left
和right
也可以,但需要开启定位,但为了避免脱离文档流的麻烦,使用relative
相对定位。
- 子级元素增加浮动,父级元素没有加浮动,父级元素会有高度坍塌的问题(高度为0),因此需要给父级元素设置
- 详情见下面代码注释。
效果:
# 七. 双飞翼布局
双飞翼布局最早是淘宝团队提出,是针对圣杯布局的优化解决方案。主要是优化了圣杯布局中开启定位(即 left 和 right 两列)的问题。
双飞翼布局和圣杯布局本质上都是为了解决一个问题:三列的重合部分如何解决。下面看下双飞翼布局给出的解决方案。
原理:
- 优化
- 需要优化圣杯布局中
position
定位的问题。
- 需要优化圣杯布局中
- 思路
center
(自适应那一列)中增加子级元素(本案例中为inner
);- 之后开发的内容写在
inner
元素里。
- 详情见下面代码注释。
效果:
# 八. 等分布局
等分布局就是指一行被分为若干列,每一列的宽度是相同的值。
等分布局主要有两种实现方式:
float
属性实现等分布局效果。display
属性的table
实现等分布局效果。
需要兼顾的问题:
- 实现等分布局时,有可能需要每一列之间实现空白间隔区域。
- 通过在原有 HTML 页面源代码的基础上增加一个父级容器(本案例中为
parent-fix
)来实现。
- 通过在原有 HTML 页面源代码的基础上增加一个父级容器(本案例中为
# 1. float 属性实现
效果:
# 2. table 元素实现
效果:
# 九. 等高布局
等高布局就是指一行被分为若干列,每一列的高度是相同的值。
等高布局主要有两种实现方式:
display
属性的table
实现等高布局效果。padding
+margin
属性实现等高布局效果。
# 1. table 元素实现
原理:
表格的单元格默认是等高的。
效果:
优缺点:
- 优点
- 浏览器兼容性比较好。
# 2. padding + margin
原理:
padding-bottom
和 margin-bottom
都设置为极大且相反值的时候,有一个对冲的效果,然后结合父元素的 overflow
属性,实现 伪等高布局。
这种解决方案实现的并不是真正的等高布局,只是视觉上等高的伪等高布局。在实现页面布局中有句话叫做:眼见不一定为实,说的就是这种情况。
效果:
# 十. CSS3 多列布局
# 1. columns 属性
columns 属性:它是一个简写属性,可以分成以下两个属性
column-count
属性:定义列的数量。auto
:默认值,用于表示列的数量由其他CSS属性决定。number
:必须是正整数,用于表示定义列的数量。
column-width
属性:定义列的宽度。auto
:默认值,用于表示列的宽度由其他CSS属性决定。length
:必须是正整数,用于表示定义列的宽度。
效果:
# 2. 列的间距
上图中可以看到,列与列之间有空白的间隙,这个间隙不是由 padding 或者 margin 设置的,而是 CSS3 在多列布局时自动分配的。
在CSS3中,column-gap
属性用于设置列与列之间的间距,该属性主要为多列显示时的元素设置。
column-gap
属性有两个属性值:
normal
:用于表示使用浏览器定义列的默认间距,默认值为 1em。length
:必须是正整数,用于表示定义列之间的间距。
效果:
# 3. 列的边框
在 CSS3 中,column-rule
属性用于定义列与列之间的边框,其中包括边框宽度、边框颜色以及边框样式。
column-rule
属性:它是一个简写属性,可以分成以下三个属性
column-rule-width
属性:用于表示列与列之间的边框宽度。column-rule-color
属性:用于表示列与列之间的边框颜色。column-rule-style
属性:用于表示列与列之间的边框样式。
效果:
# 4. 横跨多列
在 CSS3 中,column-gap
属性用于定义一个列元素是否跨列。
column-gap
属性有两个属性值:
none
:用于表示元素不跨列。all
:用于表示元素跨所有列。
效果:
# 5. 列的填充
在 CSS3 中,column-fill
属性用于定义列的高度是由内容决定,还是统一高度。
column-fill
属性有两个属性值:
auto
:默认值,用于表示列的高度由内容决定。balance
:用于表示列的高度根据内容最多的一列高度为准。- 这个属性在 Chrome浏览器中兼容不是很好,此处省略示例。
# 十一. 全屏布局
全屏布局就是指 HTML 页面铺满整个浏览器窗口,并且没有滚动条。而且还可以跟随浏览器的大小变化而变化。
全屏布局示意图如下图所示:
# 1. 全屏布局的一种解决方案
<head>
<style type="text/css">
html, body {
margin: 0;
overflow: hidden;
}
header {
height: 100px;
position: fixed;
top: 0;
left: 0;
right: 0;
background: lightgray;
}
.content {
position: fixed;
left: 0;
right: 0;
top: 100px;
bottom: 100px;
overflow: auto; /* 解决内容溢出问题 */
background: lightblue;
}
.content .left {
width: 300px;
height: 100%;
position: fixed;
left: 0;
top: 100px;
bottom: 100px;
background: lightcoral;
}
.content .right {
height: 600px; /* div是个块级元素,它的高度由后代元素的高度之和决定,故设置100%无效*/
margin-left: 300px;
background: greenyellow;
}
footer {
height: 100px;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: lightslategray;
}
</style>
</head>
<body>
<header></header>
<div class="content">
<div class="left"></div>
<div class="right"></div>
</div>
<footer></footer>
</body>
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
效果图:
# 十二. 总结
其它布局在网上已经有很多人总结过了,这里不再赘述,例如:
- 网格布局(响应式布局)。
- 弹性盒子布局(flex布局)。
最后需要注意,没有完美的解决方案,在实际开发中,要根据实际情况选择合适的布局方案。