CSS中,通过 float属性,任何元素都可以浮动,取值 left 让一个元素向左浮动,取值 right 则向右浮动。
浮动会影响包含块中的布局,如果一个包含块中存在浮动框,则先让所有的框按照普通流中的位置摆放,再将浮动框从文档流中取出来,并让浮动框从包含块的顶部开始,根据浮动方向一个接一个地水平排列。
浮动元素的包含块,是它最近的块级祖先元素(或表格单元格、或行内块祖先元素)的内容边界。向左浮动的元素,尽可能向左移动,直到碰到包含块的左边界。向右浮动的元素,尽可能向右移动,直到碰到包含块的右边界。
假设在一个容器中,有两个子元素,一个向左浮动,一个向右浮动:
<div class = "wrapper">
<div class = "floatL">box1 </div>
<div class = "floatR">box2 </div>
</div>
现在,为容器设置 10px 的内边距,为了便于观察,为容器和子元素设置了边框,并为向左和向右浮动元素添加指示箭头:
.wrapper {
width: 320px;
padding: 10px;
overflow: hidden;
border: 2px dashed #ccc;
}
.wrapper div {
width: 80px;
height: 60px;
border: 1px dashed #444;
}
.floatL {
float: left;
background: url(img/fl.png) 50% 36% no-repeat;
}
.floatR {
float: right;
background: url(img/fr.png) 50% 36% no-repeat;
}
上述代码的运行结果如图 5‑21 所示:
图5-21 框可以向左或向右浮动
从上图可以看出,无论向左浮动,还是向右浮动,浮动元素左右边界,都不会超过包含块内容区的左右边界。并且,浮动元素的上边界,也不会超过包含块内容区的上边界。
一个浮动元素,无论它是块级元素,还是行内级元素,都会生成一个块级框,并可以为它指定宽度和高度。如果没有显式设置宽度和高度,它的宽度和高度由其内容决定,但不超过包含块的宽度和高度。
假设在一个段落中,有两个 span 子元素,一个向左浮动,一个向右浮动。向左浮动的元素设置了宽度和高度,而向右浮动的元素没有设置宽度和高度:
<p>
<span class = "floatL">float left</span>
<span class = "floatR">float right</span>
</p>
p {
border: 1px solid #ccc;
}
span {
border: 1px dashed #ccc;
}
.floatL {
float: left;
width: 200px;
height: 40px;
}
.floatR {
float: right;
}
上述代码的运行结果如图 5‑22 所示:
图5-22 浮动元素的宽度和高度
从上图可以看出,未设置宽度和高度的元素,其尺寸由其内容决定,而设置宽度和高度元素则使用设置的尺寸。由于包含块的高度为 auto,其高度被向左浮动的元素撑开。
虽然浮动元素生成的也是块级框,但跟块级元素生成的块级框不同的是,浮动框的旁边允许放置其他的框。也就是说,浮动框可以跟块级框、或行内级框、或浮动框在同一行内水平显示。
由于浮动框已经脱离文档流,当浮动框和块级框并列时,同一行中的块级框会无视浮动框的存在,并占满一整行。这种情况下,块级框会处在浮动框的下层,也无法通过 z-index 属性改变它们的堆叠顺序。但是,块级框中的文本会环绕着浮动框,不会被浮动框覆盖,其效果跟印刷排版中的文本环绕相似。
假设有一个容器中,有一幅图像和一个段落,图像向左浮动。为了便于观察,为段落添加背景:
<div>
<img src = "img/img.gif" style = "float:left;" />
<p>无论是块级元素,…,浮动元素的旁边允许放置其他元素。</p>
</div>
div {
width: 300px;
border: 1px dashed #ccc;
}
p {
font-size: 13px;
line-height: 2;
background: #ddd;
}
img {
float: left;
}
上述代码的运行结果如图 5‑23 所示:
图5-23 浮动框与块级框并列
从上图可以看出,图像会生成一个浮动框,并且,浮动框和段落都紧贴包含块的左内边界,导致段落被浮动框覆盖,而段落中的文本所形成的行框却向右移动,并水平变窄来给浮动框腾出空间。随着文本的增加,后面的文本又会紧贴包含块的左内边界,因为它不再受浮动框的影响,无需再向右移动了。
如果浮动框和行内级框并列,浮动框将被置于包含块和行框的外边界之间,使行框的水平可用空间减少,导致行框的宽度变窄。
假设在一个段落中,有四个 span 子元素,一个向左浮动,一个向右浮动,其余两种不进行浮动:
<p>
<span>inline element 1</span>
<span class = "floatL">float left</span>
<span class = "floatR">float right</span>
<span>inline element 2</span>
</p>
为了便于观察,为 span 元素添加了 1px 的虚线边框:
p {
border: 1px solid #ccc;
}
span {
border: 1px dashed #ccc;
}
.floatL {
float: left;
}
.floatR {
float: right;
}
上述代码的运行结果如图 5‑24 所示:
图5-24 浮动框与行内级框并列
从上图可以看出,由于浮动框的存在,行框的宽度变窄,当行框的水平空间不足时,行内级框会自动换行。由于受浮动框高度的影响,行内级框被浮动框卡住。
如果多个浮动框并列时,它们会按在HTML中的定义顺序,一个接一个,依次水平排列,每个框按照各自的方向浮动。
假设所有的三个框都向左浮动,则框 1 向左浮动,直到碰到包含块内容区域的边界,另外两个框向左浮动,直到碰到前一个浮动框。如图 5‑25 所示:
图5-25 所有三个框都向左浮动
假设所有的三个框都向右浮动,情况与全部向左浮动类似。在HTML代码中,框 1 最先被定义,所以排在最右边,框 3 最后被定义,所以排在最左边。如图 5‑26 所示:
图5-26 所有三个框都向右浮动
如果在一行内无法容纳所有的浮动框,则后面的框会向下移动,直到有足够的空间。如果浮动框的高度不同,在向下移动时,可能被其它浮动框“卡住”。如图 5‑27 所示:
图5-27 浮动框下移到有足够空间的地方
如果多个框的浮动方向不尽相同,情况会怎样呢?假设有六个浮动框,按从小到大的顺序依次定义,框 1、2、5向左浮动,框 3、4、6向右浮动。运行结果如图 5‑28 所示:
图5-28 不同方向浮动的框
从上图可以看出,当框的浮动方向不尽相同时,会按照在HTML中定义的顺序,摆放每一个框,如果一行内空间不足,后面的框会自动下移,形成多行,在每一行中,每个框按照各自的方向浮动。
关于作者
歪脖先生,十五年以上软件开发经验,酷爱Web开发,精通 HTML、CSS、JavaScript、jQuery、JSON、Python、Less、Bootstrap等,著有《HTML宝典》、《揭秘CSS》、《Less简明教程》、《JSON教程》、《Bootstrap2用户指南》、《Bootstrap3实用教程》,并全部在 GitHub 上开源。