第3周:CSS 选择器与盒模型

本周目标:理解 CSS 的工作原理,掌握选择器和盒模型,能独立完成页面样式编写
核心思维:CSS 是"样式表",就像给 HTML 这个"骨架"穿上"衣服"


3.1 什么是 CSS?

概念讲解

CSS 全称 Cascading Style Sheets(层叠样式表)。拆开来看:

  • 层叠(Cascading):多个样式来源可以叠加在一起,按优先级决定最终效果
  • 样式表(Style Sheets):把样式集中写在"表"里,统一管理

CSS 和 HTML 的关系:

HTML = 骨架(页面有什么内容)    → 建筑的框架结构
CSS  = 衣服(内容长什么样子)    → 建筑的装修设计
JS   = 行为(内容怎么交互)      → 建筑的电梯、门禁等

类比 Java:
HTML → 实体类(定义数据结构)
CSS  → 注解 + 配置文件(定义展示规则)
JS   → Service 方法(定义业务逻辑)

更直观的类比——装修房子:
- HTML 决定了:这里有3个房间,1个厨房,1个卫生间
- CSS  决定了:卧室刷蓝色,客厅铺木地板,厨房装白色橱柜
- JS   决定了:开门时灯自动亮起,温度低于20度自动开暖气

不使用 CSS 的页面:浏览器会用默认样式渲染——白底、黑字、宋体、无间距……丑到无法直视。

使用 CSS 后:可以自定义颜色、字体、大小、间距、布局、动画……把页面打扮得漂漂亮亮。


3.2 CSS 的三种引入方式

概念讲解

CSS 样式有三种"放"到 HTML 中的方式,就像 Java 中"配置"可以放在不同地方:

方式一:行内样式 → 写在 HTML 标签的 style 属性里
类比:在 Java 方法里直接写死配置值(硬编码)

方式二:内部样式表 → 写在 <head> 的 <style> 标签里
类比:在同一个 Java 类里定义常量

方式三:外部样式表 → 写在独立的 .css 文件里,通过 <link> 引入
类比:把配置抽离到 application.yml 或 .properties 文件中

代码示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>CSS 引入方式</title>

    <!-- 方式二:内部样式表 -->
    <style>
        .internal-demo {
            color: green;
            font-size: 18px;
        }
    </style>

    <!-- 方式三:外部样式表(强烈推荐!生产环境标配) -->
    <!-- rel="stylesheet" 告诉浏览器这是一个样式表 -->
    <!-- href 指向 CSS 文件路径 -->
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <!-- 方式一:行内样式 -->
    <p style="color: blue; font-size: 16px;">我是行内样式(蓝色)</p>

    <!-- 方式二:内部样式表 -->
    <p class="internal-demo">我是内部样式(绿色)</p>

    <!-- 方式三:外部样式表 -->
    <p class="external-demo">我是外部样式(CSS文件中定义)</p>
</body>
</html>

三种方式对比

方式写法优先级可维护性适用场景
行内样式style="..."最高差(样式和结构混在一起)临时调试、动态样式
内部样式<style>...</style>中一般(和 HTML 在同一文件)小页面、Demo
外部样式<link href="...">最低最好(样式和结构分离)生产环境(标准做法)

开发建议:实际项目中,几乎 100% 使用外部样式表。行内样式和内部样式只在写 Demo 或快速调试时使用。


3.3 CSS 语法基础

概念讲解

CSS 的基本语法非常简单,就是一个"选择器 + 一组属性":

选择器 {
    属性名: 属性值;
    属性名: 属性值;
}

类比 Java:

// CSS 写法
p {
    color: red;
    font-size: 16px;
}

// 类比 Java 代码
if (element 是 p 标签) {
    element.setColor("red");
    element.setFontSize(16);
}

CSS 声明的三个部分:

