CSS中,通过 float属性,任何元素都可以浮动,取值 left 让一个元素向左浮动,取值 right 则向右浮动。

浮动会影响包含块中的布局,如果一个包含块中存在浮动框,则先让所有的框按照普通流中的位置摆放,再将浮动框从文档流中取出来,并让浮动框从包含块的顶部开始,根据浮动方向一个接一个地水平排列。

浮动元素的包含块,是它最近的块级祖先元素(或表格单元格、或行内块祖先元素)的内容边界。向左浮动的元素,尽可能向左移动,直到碰到包含块的左边界。向右浮动的元素,尽可能向右移动,直到碰到包含块的右边界。

假设在一个容器中,有两个子元素,一个向左浮动,一个向右浮动:


  1. <div class = "wrapper">
  2.    <div class = "floatL">box1 </div>
  3.    <div class = "floatR">box2 </div>
  4. </div>

现在,为容器设置 10px 的内边距,为了便于观察,为容器和子元素设置了边框,并为向左和向右浮动元素添加指示箭头:


  1. .wrapper {
  2.     width: 320px;
  3.     padding: 10px;
  4.     overflow: hidden;
  5.     border: 2px dashed #ccc;
  6. }
  7. .wrapper div {
  8.     width: 80px;
  9.     height: 60px;
  10.     border: 1px dashed #444;
  11. }
  12. .floatL {
  13.     float: left;
  14.     background: url(img/fl.png) 50% 36% no-repeat;
  15. }
  16. .floatR {
  17.     float: right;
  18.     background: url(img/fr.png) 50% 36% no-repeat;
  19. }

上述代码的运行结果如图 5‑21 所示:

CSS 浮动 float属性-编程知识网图5-21 框可以向左或向右浮动

从上图可以看出,无论向左浮动,还是向右浮动,浮动元素左右边界,都不会超过包含块内容区的左右边界。并且,浮动元素的上边界,也不会超过包含块内容区的上边界。

一个浮动元素,无论它是块级元素,还是行内级元素,都会生成一个块级框,并可以为它指定宽度和高度。如果没有显式设置宽度和高度,它的宽度和高度由其内容决定,但不超过包含块的宽度和高度。

假设在一个段落中,有两个 span 子元素,一个向左浮动,一个向右浮动。向左浮动的元素设置了宽度和高度,而向右浮动的元素没有设置宽度和高度:


  1. <p>
  2. <span class = "floatL">float left</span>
  3. <span class = "floatR">float right</span>
  4. </p>

  1. p {
  2.     border: 1px solid #ccc;
  3. }
  4. span {
  5.     border: 1px dashed #ccc;
  6. }
  7. .floatL {
  8.     float: left;
  9.     width: 200px;
  10.     height: 40px;
  11. }
  12. .floatR {
  13.     float: right;
  14. }

上述代码的运行结果如图 5‑22 所示:

CSS 浮动 float属性-编程知识网图5-22 浮动元素的宽度和高度

从上图可以看出,未设置宽度和高度的元素,其尺寸由其内容决定,而设置宽度和高度元素则使用设置的尺寸。由于包含块的高度为 auto,其高度被向左浮动的元素撑开。

虽然浮动元素生成的也是块级框,但跟块级元素生成的块级框不同的是,浮动框的旁边允许放置其他的框。也就是说,浮动框可以跟块级框、或行内级框、或浮动框在同一行内水平显示。

由于浮动框已经脱离文档流,当浮动框和块级框并列时,同一行中的块级框会无视浮动框的存在,并占满一整行。这种情况下,块级框会处在浮动框的下层,也无法通过 z-index 属性改变它们的堆叠顺序。但是,块级框中的文本会环绕着浮动框,不会被浮动框覆盖,其效果跟印刷排版中的文本环绕相似。

