CSS-浮动详解

2,699 阅读4分钟

1. 认识浮动

  • float 属性可以指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它

    • float 属性最初只用于在一段文本内浮动图像,实现文字环绕的效果

    • 但是早期的CSS标准中并没有提供好的左右布局方案, 因此在一段时间里面它成为网页多列布局的最常用工具

  • 绝对定位、浮动都会让元素脱离标准流,以达到灵活布局的效果

  • 可以通过float属性让元素产生浮动效果,float的常用取值

    • none:不浮动,默认值
    • left:向左浮动
    • right:向右浮动

2. 浮动规则

  • 规则一:向左浮动或者向右浮动

    • 向左或向右方向移动,直到自己的边界紧贴着包含块(一般是父元素)或者其他浮动元素的边界为止
    • 定位元素会层叠在浮动元素上面

    float.png

  • 规则二:不能超出包含块

    • 如果元素是向左(右)浮动,浮动元素的左(右)边界不能超出包含块的左(右)边界 float2.png
  • 规则三:浮动元素不能层叠

    • 如果一个元素浮动,另一个浮动元素已经在那个位置了,后浮动的元素将紧贴着前一个浮动元素(左浮找左浮,右浮找右浮)

    • 如果水平方向剩余的空间不够显示浮动元素,浮动元素将向下移动,直到有充足的空间为止

    float3.png

  • 规则四:浮动元素会将行内级元素内容推出

    • 浮动元素不能与行内级内容层叠,行内级内容将会被浮动元素推出
    • 比如行内级元素inline-block元素、块级元素的文字内容
    • 图文环绕效果

    图文环绕.png

  • 规则五:浮动只能左右浮动, 不能超出本行的高度

    • 行内级元素、inline-block元素浮动后,其顶部将与所在行的顶部对齐

3. 案例练习

inline(行内)元素,即使通过 CSS 将它们设置为 inline-block,它们之间仍然会有空白间隙。这是由于 HTML 中的空白字符(如空格、换行符、制表符)在渲染时也会被解释为空白。

  • 将多个行内级元素中间的空格(间隙)去除的方法:

    1. 删除换行符(不推荐)
    2. 将父级元素的font-size设置为0, 但是需要子元素设置回来
    3. 通过子元素(span)统一向一个方向浮动即可
    4. flex布局
  • 多列布局一

    <!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>
        /* 公共的class */
        .content {
          width: 1190px;
          margin: 0 auto;
          background-color: orange;
          height: 800px;
        }
    
        /* 布局样式 */
        .box {
          /* margin: 0 -5px; */
          /* 3.方案三: 设置负的的margin(没有兼容性) */
          margin-right: -10px;
        }
    
        .item {
          width: 230px;
          height: 322px;
          background-color: purple;
          color: #fff;
    
          /* 浮动 */
          float: left;
          margin-right: 10px;
          /* margin: 0 5px; */
        }
    
        /* 1.有可能存在兼容性 */
        /* .item:nth-child(5n) {
          margin-right: 0;
        } */
    
        /* 2.比较麻烦 */
        /* .item.last-item {
          margin-right: 0;
        } */
      </style>
    </head>
    <body>
    
      <div class="content">
        <div class="box">
          <div class="item item1">1</div>
          <div class="item item2">2</div>
          <div class="item item3">3</div>
          <div class="item item4">4</div>
          <div class="item item5">5</div>
        </div>
      </div>
    
    </body>
    </html>
    

    多列布局.png

  • 多列布局2

    <!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>
        .content {
          width: 1190px;
          margin: 0 auto;
          background-color: #f00;
          height: 1000px;
        }
    
        .wrapper {
          margin-right: -10px;
        }
    
        .item {
          width: 290px;
          background-color: purple;
          margin-bottom: 10px;
    
          float: left;
          margin-right: 10px;
        }
    
        .item.left {
          height: 370px;
        }
    
        .item.right {
          height: 180px;
        }
      </style>
    </head>
    <body>
    
      <div class="content">
        <div class="wrapper">
          <div class="item left"></div>
          <div class="item left"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
          <div class="item right"></div>
        </div>
      </div>
    
    </body>
    </html>
    

    多列布局2.png

  • 带边框多列布局

    <!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>
        .content {
          width: 1100px;
          margin: 0 auto;
          height: 800px;
          background: #ccc;
        }
    
        .box {
          /* margin-left: 1px; */
        }
    
        .item {
          width: 221px;
          height: 168px;
          background: orange;
          color: #fff;
    
          float: left;
    
          border: 1px solid #000;
          margin-right: -1px;
    
          box-sizing: border-box;
        }
    
        .item.first {
          width: 220px;
        }
      </style>
    </head>
    <body>
    
      <div class="content">
        <div class="box">
          <div class="item first">1</div>
          <div class="item">2</div>
          <div class="item">3</div>
          <div class="item">4</div>
          <div class="item">5</div>
        </div>
      </div>
    
    </body>
    </html>
    

    带边框布局.png

4. 清除浮动

  • 浮动的问题

    • 由于浮动元素脱离了标准流,变成了脱标元素,所以不再向父元素汇报高度
    • 父元素计算总高度时,就不会计算浮动子元素的高度,导致了高度坍塌的问题
  • 解决父元素高度坍塌问题的过程,一般叫做清浮动(清理浮动、清除浮动)

    • 清浮动的目的:让父元素计算总高度的时候,把浮动子元素的高度算进去
  • CSS属性 clear

    • clear 属性可以指定一个元素是否必须移动(清除浮动后)到在它之前的浮动元素下面

    • clear的常用取值

      • left:要求元素的顶部低于之前生成的所有左浮动元素的底部
      • right:要求元素的顶部低于之前生成的所有右浮动元素的底部
      • both:要求元素的顶部低于之前生成的所有浮动元素的底部
      • none:默认值,无特殊要求
  • 清除浮动的方法

    • 方法一:给父元素设置固定高度

      • 扩展性不好(不推荐)
    • 方法二:在父元素最后增加一个空的块级子元素,并且让它设置clear: both

      • 增加很多无意义的空标签,维护麻烦
      • 违反了结构与样式分离的原则(不推荐)
    • 方法三:给父元素添加一个伪元素 (终极方案)

      • 给父元素增加::after伪元素,纯CSS样式解决,结构与样式分离(推荐)
      .clear_fix::after {
        content: "";
        clear: both;
        display: block;
      
        /* 浏览器兼容 */
        visibility: hidden;
        height: 0;
      }
      
      .clear_fix {
        /* IE6/7 */
        *zoom: 1;
      }
      

5. 多种布局对比

布局对比.png