布局中的尺寸与位置

CSS盒模型的组成

在 CSS 中,所有的元素都被一个个的”盒子(box)包围着,理解这些”盒子”的基本原理,是我们使用CSS实现准确布局、处理元素排列的关键。

盒子的组成:content内容、padding内填充、border边框、margin外边距

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
<!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>Document</title>
<style>
.box1 {
width: 100px;
height: 100px;
background: pink;
padding: 20px;
border: 10px rgba(0,0,0,0) solid;
margin: 20px;
}
.box2{
width: 100px;
height: 100px;
background: skyblue;
}
</style>
</head>

<body>
<div class="box1">我是一个盒子</div>
<div class="box2">我是另一个盒子</div>
</body>

</html>

CSS盒模型的注意点

padding不能为负值,而margin可以为负值

1
2
padding: -20px; #不生效
margin: 20px; #生效

背景色会平铺到非margin的区域
也就是说会覆盖到padding、border上面去。非margin都平铺到了!

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
<!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>Document</title>
<style>
.box1 {
width: 100px;
height: 100px;
background: pink;
padding: 20px;
border: 10px rgba(0,0,0,0.5) solid;
margin: 20px;
}
.box2{
width: 100px;
height: 100px;
background: skyblue;
}
</style>
</head>

<body>
<div class="box1">我是一个盒子</div>
<div class="box2">我是另一个盒子</div>
</body>

</html>

margin-top传递的现象及解决方案

现象:

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
<!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>Document</title>
<style>
.box1 {
width: 200px;
height: 200px;
background: pink;
}
.box2{
width:100px;
height:100px;
background:skyblue;
margin-top:30px;
}
</style>
</head>

<body>
<div class="box1">
<div class="box2"></div>
</div>

</body>

</html>

解决:

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1 {
width: 200px;
height: 200px;
background: pink;
border: 1px black solid;
}
.box2{
width:100px;
height:100px;
background:skyblue;
margin-top:30px;
}
</style>
</head>

<body>
<div class="box1">
<div class="box2"></div>
</div>

</body>

</html>

margin上下叠加的现象及解决方案

正常上下为70px的,现在是40px。解决方案是margin-bottommargin-top只加一个就可以。

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1 {
width: 200px;
height: 200px;
background: pink;
margin-bottom: 40px;
}

.box2 {
width: 100px;
height: 100px;
background: skyblue;
margin-top: 30px;
}
</style>
</head>

<body>
<div class="box1"></div>
<div class="box2"></div>

</body>

</html>

块级盒子与内联盒子

在 CSS 中我们广泛地使用两种“盒子” —— 块级盒子 (block box) 和 内联盒子 (inline box)。这两种盒子会在页面流(page flow)和元素之间的关系方面表现出不同的行为。

块级盒子:div、p、h1…内联盒子:span、a、strong…

块级盒子的特性

  • 独占一行
  • 支持所有样式
  • 不写宽度的时候,跟父容器的宽度相同
  • 所占区域是一个矩形

内联盒子的特性

  • 盒子不会产生换行
  • 有些样式不支持,例如:width、height等
  • 不写宽度的时候,宽度由内容决定
  • 所占的区域不一定是矩形
  • 内联标签之间会有空隙

自适应盒模型的特性

自适应盒模型指的是,当盒子不设置宽度时,盒模型相关组成部分的处理方式是如何的

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
<!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>Document</title>
<style>
.box1 {
width: 300px;
height: 200px;
background: pink;
}

/* .box2 {
width: 300px;
height: 100px;
background: skyblue;
padding:10px;
border:5px black solid;
margin:10px;
} */
.box2 {
/* width: 300px; */
height: 100px;
background: skyblue;
padding:10px;
border:5px black solid;
margin:10px;
}
</style>
</head>

<body>
<div class="box1">
<div class="box2">盒子的内容</div>
</div>
</body>

</html>

标准盒模型与怪异盒模

  • 在标准模型中,如果你给盒设置widthheight,实际设置的是content boxpaddingborder再加上设置的宽高一飞起决定整个盒子的大小。

  • 在怪异模型中,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1 {
width: 100px;
height: 100px;
background: pink;
padding: 10px;
border: 5px black solid;
box-sizing: border-box;
}

