Skip to content

**浮动、BFC 规范、清除浮动的最佳实践

一、实现 CSS 布局的几种策略

网页布局的本质是用 CSS 来摆放盒子。CSS 提供了多种布局策略:

  • 正常布局流

  • 浮动布局

  • 定位布局

  • 表格布局​ (display: table)

  • 响应式设计

  • 弹性布局

  • 网格布局

  • 多列布局

每种布局方式都有自己的用途和优缺点,它们相互辅助,共同构建理想的网页布局。

二、正常布局流(Normal Flow)

正常布局流是指在不对页面进行任何布局控制时,浏览器默认的 HTML 布局方式。它规定了默认情况下块级元素和内联元素的排版方式。

1. 正常布局流中,块级元素的排列方式

  • 块级盒子会从包含块的顶部开始,按序垂直排列

  • 同级盒子间的垂直距离由 margin属性决定。

  • 相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则。

2. 正常布局流中,内联元素的排版方式

  • 内联盒子会从包含块的顶部开始,按序水平排列

  • 只有水平外边距、边框和内边距会被保留(垂直方向无效)。

  • 这些盒子可以以不同的方式在垂直方向对齐(底部对齐、顶部对齐或按文字底部对齐)。

注意:盒模型不仅指 div,所有 HTML 元素本质上都是一个盒子模型,并具有盒模型的结构和属性。

在正常布局流中,无法实现块级元素在水平方向一行排列,而浮动布局可以轻松实现这一点。

三、浮动布局

1、浮动布局起源

浮动布局最初引入 float属性是为了实现简单的布局,例如让图像在一列文本中浮动,并使文字环绕在它的左边或右边。

但 Web 开发人员很快意识到,任何元素都可以浮动,而不仅仅是图像,因此浮动的使用范围扩大了。 ![[Pasted image 20260228111246.png]]

2、浮动是如何工作的

TIP

  • 把一个元素“浮动”(float)起来,会改变该元素本身和在正常布局流(normal flow)中跟随它的其他元素的行为。

  • 这一元素会浮动到左侧或右侧,并且从正常布局流(normal flow)中移除,这时候其他的周围内容就会在这个被设置浮动(float)的元素周围环绕。

简单理解:

当元素添加了浮动后,元素就会脱离文档流,按照指定方向(左右)发生移动,遇到父级边界或者相邻的浮动元素就会停下来,同时会影响到他后面元素的排版行为。

  • 文档流:文档中可显示对象在排列时所占用的位置/空间(在页面中占位置)

  • 脱离文档流:元素相当于漂浮起来,不占据页面中的位置

3、浮动的本质和要点

TIP

  • 浮动的本质功能:用来实现并排

  • 浮动使用要点:要浮动,并排的盒子都要设置浮动

  • 父盒子要有足够的宽度,否则子盒子会掉下去

<style>
  .box {
    width: 600px;
    height: 200px;
    border: 1px solid #000;
  }

  /* 
        要点:要浮动,都浮动
        父盒子要有足够的宽度,否则子盒子会掉下去
    */
  .box .c1 {
    width: 200px;
    height: 200px;
    background-color: skyblue;
    float: left;
  }

  .box .c2 {
    width: 200px;
    height: 200px;
    background-color: gold;
    float: left;
  }

  .box .c3 {
    width: 200px;
    height: 200px;
    background-color: pink;
    float: left;
  }
</style>

<body>
  <h1>浮动</h1>

  <div class="box">
    <div class="c1">float: left;</div>
    <div class="c2">float: left;</div>
    <div class="c3">float: left;</div>
  </div>
</body>

![[Pasted image 20260228111410.png]]

4、如何产生浮动

TIP

给需要浮动的元素添加 float 属性,float 属性对应的值如下:

属性
float ① none 默认值,元素不浮动
② left 元素向左浮动
③ right 元素向右浮动
④ inherit 规定应该从父元素继承 float 属性的值。(一般不用,了解即可)

