欢迎光临
我们一直在努力

第16篇:文档流与浮动

第16篇:文档流与浮动

文档流是 CSS 布局的根基。理解块级格式上下文(BFC)、浮动清除以及文档流的本质,是掌握复杂布局的前提。本篇将从浏览器如何排列元素说起,深入讲解正常流、浮动、BFC 等核心概念。


学习目标

  • 理解什么是正常文档流(Normal Flow)
  • 掌握 BFC(块级格式上下文)的概念与触发条件
  • 理解浮动(float)的设计初衷与使用场景
  • 掌握清除浮动的多种方法及最佳实践
  • 理解 IFC(行内格式上下文)的基本概念
  • 学会用浮动实现简单的多栏布局

核心知识点

一、什么是文档流?

文档流(Document Flow),也称为正常流(Normal Flow),是浏览器默认的排版方式。元素按照 HTML 中出现的顺序,从上到下、从左到右依次排列。

正常流中的两种排列方式

块级格式上下文(Block Formatting Context, BFC):

  • 块级元素独占一行,垂直排列
  • 每个块级元素的左边缘紧贴包含块的左边缘

/* 块级元素在正常流中的行为 */
div, p, h1, section {
display: block;
/* 默认宽度 = 父容器宽度 */
/* 默认高度 = 内容高度 */
}

行内格式上下文(Inline Formatting Context, IFC):

  • 行内元素在水平方向依次排列
  • 当一行排不下时,自动换行

/* 行内元素在正常流中的行为 */
span, a, strong, em {
display: inline;
/* 宽度由内容决定 */
/* 高度由 line-height 决定 */
}


二、脱离文档流的方式

元素一旦脱离文档流,就不再参与正常流的排列。

方式属性说明
浮动 float: left/right 元素向左/右浮动
绝对定位 position: absolute 相对于最近的定位祖先
固定定位 position: fixed 相对于视口
弹性布局 display: flex 创建 Flex 上下文
网格布局 display: grid 创建 Grid 上下文

三、浮动(float)详解

浮动的设计初衷

/* 最初设计目的:让文字环绕图片 */
.article img {
float: left; /* 图片向左浮动 */
margin: 0 16px 16px 0; /* 文字与图片间距 */
}