.box2 {
width: 400px;
height: 111px;
padding: 20px 0;
background: skyblue;
box-sizing: border-box;
}

input{
width:100%;
padding:30px;
box-sizing: border-box;
}
</style>
</head>

<body>
<div class="box1">一个盒子</div>
<div class="box2">
个人信息
</div>
<input type="text">
</body>

</html>

box-sizing属性

  • content-box:width、 height -> content
  • border-box:width、 height -> content + padding + border
  • 应用1:量取尺寸时不用再去计算一些值
  • 应用2:解决一些需要设置百分比和盒模型值

浮动样式详解

当元素被浮动时,会脱离文档流,根据float的值向左或向右移动,直到它的外边界碰到父元素的内边界或另一个浮动元素的外边界为止,是CSS布局中实现左右布局的一种方式

文档流:文档流是元素在Web贝面上的一种呈现万式,按照出现的先后顺序进行排列。

请看下图,当把框 1 向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘:

再请看下图,当框 1 向左浮动时,它脱离文档流并且向左移动,直到它的左边缘碰到包含框的左边缘。因为它不再处于文档流中,所以它不占据空间,实际上覆盖住了框 2,使框 2 从视图中消失。

如果把所有三个框都向左移动,那么框 1 向左浮动直到碰到包含框,另外两个框向左浮动直到碰到前一个浮动框。

如下图所示,如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”:

清楚浮动的方案

  • clear属性
  • BFC
  • 空标签
  • .clearfix::after{}

现象:

清楚浮动后

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
<!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>Document</title>
<style>
/* .box1{
width:100px;
height:100px;
background:pink;
float:left;
}
.box2{
width:200px;
height:200px;
background:skyblue;
clear:both;
} */

.box1 {
width: 200px;
border: 1px black solid;
}

.box2 {
width: 100px;
height: 100px;
background: pink;
float:left;
}

.clearfix::after{
content : "";
clear:both;
display:block;
}
</style>
</head>

<body>
<!-- <div class="box1"></div>
<div class="box2"></div> -->
<!-- <div class="box1">
<div class="box2"></div>
<div style="clear:both;"></div>
</div>
aaaaaaaaa -->

<div class="box1 clearfix">
<div class="box2"></div>
</div>
aaaaaaaaa
</body>

</html>