四、元素浮动的特性

TIP

深入了解元素添加浮动后的 7 大特性

1、元素添加浮动后,脱离文档流

TIP

同时会影响其后面的元素,但不影响它前面的元素

<style>
  .box {
    width: 300px;
    height: 200px;
    border: 2px solid red;
  }
  .box1 {
    width: 100px;
    height: 50px;
    background-color: khaki;
  }
  .box2 {
    width: 200px;
    height: 50px;
    background-color: rgb(133, 206, 235, 0.5);
    /* 给元素添加左浮动 */
    /* float: left; */
  }
  .box3 {
    width: 100px;
    height: 100px;
    background-color: pink;
  }
</style>
<div class="box">
  <div class="box1">1</div>
  <div class="box2">2</div>
  <div class="box3">3</div>
</div>
正常布局流中 box2(蓝色盒子浮动后效果)
![[Pasted image 20260228111816.png]] ![[Pasted image 20260228111823.png]]
正常布局流中,块级元素默认从上往下排列 蓝色 div 加了浮动后,相当于漂浮起来,不占据页面空间,这时候蓝色盒子后面的粉色盒子的位置就会发生改变,移动到上面来,就出现如图,蓝色的盒子相当于漂浮在红色的上面。但黄色的盒子不受任何影响
## 2、如果父元素的宽度不够

TIP

子元素在放不下的情况下会换行显示

<style type="text/css">
  .main {
    width: 240px;
    height: 150px;
    background-color: khaki;
  }
  .box {
    width: 50px;
    height: 50px;
    background-color: skyblue;
    margin: 10px;
    float: left;
  }
</style>
<body>
  <div class="main">
    <div class="box">框1</div>
    <div class="box">框2</div>
    <div class="box">框3</div>
    <div class="box">框4</div>
  </div>
</body>

![[Pasted image 20260228111859.png]]

3、浮动的顺序贴靠特性

**TIP

子盒子会按顺序进行贴靠,如果没有足够空间,则会寻找在前一个兄弟元素

<style>
  .box {
    width: 300px;
    height: 200px;
    border: 1px solid #000;
  }

  /* 
        浮动的顺序贴靠特性:

        子盒子会按顺序进行贴靠,
        如果没有足够空间,则会寻找在前一个兄弟元素
    */
  .box .c1 {
    width: 200px;
    height: 100px;
    background-color: orange;
    float: left;
  }

  .box .c2 {
    width: 100px;
    height: 50px;
    background-color: skyblue;
    float: left;
  }

  .box .c3 {
    width: 100px;
    height: 50px;
    background-color: tomato;
    float: left;
  }
</style>

<body>
  <h1>浮动的顺序贴靠特性</h1>

  <div class="box">
    <div class="c1"></div>
    <div class="c2"></div>
    <div class="c3"></div>
  </div>
</body>

![[Pasted image 20260228111956.png]] **利用贴靠性布局案例: ![[Pasted image 20260228112020.png]]

4、元素浮动后,具有行内块级元素特性

TIP

浮动的元素不再区分块级元素、行内元素,已经脱离了标准文档流 一律能够设置宽度和高度,即使它是 span 标签 或 a 标签 等等

<style>
  span {
    width: 100px;
    height: 30px;
    background-color: tomato;
    /* 
            只要设置了浮动的元素,不再区分块级元素和行内元素
            都能设置高度和宽度
        */
    float: left;
    margin-right: 10px;
    text-align: center;
    line-height: 30px;
    color: #fff;
  }
</style>

<body>
  <h1>浮动的元素一定能设置宽高</h1>

  <span>1</span>
  <span>2</span>
  <span>3</span>
  <span>4</span>
  <span>5</span>
</body>

![[Pasted image 20260228112107.png]] 右浮动

float: right; 即可设置右浮动 实际工作中,右浮动没有左浮动用的多 原理同左浮动

