# CSS布局
# 常见布局方案
前端布局的发展历程:
表格布局 > 定位布局 > 浮动布局 > Flex布局 > 网格布局
还有一种 多列布局 比较少用。
# 表格布局
<table>
默认设置了一组table布局属性。当这些属性被应用于非<table>
元素时,就是表格布局。常用于兼容一些不支持 Flex、Grid 的浏览器。
display: table
:指定为表格容器(类比于<table>
)display: table-row
:指定为表行(类比于<tr>
)display: table-cell
:指定为单元格(类比于<td>、<th>
)
# 定位布局
脱离标准流,但不会影响 标准流的排列。
- 默认定位
- position: static(默认位置)
- 绝对定位
- position: absolute(相对最近一个非static的父元素)
- 固定定位
- position: fixed(相对浏览器视窗的左上角)
- 相对定位
- position: relative(相对本身所在位置,原位置遵循标准文档流)
- 粘性定位
- position: sticky(先保持
position: static
,达到阈值时变成postion: fixed
) - 该定位遵循
标准文档流
,仍然保留元素原本在文档流中的位置
- position: sticky(先保持
# 浮动布局
浮动布局 脱离标准流,会影响 标准流的排列。
# 网格布局
从 行、列 上定义元素的排列。(兼容性:需IE10 及以上
)
display: grid
:将父元素设为网格容器。grid-template-columns
:定义列轨道grid-template-rows
:定义行轨道grid-gap
:定义行列之间的间隙
.container {
display: grid;
grid-template-colums: 200px auto 200px; /* 定义分别为 200px、自适应、200px的3列 */
grid-template-rows: 100px 200px; /* 定义分别为 100px、200px高度的行 */
grid-gap: 20px; /* 定义行、列之间间隙为20px */
}
1
2
3
4
5
6
2
3
4
5
6
# 多列布局(少见)
把内容按列排序
(类似报纸)。
colum-width
,指定按照至少某个宽度用尽可能多的列
来填充- 类似
column-count
。高度浏览器列的数量
- 类似
# [扩展] 三列布局的实现
要求:三个元素:左、中、右,其中左、右固定宽度为200px,中间宽度自适应。(元素高度100px)
<div class="container">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div>
1
2
3
4
5
2
3
4
5
以下为 5种 实现方式:
# 表格布局
.container {
display: table;
width: 100%; /* 注意,这里因为是table,所以width是100% */
height: 100px;
}
.left,
.center,
.right {
display: table-cell;
}
.left,
.right {
width: 200px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 定位方式
.container {
position: relative;
height: 100px;
}
.left,
.right {
position: absolute;
width: 200px;
height: 100%;
}
.left {
left: 0;
}
.right {
right: 0;
}
.center {
position: absolute;
left: 200px;
right: 200px;
height: 100%;
}
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
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
# 浮动方式
/*
* 注:因为浮动元素的前一个元素若为非浮动,则会紧贴底部
* 所以这种方式需更换DOM的排列顺序:left、right、cente
*/
.left,
.right {
width: 200px;
height: 100px;
}
.left {
float: left;
}
.right {
float: right;
}
.center {
height: 100px;
margin: 0 200px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Flex布局
.container {
display: flex;
height: 100px;
}
.left,
.right {
width: 200px;
}
.center {
flex: 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 网格布局
.container {
display: grid;
grid-template-columns: 200px auto 200px;
grid-template-rows: 100px;
}
1
2
3
4
5
2
3
4
5
# 移动端响应式布局方案
# 媒体查询
@media media-type and (media-feature-rule) {
/* CSS rules */
}
1
2
3
2
3
其中
- media-type(媒体类型):指定媒体类型(屏幕screen、打印稿print)
- media-feature-rule:查询规则
# 百分比
也叫流式布局。
width
: 相对于父容器width内容宽的百分比;height
: 相对于父容器height内容宽的百分比padding、margin
: 相对于父容器width内容宽的百分比(任意方向)border
: 不能使用百分比
# rem
rem
是相对于html
的字体大小
默认:1rem = 16px
# 动态计算rem
通过头部内嵌一段脚本,监听设备宽度的变化来动态改变根字体大小。
1、先通过viewport tag
来设置视窗大小为内容大小,同时禁止缩放(否则按照默认预设值)。
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1;">
1
2、嵌入JS脚本。
// 一般为了方便计算,会设置成:1rem = 100px。
(function() {
function _setRootSize() {
// a、获取根元素
let rootHTML = document.documentElement;
// b、获取当前设备宽度deviceWidth
let deviceWidth = rootHTML.getBoundingClientRect().width || rootHTML.clientWidth;
// c、设置当前设备宽度最大值为750px(750px为视觉稿宽度)
// 因为deviceWidth > 750,物理分辨率大于 1500(devicePixelRatio = 2时),正常应该是PC访问
deviceWidth = deviceWidth > 750 ? 750 : deviceWidth;
// d、计算比率。(假设750px设计图也是一个设备,希望1rem = 100px,则需在其根节点字体大小设置100px,得出比率)
let ratio = 750 / 100;
// e、当前设备宽度 / 比率,算出当前设备的根节点字体大小
let rootFontSize = deviceWidth / ratio;
// f、设置根节点字体大小
rootHTML.style.fontSize = rootFontSize + 'px';
}
_setRootSize();
if (document.body) {
_setRootSize();
} else if (document) {
document.addEventListener('DOMContentLoaded', _setRootSize);
}
window.addEventListener('resize', _setRootSize)
})();
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# vw/vh
vw
、vh
都是视口单位,分别等于视口宽度、高度的百分比。
兼容性:ios8、android 4.4以上
# 几种响应式方案的区别
媒体查询:
- 缺点:1、定义多套查询规则;2、响应断点,体验性较差
百分比:
- 缺点:1、不同属性的参考基准不一;2、并非所有属性都支持百分比
rem:
- 优点:1、是个全局性的基准单位;2、动态计算,可限定最大宽度
- 缺点:1、innerWidth/innerHeight可能不准确;2、安卓4.4以下不支持viewport缩放
vw:
- 好处:1、全局性的基准单位;2、无需借助JS
- 缺点:无法限定最大宽度
可以根据实际情况采取合适的方案,也可采用多套配合(如网易新163就是:媒体查询 + rem + vw)
但以上都 无法解决1px问题。
# 参考链接
BFC和浮动 →