浮动元素会:

  • 脱离正常文档流
  • 向左或向右移动,直到触及包含块的边缘或另一个浮动元素
  • 后面的行内内容会环绕浮动元素
  • float 取值

    .none { float: none; } /* 默认值,不浮动 */
    .left { float: left; } /* 向左浮动 */
    .right { float: right; } /* 向右浮动 */

    文字环绕效果

    <div class="article">
    <img src="photo.jpg" class="float-left" alt="">
    <p>这是一段很长的文字…</p>
    </div>

    .float-left {
    float: left;
    width: 200px;
    height: 150px;
    margin: 0 16px 8px 0;
    }

    .article p {
    /* 文字会自动环绕图片 */
    }


    四、浮动的副作用:高度塌陷

    当容器内的子元素全部浮动时,容器会失去高度——因为浮动元素脱离了文档流。

    <div class="parent">
    <div class="float-child">浮动元素 1</div>
    <div class="float-child">浮动元素 2</div>
    </div>

    .float-child {
    float: left;
    width: 100px;
    height: 100px;
    background: #4a90d9;
    }

    .parent {
    background: #f0f0f0;
    /* ❌ 父元素高度为 0! */
    }


    五、清除浮动的六种方法

    方法 1:额外空元素 + clear

    <div class="parent">
    <div class="float-child"></div>
    <div class="float-child"></div>
    <div style="clear: both;"></div> <!– 额外元素 –>
    </div>

    ❌ 不推荐:增加无意义 HTML

    方法 2:伪元素清除(推荐)

    .clearfix::after {
    content: "";
    display: block; /* 或 table */
    clear: both;
    }

    <div class="parent clearfix">
    <div class="float-child"></div>
    <div class="float-child"></div>
    </div>

    ✅ 最常用:不增加额外 HTML,兼容性好

    方法 3:父元素 overflow

    .parent {
    overflow: hidden; /* 或 auto */
    }

    ⚠️ 副作用:可能会裁剪内容或显示滚动条

    方法 4:父元素也浮动

    .parent {
    float: left;
    }

    ❌ 不推荐:影响父元素自身的布局

    方法 5:父元素 display: flow-root(现代)

    .parent {
    display: flow-root; /* 创建 BFC,无副作用 */
    }

    ✅ 推荐:语义清晰,无副作用,但 IE 不支持

    方法 6:父元素 display: flex/grid

    .parent {
    display: flex;
    /* 或 display: grid; */
    }

    💡 Flexbox/Grid 容器自动包裹浮动子元素

    清除浮动方法总结:

    方法优点缺点
    空元素 + clear 简单直观 增加无意义 HTML
    伪元素 clearfix 纯 CSS,无额外标签 需要记住代码片段
    overflow 简单 可能裁剪内容
    flow-root 语义正确,无副作用 IE 不支持
    flex/grid 现代布局 改变布局方式

    六、BFC(块级格式上下文)

    什么是 BFC?

    BFC 是 CSS 中一个独立的渲染区域,内部的元素布局不会影响外部,外部的也不会影响内部。

    BFC 的创建条件

    /* 以下任意一种都会创建 BFC */
    .bfc-1 { overflow: hidden; } /* 最常见 */
    .bfc-2 { overflow: auto; }
    .bfc-3 { display: flow-root; } /* 最推荐(现代浏览器) */
    .bfc-4 { display: inline-block; }
    .bfc-5 { float: left; } /* 浮动元素自身 */
    .bfc-6 { position: absolute; } /* 绝对/固定定位 */
    .bfc-7 { position: fixed; }

    BFC 的特性

    /* 特性 1:BFC 内部浮动元素会被计算高度 */
    .parent {
    overflow: hidden; /* 创建 BFC */
    }
    .parent .float-child {
    float: left;
    }
    /* 父元素会自动包裹浮动子元素 */

    /* 特性 2:BFC 区域不会与浮动元素重叠 */
    .main {
    float: left;
    width: 70%;
    }
    .sidebar {
    overflow: hidden; /* 创建 BFC,自动避开浮动元素 */
    }

    /* 特性 3:BFC 内部 margin 不会与外部折叠 */
    .bfc-container {
    overflow: hidden; /* 创建 BFC */
    }
    .bfc-container p {
    margin: 20px 0; /* margin 不会穿透到外部折叠 */
    }


    七、浮动布局实战:多栏布局

    经典两栏布局

    <div class="two-column clearfix">
    <div class="main">主内容区</div>
    <div class="sidebar">侧边栏</div>
    </div>

    .two-column {
    max-width: 900px;
    margin: 0 auto;
    }

    .main {
    float: left;
    width: 70%;
    padding: 20px;
    background: #f9fafb;
    }

    .sidebar {
    float: left;
    width: 30%;
    padding: 20px;
    background: #e3f2fd;
    }

    .clearfix::after {
    content: "";
    display: block;
    clear: both;
    }

    三栏布局(双飞翼/圣杯布局的简化版)

    .three-column .col {
    float: left;
    width: 33.33%;
    padding: 20px;
    box-sizing: border-box;
    }


    动手练习

    练习 1:文字环绕图片

    实现一个图文混排效果:

    • 图片向左浮动
    • 文字环绕图片右侧和底部
    • 图片与文字之间有适当间距

    练习 2:清除浮动对比

    创建包含浮动子元素的父容器:

    • 不使用清除浮动,观察高度塌陷
    • 分别用 overflow:hidden、伪元素、flow-root 三种方法清除
    • 对比效果差异

    练习 3:浮动多栏布局

    用 float 实现一个三栏布局:

    • 三栏等宽排列
    • 每栏之间有间距
    • 父容器正确包裹所有子元素

    常见误区 ⚠️

    误区真相
    “浮动元素完全脱离文档流” 浮动是"半脱离"——块级元素当它不存在,但行内内容会环绕它
    “clear: both 只能用在空 div 上” 可以用在任何元素上,包括伪元素
    “overflow: hidden 是清除浮动的最佳方法” 它可能裁剪内容,伪元素 clearfix 或 flow-root 更推荐
    “所有块级元素都能创建 BFC” 需要特定条件(如 overflow、float、position 等)
    “flex/grid 不需要清除浮动” 正确!它们本身就是独立的格式上下文
    “float 适合所有布局场景” 现代布局应优先使用 flexbox/grid,float 主要用于文字环绕
    “BFC 就是清除浮动” BFC 远不止清除浮动,它还能阻止 margin 折叠、避免浮动重叠
    “display: flow-root 兼容性不好” IE 不支持,但所有现代浏览器都支持,是创建 BFC 的最佳方式

    速查卡片 📋

    脱离文档流的方式

    float: left/right;
    position: absolute/fixed;
    display: flex/grid;

    清除浮动(clearfix)

    .clearfix::after {
    content: "";
    display: block;
    clear: both;
    }

    BFC 创建方式

    overflow: hidden;
    overflow: auto;
    display: flow-root; /* 推荐 */
    display: inline-block;
    float: left;
    position: absolute/fixed;

    浮动多栏布局

    .col {
    float: left;
    width: 33.33%;
    box-sizing: border-box;
    }


    扩展阅读

    • MDN: 浮动
    • MDN: 块级格式上下文
    • MDN: clear
    • CSS-Tricks: All About Floats(英文)

    📌 配套代码:

    • CODE/16/float-demo.html — 浮动与文字环绕演示
    • CODE/16/clearfix-bfc.html — 清除浮动与 BFC 实战

    🎉 下一步:进入 第17篇:溢出处理与文本截断,学习 overflow 和文本截断的完整方案。

    赞(0)
    未经允许不得转载:171主机测评 » 第16篇:文档流与浮动
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址