浮动特性注意点

  • 只会影响后面的元素
  • 文本不会被浮动元素覆盖
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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:100px;
height:100px;
background:pink;
}
.box2{
width:200px;
height:200px;
background:skyblue;
float:left;
}
.box3{
width:300px;
height:300px;
background:red;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3">我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子我是一个浮动的盒子</div>
</body>
</html>
  • 具备内联盒子特性:宽度由内容决定
  • 具备块级盒子特性:支持所有样式
  • 浮动放不下,会自动换行

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
<!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>Document</title>
<style>
/* .box{
background:red;
float:left;
} */

/* .inline{
width:100px;
height:100px;
background:red;
float:left;
} */
.wrapper {
width: 300px;
height: 300px;
background: pink;
}

.wrapper div {
width: 100px;
height: 100px;
border: 1px yellow solid;
box-sizing: border-box;
float: left;
}
</style>
</head>

<body>
<!-- <div class="box">aaaaaaaaaa</div> -->
<!-- <span class="inline">bbbbbbbbb</span> -->

<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
</body>

</html>

定位样式详解

CSS position属性用于指定一个元素在文档中的定位方式,其中top,right,bottom和left属性则决定了该元素的最终位置。

相对定位及特性

  • 相对定位的元素是在文档中的正常位置偏移给定的值

  • 不影响其他元素布局

  • 相对于自身进行偏移

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box1{
width:100px;
height:100px;
background:pink;
}
.box2{
width:100px;
height:100px;
background:skyblue;
position: relative;
left:100px;
top:100px;
/* margin-left:100px;
margin-top:100px; */
}
.box3{
width:100px;
height:100px;
background:red;
}
</style>
</head>
<body>
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
.box2{
width:100px;
height:100px;
background:skyblue;
position: relative;
left:100px;
top:100px;
/* margin-left:100px;
margin-top: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
33
34
35
36
37
<!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>Document</title>
<style>
.box1{
width:100px;
height:100px;
background:pink;
}
.box2{
/* width:100px;
height:100px;
background:skyblue;
position: absolute; */

width:100px;
height:100px;
background:skyblue;
position: absolute;
}
.box3{
width:100px;
height:100px;
background:red;
}
</style>
</head>
<body>
<div class="box1"></div>
<span class="box2">aaaaaaaaaaaaaa</span>
<div class="box3"></div>
</body>
</html>
  • 具备块级盒子特性:支持所有样式
  • 绝对定位元素相对于最近的非static祖先元素定位。当这样的祖先元素不存在时,则相对于可视区定位

固定定位及特性

  • 固定定位与绝对定位相似,但是会固定在可视区中

  • 具备内联盒子特性:宽度由内容决定

  • 具备块级盒子特性:支持所有样式

  • 固定定位元素不受祖先元素影响

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
<!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>Document</title>
<style>
body{
height:2000px;
/* position: relative; */
}
.box1{
width:500px;
height:500px;
border:1px black solid;
margin:200px;
/* position: relative; */
}
.box2{
width:100px;
height:100px;
background:pink;
position: fixed;
left:0;
top:0;
}
</style>
</head>
<body>
<div class="box1">
<div class="box2"></div>
</div>
</body>
</html>

黏性定位及特性

  • 粘性定位可以被认为是相对定位和固定定位的混合。元素在跨越特定國值前为相对定位,之后为固定定位

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
<!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>Document</title>
<style>
body{
height:2000px;
}
p {
margin-top: 20px;
}
div{
position: sticky;
top : 0;
}
</style>
</head>

<body>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<div>这是一个粘性盒子</div>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
<p>pppppppppppppppppp</p>
</body>

</html>

z-index,如果写在父标签上,权重就以它的为准。

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 http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>

.parent{
position: absolute;
z-index: 1;
}
.box1 {
width: 100px;
height: 100px;
background: red;
position: absolute;
left: 0;
top: 0;
z-index: 3;
}

.box2 {
width: 100px;
height: 100px;
background: blue;
position: absolute;
left: 50px;
top: 50px;
z-index: 2;
}
</style>
</head>

<body>
<div class="parent">
<div class="box1"></div>
</div>
<div class="box2"></div>
</body>

</html>

详解display属性

display属性的作用

在CSS中display属性表示“显示框类型”,即不同的盒模型。简单来说,可以把块级盒子转成内联盒子,也可以把内联盒子转成块级盒子。

1
2
3
4
5
6
7
8
<style>
.box1{ display:inline; background:gold;}
.box2{ display:block; background:skyblue;}
</style>
<div class="box1">块1</div>
<div class="box1">块2</div>
<span class="box2">内联1</span>
<span class="box2">内联2</span>

可以看到,div具备了内联盒子的特性,而span则具备了块级盒子的特性。当然display远比这些复杂的多,像我们后面章节中讲到的弹性布局、网格布局等都是跟display有着紧密关系。

display属性大概可分为以下几类进行学习:

display-outside(外部值)

外部值就是定义自身元素的外部表现,而不影响其内的子元素。

  • block:表示块级盒子 像

    等默认就是块级盒子。
  • inline:表示内联盒子 像 等默认就是内联盒子。
  • run-in:实验性质的属性,浏览器支持不好。

display-inside(内部值)

和外部值相反,内部值就是定义子元素布局的。像flex、grid这些设置都会影响到子元素的布局形式,后面章节将详细的对flex和grid进行讲解。

  • flow-root:一个BFC的块级盒子(注:BFC后面小节会讲解)。
  • table:带有内部表格布局的块级盒子。
  • flex:带有内部弹性布局的块级盒子。
  • grid:带有内部网格布局的块级盒子。

display-listitem(列表值)

list-item属性值是生成一个容纳内容和单独的列表行内元素盒的块级盒子,目的是为了用div去代替

  • 标签之类的,
  • 元素默认就是list-item;

    display-internal(属性值)

    一些和table布局、ruby搭配一起控制页面布局的属性值,因为使用的比较少,这里不展开探讨。

    display-box(显示值)

    • contents:只影响其内容的样式生效,比如:字体大小、文字颜色等;但是像背景色、边框是不会生效的。
    • none:从盒子树中移除,包括其所有后代元素。

    display-legacy(混合值)

    • inline-block:对外表现成内联盒子,对内表现成块级盒子
    • inline-table:对外表现成内联盒子,对子元素表现成表格盒子
    • inline-flex:对外表现成内联盒子,对子元素表现成弹性盒子
    • inline-grid:对外表现成内联盒子,对子元素表现成网格盒子

    下面通过代码来演示一下inline-block的特性:

    1
    2
    3
    4
    5
    6
    7
    <style>
    .box{ display:inline-block; width:100px; height:100px; background:gold;}
    </style>
    <div class="box">块1</div>
    <div class="box">块2</div>
    <span class="box">内联1</span>
    <span class="box">内联2</span>

    可以看到,盒子即具备了块级盒子的特性(支持宽高)又具备了内联盒子的特性(横向排列)。 关于inline-flexinline-grid的特性会在相关章节中进行讲解。

    global(全局值)

    • inherit:继承父元素的display属性
    • initial:不管父元素怎么设定,恢复到浏览器最初始时的display属性
    • unset:unset混合了 inherit 和 initial。如果父元素设值了,就用父元素的设定,如果父元素没设值,就用浏览器的缺省设定。

    书写模式与逻辑属性

    书写模式

    绝大多数国家的阅读方式都是从左到右进行的,但是也有一小部分国家的阅读方式,可能是从右向左或从上到下。比如阿拉伯国家就是从右向左进行阅读的,所以在网页排版的时候,就要考虑到这个情况,尤其是做国际站的同学们。

    书写模式即writing-mode属性,可以帮助以上下阅读的国家去展示网页内容。它定义了文本水平或垂直排布以及在块级元素中文本的行进方向。

    可选值有:

    • horizontal-tb 水平方向自上而下的书写方式

    • vertical-rl 垂直方向自右而左的书写方式

    • vertical-lr 垂直方向自左而右的书写方式

    • sideways-rl 内容垂直方向从上到下排列

    • sideways-lr 内容垂直方向从下到上排列

    注:目前sideways-rl和sideways-lr的兼容性并不是很好。

    逻辑属性

    如果一套代码想实现国际化,处理不同国家的排版方式时,就会导致无法实现。代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <style>
    body{
    border:1px black solid;
    height:100px;
    }
    div{
    border:1px red solid;
    float:left;
    margin-left:30px;
    }
    </style>
    <div>hello world</div>
    <div>hello world</div>

    接下来给body添加垂直方向自左而右的书写方式,可以发现布局出现了混乱,height属性依然只针对高度,而margin-left属性也依然只针对左间距。

    1
    2
    3
    4
    5
    body{
    border:1px black solid;
    height:100px;
    writing-mode:vertical-lr; /* 新增样式 */
    }

    那么如何更好的处理不同的书写模式呢?就要配合逻辑属性了。逻辑属性是从逻辑角度控制布局,而不是从物理、方向或维度来控制。

    简单来说,物理属性和值指的是width、height、left、top、right、bottom等值;而逻辑属性和值指的是start、end、inline-start、inline-end、block-start、block-end等值。其中block表示垂直方向,inline表示水平方式,在不同的书写模式下,block和inline所代表的方向是会发生变化的。理解逻辑属性对于后面章节中理解弹性布局和网格布局也有非常大的帮助。

    下面用逻辑属性和值修改一下之前代码中出现的问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    body{
    border:1px black solid;
    block-size:100px; /* 修改样式 height:100px; */
    writing-mode:vertical-lr;
    }
    div{
    border:1px red solid;
    float:left;
    margin-inline-start:30px; /* 修改样式 margin-left:30px; */
    }

    下面再举一个例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style>
    section {
    text-align: start; /* start 逻辑值 */
    }
    h2 {
    border-inline-start: .3em solid #ccc; /* border-inline-start 逻辑属性 */
    padding-inline-start: .5em; /* padding-inline-start 逻辑属性 */
    }
    </style>
    <section dir="auto">
    <h2>第一章<h2>
    <div>本章介绍了逻辑属性和逻辑值,这是一个演示示例。div>
    <section>
    <section dir="auto">
    <h2>الفصل الأول<h2>
    <div>يقدم هذا الفصل القيم المنطقية والمنطقية ، والتي هي مثال توضيحي.div>
    <section>

    注:dir属性可以设置元素的显示方向,是从左往右(ltr),还是从右往左(rtl),当设置auto时会自动根据当前语言决定排列方向,dir属性非常适合那些从右向左进行阅读的国家,例如:阿拉伯语,波斯语,希伯来语等。

    BFC块级格式化上下文

    BFC概念

    BFC即Block Formatting Contexts(块级格式化上下文),它是W3C CSS2.1 规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

    具有BFC特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容器所没有的一些特性。

    通俗一点来讲,可以把BFC理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。

    BFC触发条件

    满足以下条件之一,即可触发BFC:

    • float的值不是none
    • position的值不是static或者relative
    • display的值是inline-block、table-cell、flex、table-caption或者inline-flex
    • overflow的值不是visible

    下面的box盒子就是一个BFC独立容器:

    1
    2
    3
    4
    5
    .box{
    width: 100px;
    height: 100px;
    overflow: hidden; /* 触发了BFC,形成独立盒子 */
    }

    BFC的应用

    在前面介绍盒模型的margin时,出现了传递和叠加的问题,这里可以采用BFC规范来解决,原理就是让盒子形成一个独立的容器,无论里面的子元素如何折腾,都不影响到外面的元素。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <style>
    .box1 {
    width: 200px;
    height: 200px;
    background: pink;
    overflow: hidden; /* 触发了BFC,形成独立盒子 */
    }
    .box2{
    width: 100px;
    height: 100px;
    background: skyblue;
    margin-top: 30px;
    }
    </style>
    <div class="box1">
    <div class="box2"></div>
    </div>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <style>
    section{
    overflow: hidden; /* 触发了BFC,形成独立盒子 */
    }
    .box1 {
    width: 200px;
    height: 200px;
    background: pink;
    margin-bottom: 40px;
    }

    .box2 {
    width: 100px;
    height: 100px;
    background: skyblue;
    margin-top: 30px;
    }
    </style>
    <section>
    <div class="box1"></div>
    </section>
    <section>
    <div class="box2"></div>
    </section>

    BFC还可以解决前面浮动遇到了父容器高度塌陷的问题,也就是不管里面子元素是否浮动,都不会因为脱离文档流对容器高度造成影响。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <style>
    .box1 {
    width: 200px;
    border: 1px black solid;
    overflow: hidden; /* 触发了BFC,形成独立盒子 */
    }
    .box2 {
    width: 100px;
    height: 100px;
    background: pink;
    float: left;
    }
    </style>
    <div class="box1">
    <div class="box2"></div>
    </div>

    在现代布局flex和grid中,是默认自带BFC规范的,所以可以解决非BFC盒子的一些问题,这就是为什么flex和grid能成为更好的布局方式原因之一。

    标签默认样式及清除

    标签默认样式

    一些HTML标签在浏览器中会有默认样式,例如:body标签会有margin:8px;ul标签会有margin:16px 0;及padding-left:40px。

    当我们在切图软件中进行尺寸或位置测量的时候,把测量出来的数值设置到对应的标签上时,可能会受到当前标签默认样式的影响,从而页面显示效果跟设计图效果不符。

    清除默认样式

    通常在网页开发中,要去掉这些影响尺寸和位置的默认样式及其他影响布局的默认值。可以参考CSS Tools: Reset CSS方案。

    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
    html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed,
    figure, figcaption, footer, header, hgroup,
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
    }
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure,
    footer, header, hgroup, menu, nav, section {
    display: block;
    }
    body {
    line-height: 1;
    }
    ol, ul {
    list-style: none;
    }
    blockquote, q {
    quotes: none;
    }
    blockquote:before, blockquote:after,
    q:before, q:after {
    content: '';
    content: none;
    }
    table {
    border-collapse: collapse;
    border-spacing: 0;
    }

    由于Reset CSS相对“暴力”,不管你有没有用,统统重置成一样的效果,且影响的范围很大,所以更加“平和”的一种方式Normalize CSS诞生了。

    Normalize CSS可以看成是一种Reset CSS的替代方案。创造Normalize CSS有下面这几个目的:

    • 保护有用的浏览器默认样式而不是完全去掉它们
    • 一般化的样式:为大部分HTML元素提供
    • 修复浏览器自身的bug并保证各浏览器的一致性
    • 优化CSS可用性:用一些小技巧
    • 解释代码:用注释和详细的文档来
    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
    html {
    line-height: 1.15; /* 1 */
    -webkit-text-size-adjust: 100%; /* 2 */
    }
    body {
    margin: 0;
    }
    main {
    display: block;
    }
    h1 {
    font-size: 2em;
    margin: 0.67em 0;
    }
    hr {
    box-sizing: content-box; /* 1 */
    height: 0; /* 1 */
    overflow: visible; /* 2 */
    }
    pre {
    font-family: monospace, monospace; /* 1 */
    font-size: 1em; /* 2 */
    }
    a {
    background-color: transparent;
    }
    abbr[title] {
    border-bottom: none; /* 1 */
    text-decoration: underline; /* 2 */
    text-decoration: underline dotted; /* 2 */
    }
    b,
    strong {
    font-weight: bolder;
    }
    code,
    kbd,
    samp {
    font-family: monospace, monospace; /* 1 */
    font-size: 1em; /* 2 */
    }
    small {
    font-size: 80%;
    }
    sub,
    sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
    }
    sub {
    bottom: -0.25em;
    }
    sup {
    top: -0.5em;
    }
    img {
    border-style: none;
    }
    button,
    input,
    optgroup,
    select,
    textarea {
    font-family: inherit; /* 1 */
    font-size: 100%; /* 1 */
    line-height: 1.15; /* 1 */
    margin: 0; /* 2 */
    }
    button,
    input { /* 1 */
    overflow: visible;
    }
    button,
    select { /* 1 */
    text-transform: none;
    }
    button,
    [type="button"],
    [type="reset"],
    [type="submit"] {
    -webkit-appearance: button;
    }
    button::-moz-focus-inner,
    [type="button"]::-moz-focus-inner,
    [type="reset"]::-moz-focus-inner,
    [type="submit"]::-moz-focus-inner {
    border-style: none;
    padding: 0;
    }
    button:-moz-focusring,
    [type="button"]:-moz-focusring,
    [type="reset"]:-moz-focusring,
    [type="submit"]:-moz-focusring {
    outline: 1px dotted ButtonText;
    }
    fieldset {
    padding: 0.35em 0.75em 0.625em;
    }
    legend {
    box-sizing: border-box; /* 1 */
    color: inherit; /* 2 */
    display: table; /* 1 */
    max-width: 100%; /* 1 */
    padding: 0; /* 3 */
    white-space: normal; /* 1 */
    }
    progress {
    vertical-align: baseline;
    }
    textarea {
    overflow: auto;
    }
    [type="checkbox"],
    [type="radio"] {
    box-sizing: border-box; /* 1 */
    padding: 0; /* 2 */
    }
    [type="number"]::-webkit-inner-spin-button,
    [type="number"]::-webkit-outer-spin-button {
    height: auto;
    }
    [type="search"] {
    -webkit-appearance: textfield; /* 1 */
    outline-offset: -2px; /* 2 */
    }
    [type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
    }
    ::-webkit-file-upload-button {
    -webkit-appearance: button; /* 1 */
    font: inherit; /* 2 */
    }
    details {
    display: block;
    }
    summary {
    display: list-item;
    }
    template {
    display: none;
    }
    [hidden] {
    display: none;
    }

    在后面章节中编写的实战案例部分,会采用Normalize CSS和Reset CSS结合代码,形成一个更加强大的方案,文件命名为reset.css,代码如下,当然后面章节中也会直接把文件提供给同学们:

    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
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    @charset "utf-8";

    /* --------------------重置样式-------------------------------- */

    body,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6,
    hr,
    p,
    blockquote,
    dl,
    dt,
    dd,
    ul,
    ol,
    li,
    button,
    input,
    textarea,
    th,
    td {
    margin : 0;
    padding: 0
    }

    /*设置默认字体*/
    body {
    font-size : 14px;
    font-style : normal;
    font-family: -apple-system, BlinkMacSystemFont, segoe ui, Roboto, helvetica neue, Arial, noto sans, sans-serif, apple color emoji, segoe ui emoji, segoe ui symbol, noto color emoji;
    }

    /*字体太小用户体检不好,让small恢复12px*/
    small {
    font-size: 12px
    }

    h1 {
    font-size: 18px
    }

    h2 {
    font-size: 16px
    }

    h3 {
    font-size: 14px
    }

    h4,
    h5,
    h6 {
    font-size: 100%
    }

    ul,
    ol {
    list-style: none
    }

    a {
    text-decoration : none;
    background-color: transparent
    }

    a:hover,
    a:active {
    outline-width : 0;
    text-decoration: none
    }

    /*重置表格*/
    table {
    border-collapse: collapse;
    border-spacing : 0
    }

    /*重置hr*/
    hr {
    border: 0;
    height: 1px
    }

    /*图形图片*/
    img {
    border-style: none
    }

    img:not([src]) {
    display: none
    }

    svg:not(:root) {
    overflow: hidden
    }

    /*下面的操作是针对于html5页面布局准备的,不支持ie6~8以及其他低版本的浏览器*/
    html {
    /*禁用系统默认菜单*/
    -webkit-touch-callout : none;
    /*关闭iphone & Android的浏览器纵向和横向模式中自动调整字体大小的功能*/
    -webkit-text-size-adjust: 100%
    }

    input,
    textarea,
    button,
    a {
    /*表单或者a标签在手机点击时会出现边框或彩色的背景区域,意思是去除点击背景框*/
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
    }

    /*重置html5元素的默认样式*/
    article,
    aside,
    details,
    figcaption,
    figure,
    footer,
    header,
    main,
    menu,
    nav,
    section,
    summary {
    display: block
    }

    audio,
    canvas,
    progress,
    video {
    display: inline-block
    }

    audio:not([controls]),
    video:not([controls]) {
    display: none;
    height : 0
    }

    progress {
    vertical-align: baseline
    }

    mark {
    background-color: #ff0;
    color : #000
    }

    sub,
    sup {
    position : relative;
    font-size : 75%;
    line-height : 0;
    vertical-align: baseline
    }

    sub {
    bottom: -0.25em
    }

    sup {
    top: -0.5em
    }

    button,
    input,
    select,
    textarea {
    font-size: 100%;
    outline : 0
    }

    button,
    input {
    overflow: visible
    }

    button,
    select {
    text-transform: none
    }

    textarea {
    overflow: auto
    }

    button,
    html [type="button"],
    [type="reset"],
    [type="submit"] {
    -webkit-appearance: button
    }

    button::-moz-focus-inner,
    [type="button"]::-moz-focus-inner,
    [type="reset"]::-moz-focus-inner,
    [type="submit"]::-moz-focus-inner {
    border-style: none;
    padding : 0
    }

    button:-moz-focusring,
    [type="button"]:-moz-focusring,
    [type="reset"]:-moz-focusring,
    [type="submit"]:-moz-focusring {
    outline: 1px dotted ButtonText
    }

    [type="checkbox"],
    [type="radio"] {
    box-sizing: border-box;
    padding : 0
    }

    [type="number"]::-webkit-inner-spin-button,
    [type="number"]::-webkit-outer-spin-button {
    height: auto
    }

    [type="search"] {
    -webkit-appearance: textfield;
    outline-offset : -2px
    }

    [type="search"]::-webkit-search-cancel-button,
    [type="search"]::-webkit-search-decoration {
    -webkit-appearance: none
    }

    ::-webkit-input-placeholder {
    color : inherit;
    opacity: .54
    }

    ::-webkit-file-upload-button {
    -webkit-appearance: button;
    font : inherit
    }