p          {     color        :     red        ;
↑           ↑      ↑                ↑           ↑
选择器    左大括号  属性名          属性值      分号(必须!)
(找谁)          右大括号     (改什么)       (改成什么)

注释

/* CSS 只有一种注释方式:/* ... *\/ */
/* 类比 Java 的 // 单行注释和 /* *\/ 多行注释 */

/*
 * 这是多行注释
 * CSS 没有单行注释!
 * // 这样写不是注释,会被当作 CSS 规则解析(会报错)
 */

p {
    color: red;  /* 行尾注释:解释这一行的用途 */
}

3.4 CSS 选择器

概念讲解

选择器的本质就是告诉 CSS “哪些元素要应用这个样式”。

这就像 Java 中的查询条件:

数据库查询:SELECT * FROM users WHERE age > 18 AND city = '北京'
CSS 选择器:p.highlight { color: red; }
         → 找到"是 p 标签" 且 "有 highlight 类名" 的元素,设置颜色为红色

基础选择器

/* ========== 1. 元素选择器(标签选择器)========== */
/*
    选中所有指定标签名的元素
    类比 Java:if (element.getTagName().equals("p"))
    作用范围:最大,会影响所有同标签的元素
*/
p { color: #333; }           /* 所有 <p> 标签 */
h1 { font-size: 28px; }      /* 所有 <h1> 标签 */
a { text-decoration: none; } /* 所有 <a> 标签 */

/* ========== 2. 类选择器(最常用!)========== */
/*
    选中 class 属性包含指定值的元素
    类比 Java:if (element.hasClass("highlight"))
    一个元素可以有多个 class(空格分隔)
*/
.highlight { background-color: yellow; }
.card { border: 1px solid #ddd; padding: 16px; }
.active { color: #1890ff; font-weight: bold; }

/* HTML 中使用 class:
    <p class="highlight">这段文字会高亮</p>
    <div class="card active">这个卡片既有 card 样式又有 active 样式</div>
*/

/* ========== 3. ID 选择器 ========== */
/*
    选中 id 属性等于指定值的元素
    类比 Java:if (element.getId().equals("header"))
    页面中 id 应该是唯一的(就像 Java 中主键)
*/
#header { height: 60px; background: #001529; }
#sidebar { width: 200px; }
#main-content { flex: 1; }

/* HTML 中使用 id:
    <div id="header">...</div>
*/

/* ========== 4. 通配符选择器 ========== */
/*
    选中页面中所有元素
    类比 Java:SELECT * FROM ALL_TABLES
    慎用!性能较差(要遍历所有元素)
*/
* { margin: 0; padding: 0; }
/* 常用于清除默认样式,后面会详细讲 */

组合选择器

/*
    组合选择器用来精确选择"特定位置"的元素
    就像 SQL 的 WHERE 条件可以 AND/OR 组合一样
*/

/* ========== 后代选择器(空格)========== */
/*
    选中 A 内部所有层级的 B 元素
    类比 Java:查找某对象下所有子对象(递归)
*/
.nav a { color: blue; }
/* 选中 class="nav" 的元素内部的所有 a 标签(不论层级深浅) */

/* HTML 示例:
    <div class="nav">
        <a href="#">直接子链接</a>          ← 选中
        <ul>
            <li>
                <a href="#">深层嵌套链接</a>  ← 也选中
            </li>
        </ul>
    </div>
*/


/* ========== 子代选择器(>)========== */
/*
    只选中 A 的直接子元素 B(不包括孙级及更深)
    类比 Java:list.stream().filter(e -> e.getParent() == A)
*/
.nav > a { font-weight: bold; }
/* 只选中 nav 的直接子 a 标签(不包含嵌套在 li 里的 a) */

/* HTML 示例:
    <div class="nav">
        <a href="#">直接子链接</a>          ← 选中 ✓
        <ul>
            <li>
                <a href="#">嵌套链接</a>     ← 不选中 ✗
            </li>
        </ul>
    </div>
*/


/* ========== 相邻兄弟选择器(+)========== */
/*
    选中紧挨在 A 后面的第一个 B 元素
    "相邻" = 同级 + 紧挨着
*/
h2 + p { margin-top: 0; }
/* 选中紧跟在 h2 后面的那个 p(如果紧挨着的是 div 就选不到) */


/* ========== 通用兄弟选择器(~)========== */
/*
    选中 A 后面所有同级的 B 元素
    "兄弟" = 同一个父元素下的元素
*/
h2 ~ p { color: gray; }
/* 选中 h2 后面所有同级的 p 元素 */

属性选择器

/*
    根据元素的属性来选择
    类比 Java:if (element.getAttribute("type").equals("text"))
*/

/* 精确匹配属性值 */
input[type="text"] { border: 1px solid #ccc; }
/* 选中 type="text" 的 input */

/* 属性以某个值开头 */
a[href^="https"] { color: green; }
/* 选中 href 以 "https" 开头的链接 */

/* 属性以某个值结尾 */
a[href$=".pdf"] { color: red; }
/* 选中所有 PDF 链接 */

/* 属性包含某个值 */
a[href*="baidu"] { font-weight: bold; }
/* 选中 href 包含 "baidu" 的链接 */

/* 属性存在即可(不管值是什么) */
input[disabled] { background: #f5f5f5; }
/* 选中所有有 disabled 属性的 input */

/* 属性值匹配列表中的某一个(用空格分隔) */
[class~="active"] { color: blue; }
/* 选中 class 包含 "active" 的元素(多 class 中的一个) */

伪类选择器

/*
    伪类 = 元素的某种"状态"
    元素在不同状态下可能有不同的样式
    类比 Java:同一个对象在不同状态下行为不同(状态模式)
*/

/* ========== 交互状态伪类 ========== */
a:hover { color: red; }           /* 鼠标悬停时(最常用!) */
a:active { color: blue; }         /* 鼠标按下时(点击瞬间) */
a:visited { color: purple; }      /* 已访问过的链接 */
input:focus { border-color: #1890ff; }  /* 获取焦点时(点击输入框) */

/* 链接样式推荐顺序(LVHA 记忆法:Love HAte) */
a:link { color: blue; }    /* 未访问 */
a:visited { color: purple; } /* 已访问 */
a:hover { color: red; }    /* 悬停 */
a:active { color: blue; }  /* 激活 */

/* ========== 结构伪类 ========== */
/*
    根据元素在父元素中的位置来选择
    类比 Java:list.get(0), list.getLast(), list.get(index)
*/

li:first-child { font-weight: bold; }    /* 第一个子元素 */
li:last-child { font-style: italic; }    /* 最后一个子元素 */
li:nth-child(3) { color: red; }          /* 第3个子元素 */
li:nth-child(odd) { background: #f9f9f9; }  /* 奇数行(1,3,5...) */
li:nth-child(even) { background: #fff; }     /* 偶数行(2,4,6...) */
li:nth-child(3n) { border-bottom: 1px solid #eee; } /* 每3个一组 */
li:nth-child(3n+1) { font-weight: bold; } /* 每组的第1个 */

/* ========== 表单伪类 ========== */
input:enabled { background: white; }     /* 启用状态(默认) */
input:disabled { background: #f5f5f5; }  /* 禁用状态 */
input:checked { accent-color: #1890ff; } /* 选中状态(checkbox/radio) */
input:valid { border-color: green; }     /* 验证通过 */
input:invalid { border-color: red; }     /* 验证失败 */

/* ========== 否定伪类 ========== */
input:not([type="submit"]) { border: 1px solid #ccc; }
/* 选中所有 type 不等于 submit 的 input */
input:not(:disabled) { cursor: pointer; }
/* 选中所有未禁用的 input */

伪元素选择器

/*
    伪元素 = 在元素内容中"虚拟"出一个位置
    通过 CSS 创建出 HTML 中不存在的元素
    类比 Java:动态代理 —— 看不到实现,但效果存在
*/

p::first-letter { font-size: 2em; font-weight: bold; }
/* 首字母样式(像报纸文章开头的超大字母) */

p::first-line { color: gray; }
/* 首行样式 */

p::before { content: ">> "; color: #999; }
/* 在元素内容前面插入虚拟内容(content 属性必须有!) */

p::after { content: " <<"; color: #999; }
/* 在元素内容后面插入虚拟内容 */

/* 实际应用:清除浮动(后面会详细讲) */
.clearfix::after {
    content: "";
    display: block;
    clear: both;
}

/* 实际应用:必填标记 */
.form-item.required > label::after {
    content: " *";
    color: red;
}

3.5 CSS 选择器优先级(Specificity)

概念讲解

当多个 CSS 规则同时作用于同一个元素时,浏览器需要决定"听谁的"。这就是"优先级"。

优先级就像公司里的决策层级:

!important  → 董事长(一句话定乾坤,谁都不能反驳)
行内样式    → CEO(直接指挥)
ID 选择器   → 部门经理(管理特定部门)
类选择器    → 小组长(管理一类人)
元素选择器  → 普通员工(影响范围最大,但话语权最小)

优先级计算

每种选择器有一个"权重分",多个选择器组合时权重相加:

选择器权重类比
* 通配符0临时工
元素选择器 p1普通员工
类选择器 .highlight10小组长
属性选择器 [type="text"]10小组长
伪类 :hover10小组长
伪元素 ::before10小组长
ID 选择器 #header100部门经理
行内样式 style="..."1000CEO
!important无穷大董事长

代码示例

/* 权重 = 1(一个元素选择器) */
p { color: black; }

/* 权重 = 11(1个类 + 1个元素) */
p.highlight { color: blue; }
/* 比 p 的权重高,所以蓝色胜出 */

/* 权重 = 100(一个 ID) */
#main { color: green; }
/* 比 11 高,所以绿色胜出 */

/* 权重 = 111(1个 ID + 1个类 + 1个元素) */
#main p.highlight { color: orange; }
/* 更高了,橙色胜出 */

/* 权重 = 1000(行内样式) */
/* <p style="color: red;">文字</p> */
/* 红色胜出 */

/* 权重 = 无穷大(!important) */
p { color: pink !important; }
/* 粉色胜出(但强烈不推荐滥用!) */

优先级规则总结

1. !important 优先级最高(尽量避免使用)
2. 行内样式 > 内部/外部样式
3. ID 选择器 > 类选择器 > 元素选择器
4. 同优先级时,后写的覆盖先写的("层叠"的含义)
5. 选择器权重相加比较

开发建议:

  • 尽量用类选择器来控制样式(权重适中,可复用)
  • 避免 !important(像避免全局变量一样)
  • 避免 ID 选择器做样式(ID 主要给 JS 用)

3.6 盒模型(Box Model)——最重要的概念

概念讲解

盒模型是 CSS 布局的基石,理解了盒模型,CSS 布局就懂了一半。

每一个 HTML 元素在浏览器中都被渲染成一个"矩形盒子":

┌─────────────────────────────────────────────────┐
│                   margin(外边距)                 │
│         盒子与盒子之间的距离                         │
│  ┌───────────────────────────────────────┐      │
│  │            border(边框)               │      │
│  │         盒子的边界线                    │      │
│  │  ┌─────────────────────────────┐     │      │
│  │  │       padding(内边距)       │     │      │
│  │  │    内容和边框之间的空间        │     │      │
│  │  │  ┌───────────────────┐      │     │      │
│  │  │  │  content(内容)   │      │     │      │
│  │  │  │  文字、图片等      │      │     │      │
│  │  │  │  width × height    │      │     │      │
│  │  │  └───────────────────┘      │     │      │
│  │  └─────────────────────────────┘     │      │
│  └───────────────────────────────────────┘      │
└─────────────────────────────────────────────────┘

通俗类比——快递盒子:

一个快递盒子的结构:

┌─ 外面的大纸箱 → margin(外边距)
│  和别的包裹之间的距离
│
│  ┌─ 瓦楞纸板 → border(边框)
│  │  盒子的边界
│  │
│  │  ┌─ 泡沫/气泡膜 → padding(内边距)
│  │  │  保护商品不被磕碰
│  │  │
│  │  │  ┌─ 商品 → content(内容)
│  │  │  │  你真正要的东西
│  │  │  └─
│  │  └─
│  └─
└─

content-box vs border-box(关键区别)

这是初学者最容易踩坑的地方!

content-box(默认值):
你设置的 width/height 只是内容区域的宽高
实际占用的总宽度 = width + 左右padding + 左右border

示例:
.box {
    width: 200px;      ← 内容宽 200px
    padding: 10px;     ← 左右各 10px
    border: 5px;       ← 左右各 5px
}
实际宽度 = 200 + 10×2 + 5×2 = 230px  ← 不是 200px!
→ 这会让布局计算变得复杂


border-box(推荐值):
你设置的 width/height 是内容 + padding + border 的总宽高
实际占用的总宽度 = 你设置的 width

示例:
.box {
    width: 200px;           ← 总宽 200px
    padding: 10px;          ← 左右各 10px
    border: 5px;            ← 左右各 5px
    box-sizing: border-box; ← 关键!
}
实际宽度 = 200px  ← 就是你设置的值!
内容实际宽度 = 200 - 10×2 - 5×2 = 170px
→ 布局计算变得简单

结论:永远使用 border-box!这是前端开发的"标准配置"。

/* 全局设置(每个项目都建议加上) */
*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

代码示例

.box {
    /* 内容尺寸 */
    width: 300px;
    height: 200px;

    /* 内边距:内容和边框之间的空间 */
    padding: 20px;                   /* 四个方向相同 */
    padding: 10px 20px;              /* 上下10px 左右20px */
    padding: 10px 20px 30px;         /* 上10px 左右20px 下30px */
    padding: 10px 20px 30px 40px;    /* 上10px 右20px 下30px 左40px(顺时针!) */
    /*
        padding 的四个值按照"上 → 右 → 下 → 左"的顺序
        记忆法:TRouBLe(Top Right Bottom Left)
    */

    /* 边框 */
    border: 2px solid #333;          /* 宽度 样式 颜色(简写) */
    border-top: 3px dashed red;      /* 单独设置某一边 */
    border-bottom: 3px dotted blue;
    border-left: 3px double green;
    border-right: 3px groove orange;
    /*
        border-style 样式:
        solid   → 实线(最常用)
        dashed  → 虚线
        dotted  → 点线
        double  → 双实线
        groove  → 凹槽
        ridge   → 山脊
    */
    border-radius: 8px;              /* 圆角(四个角相同) */
    border-radius: 8px 0 8px 0;      /* 左上 右上 右下 左下(顺时针) */
    border-radius: 50%;              /* 变成圆形/椭圆形 */

    /* 外边距 */
    margin: 20px;                    /* 四个方向相同 */
    margin: 10px auto;               /* 上下10px 左右自动居中 */
    /*
        margin: auto 的居中原理:
        当左右 margin 都是 auto 时,浏览器会把剩余空间平均分配给左右
        就像把一个盒子放在桌子中间,两边留一样宽的空隙
    */
    margin: 0 auto;                  /* 上下0 左右居中(最常用的居中方式) */

    /* 盒模型类型 */
    box-sizing: border-box;          /* 推荐值 */
}

/* margin 塌陷现象(重要!) */
/*
    上下相邻的两个 margin 会合并,取较大的值
    而不是相加

    示例:
    .box1 { margin-bottom: 30px; }
    .box2 { margin-top: 20px; }
    两个盒子之间的距离是 30px,不是 50px!

    这叫"外边距塌陷"(Margin Collapse)
    类比 Java:两个方法的返回值冲突时,取其中一个而不是相加
*/

3.7 常用文本样式

.text-demo {
    /* 字体 */
    font-family: "Microsoft YaHei", sans-serif;
    /*
        字体列表:从左到右查找
        如果用户电脑有"微软雅黑"就用微软雅黑
        没有就用 sans-serif(系统默认无衬线字体)
        就像 Java 的 ClassLoader 按顺序查找类
    */
    font-size: 16px;         /* 字号(px / em / rem) */
    /*
        px:像素(固定值)
        em:相对单位(相对于父元素的 font-size,1em = 父元素字号)
        rem:相对单位(相对于根元素 html 的 font-size)
        推荐用 px 或 rem
    */
    font-weight: bold;       /* 字重:normal(400) / bold(700) / 100-900 */
    font-style: italic;      /* 字体样式:normal / italic(斜体) */

    /* 字体简写(顺序:style weight size/height family) */
    font: italic bold 16px/1.5 "Microsoft YaHei", sans-serif;

    /* 颜色 */
    color: #333333;           /* 十六进制(最常用) */
    color: #333;              /* 简写:#3a3a3a = #3a3a, 不是 #333333 */
    color: rgb(51, 51, 51);   /* RGB 值(0-255) */
    color: rgba(51, 51, 51, 0.8); /* RGB + 透明度(0-1) */
    color: red;               /* 颜色名(约140个预定义颜色) */

    /* 行高 */
    line-height: 1.5;
    /*
        1.5 = 字号的1.5倍行高
        这是提升文本可读性最重要的属性!
        行高太小 → 文字挤在一起,看着累
        行高适中(1.5-1.8) → 阅读舒适
        类比 Word 中的"行距"
    */

    /* 文本对齐 */
    text-align: left;         /* 左对齐(默认) */
    text-align: center;       /* 居中对齐 */
    text-align: right;        /* 右对齐 */
    text-align: justify;      /* 两端对齐(像报纸排版) */

    /* 文本装饰 */
    text-decoration: none;    /* 去除下划线(a 标签默认有下划线,常这样去掉) */
    text-decoration: underline;
    text-decoration: line-through; /* 删除线 */

    /* 文本缩进 */
    text-indent: 2em;         /* 首行缩进2个字符(中文文章常用) */

    /* 字间距和词间距 */
    letter-spacing: 2px;      /* 字间距(每个字/字母之间的空间) */
    word-spacing: 5px;        /* 词间距(英文单词之间的空间) */

    /* 单行文本溢出省略号 */
    white-space: nowrap;      /* 不换行 */
    overflow: hidden;         /* 溢出隐藏 */
    text-overflow: ellipsis;  /* 显示省略号 */
    /* 三个属性必须配合使用!效果:超长文本显示为 "这是一段很长的文本..." */

    /* 多行文本溢出省略号 */
    display: -webkit-box;
    -webkit-line-clamp: 3;    /* 最多显示3行 */
    -webkit-box-orient: vertical;
    overflow: hidden;
}

3.8 背景样式

.bg-demo {
    /* 背景颜色 */
    background-color: #f5f5f5;
    /*
        颜色值可以是:
        - 单词:red, blue, transparent(透明)
        - 十六进制:#ff0000, #f00
        - RGB:rgb(255, 0, 0)
        - RGBA:rgba(255, 0, 0, 0.5)(带透明度)
    */

    /* 背景图片 */
    background-image: url("images/bg.jpg");
    /* url() 中可以是相对路径或绝对路径 */

    /* 背景平铺方式 */
    background-repeat: no-repeat;   /* 不平铺(最常用) */
    /* background-repeat: repeat; */    /* 平铺(默认,填满整个容器) */
    /* background-repeat: repeat-x; */  /* 水平平铺 */
    /* background-repeat: repeat-y; */  /* 垂直平铺 */

    /* 背景位置 */
    background-position: center center;  /* 水平居中 + 垂直居中 */
    background-position: top left;       /* 左上角 */
    background-position: 50% 50%;       /* 用百分比 */
    background-position: 10px 20px;     /* 用像素 */

    /* 背景大小 */
    background-size: cover;
    /*
        cover(最常用):等比例放大,覆盖整个容器,可能裁切
        → 像手机壁纸:图片铺满整个屏幕,超出部分裁掉

        contain:等比放大,完整显示图片,可能留白
        → 像PPT中的"适应画面":图片完整显示,两边可能有空白

        200px 100px:指定宽高(会变形)
        50%:宽度的50%(高度自动计算)
    */

    /* 背景固定(视差滚动效果) */
    background-attachment: fixed;
    /* 滚动页面时,背景图片不动(像固定的壁纸) */

    /* 简写(推荐!一个属性搞定所有) */
    background: #f5f5f5 url("images/bg.jpg") no-repeat center / cover;
    /*
        简写顺序:
        background: color image repeat position / size;
        不写的部分用默认值
    */
}

3.9 display 属性——块级 vs 行内

概念讲解

HTML 元素分为两大类:块级元素和行内元素。理解它们的区别是布局的基础。

通俗类比:

块级元素(Block)→ 就像排队的人,每个人占一整行
行内元素(Inline)→ 就像文字中的字母,多个字母排在一行

具体表现:
块级元素:
- 独占一行(前后各有一个隐形的换行)
- 可以设置宽高
- 默认宽度是父容器的 100%
- 代表:div, p, h1-h6, ul, ol, li, table, form

行内元素:
- 不会独占一行,和其他行内元素排在同一行
- 不能设置宽高(width/height 无效)
- 宽高由内容决定
- 代表:span, a, strong, em, img, input
/* display 属性可以改变元素的显示类型 */

/* 块级 —— 独占一行 */
display: block;
/* 应用:把 a 标签变成块级(让整个区域都可以点击) */

/* 行内 —— 不换行 */
display: inline;
/* 应用:把 div 变成行内(很少这样做) */

/* 行内块 —— 不换行但可以设宽高(最实用的混合模式) */
display: inline-block;
/* 应用:让多个元素横向排列,同时保持各自的宽高 */

/* 隐藏元素 —— 不占空间(从文档流中移除) */
display: none;
/*
    display: none vs visibility: hidden 的区别:
    display: none → 完全消失,不占空间(像从未存在过)
    visibility: hidden → 隐藏但占空间(像隐身人还占着座位)

    类比 Java:
    display: none → list.remove(obj)
    visibility: hidden → obj.setVisible(false)
*/

/* 弹性布局 */
display: flex;

/* 网格布局 */
display: grid;

3.10 浮动与清除浮动

概念讲解

浮动(float)曾经是 CSS 布局的核心方式,用来实现文字环绕图片的效果。后来被开发者"滥用"来做页面布局,但现在已经被 Flexbox 和 Grid 取代了。

浮动的本质:让元素"飘"起来,脱离正常的文档流,后面的内容会围绕它排列。

正常文档流(不浮动):
┌──────────────────────┐
│ [img] 文字文字文字文字 │
│       文字文字文字文字 │
└──────────────────────┘

左浮动后:
┌──────────────────────┐
│ [img] 文字文字文字文字 │
│       文字文字文字文字 │ ← 文字围绕在图片右边
└──────────────────────┘
/* 浮动 */
.left { float: left; }   /* 左浮动 */
.right { float: right; } /* 右浮动 */
.clear { clear: both; }  /* 清除浮动 */

/* 浮动的问题:父元素高度塌陷 */
/*
    当子元素全部浮动后,父元素的高度会变成 0(因为浮动元素脱离了文档流)

    .parent {
        // 高度塌陷为 0!
    }
    .child { float: left; height: 100px; }

    解决方法一:clearfix(推荐)
    .parent::after {
        content: "";
        display: block;
        clear: both;
    }

    解决方法二:BFC
    .parent { overflow: hidden; }
*/

后端程序员注意:浮动在现代 CSS 中已经很少使用了。了解概念即可,实际开发中用 Flexbox 和 Grid。


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