终于开始讲浮动了。浮动的内容有点多,大家耐心点,我会分成三个部分来讲解。
第一部分先讲基础点。
浮动,英文名float,听这个名字就知道拥有这一功能的元素可以在普通流(normal flow)上漂流,就如同漂流瓶一般。。。
事实上呢,它还真是如此!
float box由float属性不为none的dom元素产生,它会先出现在普通流(normal flow)里,接着会脱离普通流(normal flow)并依据float的值尽可能的向左或向右漂移。
先来了解一下float属性。
属性名: float
值: left | right | none| inherit
初始值: none
继承性: 无
通过设定 float 为 left ,可以使得 float box 向左移动,与此同时,普通流中 float box左边的box会向右移动,设为right 则反之。当然,如果设为none,该dom元素就不为浮动元素,产生的box也就不会浮动。
是不是float box就可以酱紫随意的漂流呢。。。
当然不是!
在实际浮动时,float box需要考虑:
第一优先级:尽可能的高
在父元素产生的containing block(看第11条)里,只要有足够空间,float box就应尽可能的处在高处,但高到什么程度呢?有没有限制呢?会不会高于父元素产生containing block的上边缘(看第24条)或在它之前产生的普通流中的任意box的上边缘或先于它的其他float box的上边缘?
先看以下例子(测试工具:chrome 49.0)。
- 例一 普通情况下的float box VS 父元素产生的containing block的上边缘
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:200px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:solid 2px #5CBDD2;
}
.float-child{
width:100px;
height:50px;
float:left;
box-sizing:border-box;
border:solid 2px #E2D72F;
}
</style>
</head>
<body>
<div class='parent'>
<div class='float-child'>
float child
</div>
</div>
</body>
</html>
复制代码
这里解释一下普通情况下的float box,其实就是普通流中的box设置了float为left或right之后的box。那么非普通情况下的float box是什么呢,其实是兼具相对定位功能的float box,详情请参考这里。
- 例二 普通情况下的float box VS 在它之前产生的block box的上边缘
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:200px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:solid 2px #5CBDD2;
}
.float-child{
width:100px;
height:50px;
float:left;
box-sizing:border-box;
border:solid 2px #E2D72F;
}
.normal-child{
width: 500px;
height:100px;
border:solid 2px #E881B2;
}
</style>
</head>
<body>
<div class='parent'>
<div class='normal-child'>
normal block box
</div>
<div class='float-child'>
float child
</div>
</div>
</body>
</html>
复制代码
测试结果如下:
- 例三 普通情况下的float box VS 在它之前产生的line box 及inline-level box的上边缘
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:auto;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:solid 2px #5CBDD2;
}
.float-child{
width:100px;
height:50px;
float:left;
box-sizing:border-box;
border:solid 2px #E2D72F;
}
.normal-child{
border:solid 2px #E881B2;
line-height:60px;
}
</style>
</head>
<body>
<div class='parent'>
<span class='normal-child'>
normal inline box
</span>
<div class='float-child'>
float child
</div>
</div>
</body>
</html>
复制代码
测试结果如下:
因为line box是个虚拟的概念,并没有与之对应的dom元素,这里我借用 div.parent 的高度来比较。
div.parent 的高度设为auto,故它的高度应由子元素决定。看源代码,我们知道它有两个子元素:span 元素 及 浮动元素。那么我们是不是就认为 div.parent 高度就是两个子元素撑起来的高度呢?
其实这里有个特例。
在普通流中,对于非replaced 元素产生的block box, 若overflow属性为visible,在计算高度时,如果子元素为浮动元素,子元素的高度是不参与父元素高度计算过程的。
在本例中,我并没有设置div.parent的overflow,故overflow会取它的默认值visible。那么div.parent 的高度就只由span元素决定。span元素产生一个inline box,该box会由一个高度为60px 的line box包裹着,而line box会由div.parent包裹着,这就决定了:
div.parent的高度 = line box的高度
line box的高度 >= inline box的高度
得出这个结论,我们就好比较了。从上例明显看出,float box与line box 在同一行,float box的上边缘等于在它之前产生的 line box的上边缘。那如果float 与line box不在同一行,高度是怎样的呢?
将float box的宽度由100px改为500px,测试结果如下:
可见,float box会因为上一行空间不够而下移,上边缘与containing block的下边缘重合, 高度低于在它之前产生的line box以及inline-level box。综合上面两例,我们可得到:普通情况下的float box的上边缘不高于在它之前产生的line box 及inline-level box的上边缘。
- 例四 普通情况下的float box VS 在它之前产生的float box的上边缘
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:100px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:solid 2px #5CBDD2;
}
.float-child{
width:200px;
height:50px;
float:left;
box-sizing:border-box;
border:solid 2px #E2D72F;
}
</style>
</head>
<body>
<div class='parent'>
<span class='float-child'>
first float child
</span>
<div class='float-child'>
second float child
</div>
</div>
</body>
</html>
复制代码
测试结果如下:
很明显,普通情况下的float box的上边缘是等于在它之前产生的float box的上边缘 。如果第一个float box的宽度足够大,剩余宽度不够放置第二个float box,那么第二个float box会浮动到第一个float box的下方。可见, 普通情况下的float box的上边缘是不高于在它之前产生的float box的上边缘。- 例五 兼具相对定位功能的float box VS 父元素产生的containing block的上边缘
<html>
<head>
<style type="text/css">
.parent{
width:500px;
height:200px;
margin-top:50px;
margin-left:auto;
margin-right:auto;
border:solid 2px #5CBDD2;
}
.float-child{
width:100px;
height:50px;
float:left;
position:relative;
top:-10px;
box-sizing:border-box;
border:solid 2px #E2D72F;
}
</style>
</head>
<body>
<div class='parent'>
<div class='float-child'>
float child
</div>
</div>
</body>
</html>
复制代码
在例一的基础上为float box设置了相对正常位置上浮10px,测试结果如下:
很明显,float box会高出父元素产生的containing block的上边缘10px。因此,如果float box被设置了相对定位,它的位置会在正常位置(即在普通情况下的位置)的基础上根据开发人员设定的值去浮动,我们也就没办法和父元素产生的containing block进行高度比较,同理和其他box作比较。
综合上述,我们能得出酱紫一个结论:普通情况下的float box在浮动过程中会尽可能的向高处浮动,但是不高于父元素产生的containing block的上边缘、在它之前产生的普通流中的任意box的上边缘以及在它之前产生的float box的上边缘;兼具相对定位的float box没办法和其他box进行高度比较,实际位置由开发人员控制。
第二优先级:尽可能的左 或 右
在尽可能高之后,float box会根据float属性值尽可能的靠左或靠右。
对于一个向左浮动的float box,如果它之前没有其他向左浮动的 float box,那么它会尽可能的靠近父元素产生的containing block的左边缘(参考例一);如果有,则它的左边缘会挨着前一个 float box的右边缘(参考例四)。向右浮动的float box反之。
浮动元素的基础讲的差不多了,大家需要记住的是它在浮动的过程中会优先往高处浮动,其次再尽可能的向左或向右浮动,至于它身上的其他特殊现象,敬请期待下回讲解!
ps: 所有例子均是在chrome 上测试。