理解float
。
什么是float
float
布局可以让一个box
移动到某一行的左边或者右边的边缘,float box
附近的line boxes
会环绕在float box
周围。
当一个box
向左向右浮动,直到自己的margin edge
碰触到containing block
的边缘或者其它float box
的margin edge
为止。如果box
是从一个line box
里面float
出来的,则这个float box
的top margin edge
会与line box
的顶部边缘对齐。
如果一个float box
在水平方向的浮动空间不够,则这个box
就会向下移动直到有足够的浮动空间给它。
float
会导致box
脱离文档流,会造成高度塌陷的问题。在float box
之后的line boxes
,如果在垂直方向上的位置关系与float box
发生重叠,则会自动缩减宽度以便为float box
的margin box
留出足够的空间,形成环绕效果。如果line box
在垂直方向的位置与float box
不重叠,则line box
不会缩减宽度。
看这个例子: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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.parent {
line-height: 30px;
color: #fff;
background-color: #ccc;
width: 500px;
min-height: 300px;
margin: 0 auto;
}
.child {
width: 100px;
height: 100px;
background-color: orange;
margin: 10px;
float: left;
}
.line1 {
background-color: red;
}
.line2 {
background-color: blue;
}
.line3 {
background-color: green;
}
.line4 {
background-color: sienna;
}
.line0 {
background-color:skyblue;
}
.line5 {
background-color: slateblue;
}
</style>
</head>
<body>
<div class="parent">
<div class="line0">0</div>
<div class="child"></div>
<div class="line1">1</div>
<div class="line2">2</div>
<div class="line3">3</div>
<div class="line4">4</div>
<div class="line5">5</div>
</div>
</body>
</html>
上面只有1、2、3、4的内的line box与floated
的div.child
在垂直位置上发生了重叠,所以它们的宽度自动缩减了,而0、5则没有。
如果一个line box
宽度缩减后太短了,以至于没法容纳任何的内容,则这个line box
会向下移动直到它的内容能够显示得下或者不再与float
发生重叠,之后宽度会自动恢复。比如这个例子:1
2p { width: 10em; border: solid aqua; }
span { float: left; width: 5em; height: 5em; border: solid blue; }
1 | <p> |
span
是float box
,理论上后面文本应该环绕它,但是这个文本是个连续单词不会自动折断,导致它对应的inline box
在变窄后的line box
里展示不下,所以line box
自动移动到了float box
下面展示。 当它到了下面的时候,其实宽度也是不够的,但是这个不是float
导致的,此时line box
旁边已经没有float box
了,所以line box
不会再向下移动,最后只能溢出了。
同一个BFC
中的,使用未脱离文档流的方式创建了新BFC
的box
、以及table
、或blocl-level
的替换元素,它们的border box
,不允许与它所在的BFC
中的任何float box
的margin box
发生重叠!如有必要,浏览器可以对这些BFC box
设置浮动清除以便让它们显示在 float box
的下面,但是如果空间足够的话,也可以将它们放置在float box
的旁边,甚至可以去缩减这些box
的border box
的宽度。 但是css2.1并没有定义浏览器什么时候可以把BFC box
放置在float box
旁边以及这些BFC box
可以缩减多少。 这个要点其实就能解释为什么新建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
37
38
39
40
41
42
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.contaienr {
color: #fff;
background-color: #ccc;
width: 500px;
min-height: 300px;
margin: 0 auto;
}
.aside {
float: left;
width: 100px;
min-height: 100px;
background-color: slateblue;
}
.main {
/* BFC */
display: table-cell;
width: 2000px;
min-height: 100px;
background-color: brown;
}
</style>
</head>
<body>
<div class="contaienr">
<div class="aside">coldplay</div>
<div class="main">something just like this</div>
</div>
</body>
</html>
float box
会有堆叠效果,看起来就像float box
创建了新的堆叠上下文一样,不同之处在于其它定位元素以及会创建新的堆叠上下文的元素都会参与到float box
的parent stacking context
当中。 这里介绍的堆叠上下文与格式化上下一样,是一个布局概念,跟z-index层级有关系。一开始的那句话,是一个类比,实际上float
并没有创建堆叠上下文,但是float
与文档流中的内容会产生堆叠效果。float box
可以与文档流中的其它box
发生重叠,float box
与block-level
的box
重叠是很容易的,那它如何与inline-box
重叠呢?line box
不是会环绕float
吗?有1种情况是可以让inline-box
与float
发生重叠的,就是利用负的margin值。 当float
与文档流中的内容发生重叠后,叠放顺序为:float
会渲染在非定位的block box
之上,在inline box
的内容之下。强调一定是非定位的block box
,因为定位的block box
会产生堆叠上下文,而此处讨论的堆叠效果,跟堆叠上下文没有关系。看下面的例子: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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.contaienr {
width: 500px;
padding: 10px;
border: 1px solid #ccc;
}
.p {
margin: 1em;
padding: 10px;
border: 5px solid #ccc;
}
.p span {
width: 100px;
height: 200px;
float: left;
background-color: skyblue;
margin: 10px;
}
.p div {
margin-left: -57px;
background: red;
color: #fff;
display: inline-block;
}
</style>
</head>
<body>
<div class="contaienr">
<div class="p">Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui vero quae nostrum debitis
<span></span>necessitatibus commodi, soluta ea amet perferendis magni voluptate provident nam. Dicta ducimus
rerum aspernatur id eaque assumenda.</div>
<div class="p">
<div>Lorem ipsum dolor</div> sit amet consectetur adipisicing elit. Qui vero quae nostrum debitis
necessitatibus commodi, soluta ea amet perferendis magni voluptate provident nam. Dicta ducimus rerum
aspernatur id eaque assumenda.
</div>
</div>
</body>
</html>
从效果图很清晰的看到,float
与文档流中的内容发生了重叠,float box
很明显地盖住了div
的边框,说明float box
渲染在block-level
的div
元素之上;然后有一个内层div,被变为了inline block box
,并设置了负的margin
值,导致它最后渲染在了float box
之上。
float
property
float
这个属性用来定义浮动方式,定义如下:
Value: left | right | none | inherit
初始值: none
应用于: 基本上所有元素
是否可被继承: 否
百分比计算: 不支持
- left 代表向左浮动
- right 代表向右浮动
- none 表示不浮动
以left
为例,来说明浮动的一些规则:
如果一个
box
是float: left
,并且在它之前还有left-floating
的boxes
,那么当前这个box
与前一个float box
的关系,要么是当前这个box
的left margin edge
紧贴着前一个float box
的right margin edge
,要么是当前这个box
的top margin edge
低于前一个float box
的bottom margin edge
。
看这个例子: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
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
.contaienr {
width: 500px;
height: 200px;
border: 1px solid #ccc;
color: #fff;
font-size: 20px;
margin: 0 auto;
}
div.a {
float: left;
width: 200px;
height: 150px;
background-color: slateblue;
}
div.b {
float: left;
width: 200px;
height: 80px;
background-color: steelblue;
}
div.c {
float: left;
width: 200px;
height: 50px;
background-color: violet;
}
</style>
</head>
<body>
<div class="contaienr">
<div class="a">A</div>
<div class="b">B</div>
<div class="c">C</div>
</div>
</body>
</html>下图是效果,图中
B
C
都贴在A
的右边,C
贴在B
的下面:
浮动相关规则:
- The left outer edge of a left-floating box may not be to the left of the left edge of its containing block. An analogous rule holds for right-floating elements.
- If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.
- The right outer edge of a left-floating box may not be to the right of the left outer edge of any right-floating box that is next to it. Analogous rules hold for right-floating elements.
- A floating box’s outer top may not be higher than the top of its containing block. When the float occurs between two collapsing margins, the float is positioned as if it had an otherwise empty anonymous block parent taking part in the flow. The position of such a parent is defined by the rules in the section on margin collapsing.
- The outer top of a floating box may not be higher than the outer top of any block or floated box generated by an element earlier in the source document.
- The outer top of an element’s floating box may not be higher than the top of any line-box containing a box generated by an element earlier in the source document.
- A left-floating box that has another left-floating box to its left may not have its right outer edge to the right of its containing block’s right edge. (Loosely: a left float may not stick out at the right edge, unless it is already as far to the left as possible.) An analogous rule holds for right-floating elements.
- A floating box must be placed as high as possible.
- A left-floating box must be put as far to the left as possible, a right-floating box as far to the right as possible. A higher position is preferred over one that is further to the left/right.
clear
property
clear
这个属性用来清除浮动,定义如下:
Value: none | left | right | both | inherit
初始值: none
应用于: block-level元素
是否可被继承: 否
百分比计算: 不支持
浮动清除
的作用是为了让元素的左右不出现float box
,只对相同BFC
中的float box
有效,同时对自己内部的float box
无效。
各个值的含义如下:
left
要求box
的top border edge
必须低于任何在它之前生成的left-floating box
的bottom margin edge
right
要求box
的top border edge
必须低于任何在它之前生成的left-floating box
的bottom margin edge
both
要求bot
的top border edge
必须低于任何在它之前生成的left-floating box
或right-floating box
的bottom margin edge
none
不清除浮动
非none
值的clear
属性,会在需要的时候,增加clearance
(间隙),clearance
会阻碍外边距合并,在盒子模型里面学margin合并的条件时了解过;clearance
这段空白的空间是加在被clear
的box
的top margin edge
之上的,以便能在垂直方向上把box
推到float box
的底下去。clearance
是看不到的。
clearance
效果:
clearance
这段空白空间大小如何计算出来呢?css官方文档里面有算法,浏览器替我们实现了。
float box
也可以设置清除浮动
,规则是:
- 设置了
clear: left
的float box
的top margin edge
必须低于它之前的任何left-floating box
的bottom margin edge
- 设置了
clear: right
的float box
的top margin edge
必须低于它之前的任何right-floating box
的bottom margin edge
- 设置了
clear: both
的float box
的top margin edge
必须低于它之前的任何left-floating box
和right-floating box
的bottom margin edge