假设有一个容器中,有一幅图像和一个段落,图像向左浮动。为了便于观察,为段落添加背景:


  1. <div>
  2. <img src = "img/img.gif" style = "float:left;" />
  3. <p>无论是块级元素,…,浮动元素的旁边允许放置其他元素。</p>
  4. </div>

  1. div {
  2.    width: 300px;
  3.    border: 1px dashed #ccc;
  4. }
  5. p {
  6.    font-size: 13px;
  7.    line-height: 2;
  8.    background:  #ddd;
  9. }
  10. img {
  11.    float: left; 
  12. }

上述代码的运行结果如图 5‑23 所示:

CSS 浮动 float属性-编程知识网图5-23 浮动框与块级框并列

从上图可以看出,图像会生成一个浮动框,并且,浮动框和段落都紧贴包含块的左内边界,导致段落被浮动框覆盖,而段落中的文本所形成的行框却向右移动,并水平变窄来给浮动框腾出空间。随着文本的增加,后面的文本又会紧贴包含块的左内边界,因为它不再受浮动框的影响,无需再向右移动了。

如果浮动框和行内级框并列,浮动框将被置于包含块和行框的外边界之间,使行框的水平可用空间减少,导致行框的宽度变窄。

假设在一个段落中,有四个 span 子元素,一个向左浮动,一个向右浮动,其余两种不进行浮动:


  1. <p>
  2. <span>inline element 1</span>
  3. <span class = "floatL">float left</span>
  4. <span class = "floatR">float right</span>
  5. <span>inline element 2</span>
  6. </p>

为了便于观察,为 span 元素添加了 1px 的虚线边框:


  1. p {
  2.     border: 1px solid #ccc;
  3. }
  4. span {
  5.    border: 1px dashed #ccc;
  6. }
  7. .floatL {
  8.    float: left;
  9. }
  10. .floatR {
  11.    float: right;
  12. }

上述代码的运行结果如图 5‑24 所示:

CSS 浮动 float属性-编程知识网图5-24 浮动框与行内级框并列

从上图可以看出,由于浮动框的存在,行框的宽度变窄,当行框的水平空间不足时,行内级框会自动换行。由于受浮动框高度的影响,行内级框被浮动框卡住。

如果多个浮动框并列时,它们会按在HTML中的定义顺序,一个接一个,依次水平排列,每个框按照各自的方向浮动。

假设所有的三个框都向左浮动,则框 1 向左浮动,直到碰到包含块内容区域的边界,另外两个框向左浮动,直到碰到前一个浮动框。如图 5‑25 所示:

CSS 浮动 float属性-编程知识网图5-25 所有三个框都向左浮动

假设所有的三个框都向右浮动,情况与全部向左浮动类似。在HTML代码中,框 1 最先被定义,所以排在最右边,框 3 最后被定义,所以排在最左边。如图 5‑26 所示:

CSS 浮动 float属性-编程知识网图5-26 所有三个框都向右浮动

如果在一行内无法容纳所有的浮动框,则后面的框会向下移动,直到有足够的空间。如果浮动框的高度不同,在向下移动时,可能被其它浮动框“卡住”。如图 5‑27 所示:

CSS 浮动 float属性-编程知识网图5-27 浮动框下移到有足够空间的地方

如果多个框的浮动方向不尽相同,情况会怎样呢?假设有六个浮动框,按从小到大的顺序依次定义,框 1、2、5向左浮动,框 3、4、6向右浮动。运行结果如图 5‑28 所示:

CSS 浮动 float属性-编程知识网图5-28 不同方向浮动的框

从上图可以看出,当框的浮动方向不尽相同时,会按照在HTML中定义的顺序,摆放每一个框,如果一行内空间不足,后面的框会自动下移,形成多行,在每一行中,每个框按照各自的方向浮动。

关于作者

歪脖先生,十五年以上软件开发经验,酷爱Web开发,精通 HTML、CSS、JavaScript、jQuery、JSON、Python、Less、Bootstrap等,著有《HTML宝典》、《揭秘CSS》、《Less简明教程》、《JSON教程》、《Bootstrap2用户指南》、《Bootstrap3实用教程》,并全部在 GitHub 上开源。