5、浮动的元素会造成父元素高度塌陷

TIP

当给子元素添加了浮动后,子元素相当于漂浮起来,不占据页面空间。 这样就造成父级元素在没有设置高度时,高度塌陷问题。 具体看如下案例:

<style>
  .main {
    width: 200px;
    border: 2px solid red;
  }
  .item {
    width: 100px;
    height: 100px;
    background-color: pink;
    /* 添加浮动的前后对比 */
    float: left;
  }
</style>
<body>
  <div class="main">
    <div class="item"></div>
  </div>
</body>
item 未设置浮动前效果 item 设置浮动后效果
![[Pasted image 20260228112357.png]] ![[Pasted image 20260228112404.png]]
## 6、浮动对文字的影响
TIP

常见的图片文字环绕效果,其实现方式主要是将图片左浮动或右浮动 浮动后其相邻的文字,就会环绕图片排列

<style>
  .box {
    width: 200px;
    background-color: #ddd;
    padding: 10px;
  }
  .img {
    width: 80px;
    height: 80px;
    background-color: skyblue;
    float: left;
    margin: 10px;
  }
</style>
<body>
  <div class="box">
    <div class="img"></div>
    最初,引入float属性是为了能让 web
    开发人员实现简单的布局,包括在一列文本中浮动的图像,文字环绕在它的左边或右边
  </div>
</body>

![[Pasted image 20260228112451.png]]

7、使用浮动实现网页布局

TIP

垂直显示的盒子,不要设置浮动,只有并排显示的盒子才要设置浮动 每一个盒子都是独立存在,每个盒子中又是一个小天地,内部可以继续使用浮动 ![[Pasted image 20260228112522.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>使用浮动实现网页布局 - arry老师</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      /* topbar start */
      .topbar {
        width: 100%;
        height: 40px;
        background-color: #666;
      }
      /* end topbar */

      /* header start */
      header {
        width: 1000px;
        height: 100px;
        margin: 20px auto 0;
      }
      header .logo {
        width: 200px;
        height: 100px;
        background-color: skyblue;
        float: left;
      }
      header .login {
        width: 200px;
        height: 30px;
        background-color: orange;
        float: right;
      }

      header .top-nav {
        width: 660px;
        height: 50px;
        background-color: tomato;
        float: right;
        margin-top: 20px;
      }
      /* end header */

      /* main start */
      main {
        width: 1000px;
        height: 500px;
        margin: 30px auto;
      }
      main aside.ad {
        width: 300px;
        height: 500px;
        background-color: rgb(190, 225, 239);
        float: left;
      }
      main article {
        width: 680px;
        height: 500px;
        float: right;
      }
      main article .banner {
        width: 680px;
        height: 380px;
        background-color: orange;
      }
      main article .pics {
        width: 680px;
        height: 100px;
        margin-top: 20px;
      }
      main article .pics ul {
        list-style: none;
      }

      main article .pics ul li {
        width: 160px;
        height: 100px;
        background-color: greenyellow;
        float: left;
        margin-right: 10px;
      }
      main article .pics ul li:last-child {
        width: 170px;
        margin-right: 0;
      }
      /* end main */

      /* footer start */
      footer {
        width: 1000px;
        height: 100px;
        background-color: gray;
        margin: 0 auto;
      }
      /* end footer */
    </style>
  </head>
  <body>
    <!-- topbar start -->
    <div class="topbar"></div>
    <!-- end topbar -->

    <!-- header start -->
    <header>
      <div class="logo"></div>
      <div class="login"></div>
      <nav class="top-nav"></nav>
    </header>
    <!-- end header -->

    <!-- main start -->
    <main>
      <aside class="ad"></aside>
      <article>
        <div class="banner"></div>
        <div class="pics">
          <ul>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
          </ul>
        </div>
      </article>
    </main>
    <!-- end main -->

    <!-- footer statr -->
    <footer></footer>
    <!-- end footer -->
  </body>
</html>