CSS3 基础语法
从语法结构到现代特性的系统讲解
让网页从"能用"变成"好看"为什么需要 CSS
你写好了一个结构完美的 HTML 页面,但打开浏览器一看——白底黑字,丑得像 1995 年的网页
没有 CSS
<h1>标题</h1>
<p>普通文字。</p>
<a href="#">链接</a>
<button>按钮</button>
→ 白底黑字
→ 全靠浏览器默认样式
→ 看起来像记事本
有 CSS
<h1>渐变标题,大字体</h1>
<p>舒适的行高和间距</p>
<a href="#">悬停变色的链接</a>
<button>圆角阴影按钮</button>
→ 配色和谐
→ 布局清晰
→ 有交互反馈
Part 1: 引入方式
有四种方式把 CSS 塞进 HTML,但只有一种是最佳实践。
内联与内部样式
了解即可。内联写在 style 属性里,内部写在 head 的 style 标签里——都难复用。
外部样式表
独立 .css 文件,多页面共享,浏览器缓存,一处修改全局生效——唯一推荐的做法。
内联与内部样式
了解即可,不推荐日常使用
内联样式
<p style="color: red;
font-size: 18px;">
红色文字
</p>
写在 style 属性里。优先级高但无法复用。
内部样式表
<head>
<style>
body { font-family: Arial; }
h1 { color: #333; }
</style>
</head>
写在 head 的 style 标签里。不能跨页面复用。
外部样式表
独立 .css 文件,多页面共享——这是唯一推荐的标准做法
<!-- HTML 文件 head 中 -->
<link rel="stylesheet" href="style.css">
/* style.css */
body {
margin: 0;
font-family: 'Segoe UI', sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
为什么推荐外部样式
- 复用:多个页面共享同一份 CSS
- 缓存:浏览器缓存 .css 文件,加载更快
- 维护:改一处,全局生效
- 分离:HTML 管结构,CSS 管样式
Part 2: 语法规则
CSS 的语法极其简单:选择器 + 大括号里的声明。
规则结构
选择器 { 属性: 值; } — "给谁穿什么衣服"。
五个组成部分
选择器、声明块、声明、属性、值 — 理解这些术语是读懂 CSS 的前提。
基本语法结构
一条 CSS 规则 = "给谁穿什么衣服"
选择器 {
属性名: 属性值;
属性名: 属性值;
/* 注释 */
}
/* 实际示例 */
h1 {
color: #2c3e50;
font-size: 2.5rem;
margin-bottom: 1rem;
text-align: center;
}
| 组成部分 | 说明 |
|---|---|
| 选择器 | 决定哪些元素应用样式(如 h1、.btn) |
| 声明块 | {} 内的所有内容 |
| 声明 | 一条完整的"属性: 值;"语句 |
| 属性 | 样式特征名(如 color、margin) |
| 值 | 属性的具体取值(如 red、20px) |
Part 3: 选择器
选择器是 CSS 的"定位器"——告诉浏览器"给谁穿衣服"。
基础与组合
类型、类、ID、通配符 — 四种基础选择器。后代、子元素、兄弟 — 组合精确匹配。
属性与伪类
按属性值匹配、按元素状态匹配(:hover、:focus)— 无需改 HTML 即可扩展样式。
基础选择器
四种最基本的选择方式,覆盖 90% 的日常需求
| 选择器 | 示例 | 匹配对象 |
|---|---|---|
| 类型选择器 | p | 所有 p 元素 |
| 类选择器 | .header | 所有 class="header" 的元素 |
| ID 选择器 | #main | id="main" 的唯一元素 |
| 通配符 | * | 所有元素 |
p { color: #333; } /* 所有段落 */
.error { color: red; } /* class="error" */
#logo { width: 150px; } /* id="logo" */
* { margin: 0; padding: 0; box-sizing: border-box; }
.nav-item、.card-title。
组合选择器
用关系符号组合多个选择器,精确定位元素
| 选择器 | 示例 | 含义 |
|---|---|---|
| 后代选择器 | div p | div 内的所有 p(含嵌套) |
| 子元素选择器 | ul > li | ul 的直接子元素 li |
| 相邻兄弟 | h1 + p | 紧接 h1 后的第一个 p |
| 通用兄弟 | h1 ~ p | h1 后面所有同级 p |
div p { color: blue; } /* div 里的 p 蓝色 */
div > p { font-weight: bold; } /* div 直接子 p 加粗 */
h1 + p { margin-top: 0; } /* 紧接 h1 的 p 无上边距 */
h1 ~ p { color: gray; } /* h1 后所有同级 p 变灰 */
属性与伪类
根据属性值或元素状态来匹配
属性选择器
/* 有 target 属性的元素 */
a[target] { }
/* href 以 https 开头 */
a[href^="https"] { }
/* src 以 .png 结尾 */
img[src$=".png"] { }
/* class 包含 btn */
[class*="btn"] { }
伪类(元素状态)
/* 鼠标悬停 */
a:hover { color: red; }
/* 获得焦点 */
input:focus { border: 2px solid blue; }
/* 被点击时 */
button:active { }
/* 第一个子元素 */
li:first-child { }
/* 奇偶行 */
tr:nth-child(even) { }
伪元素
创建不存在于 DOM 中的虚拟元素,通常用于装饰
| 伪元素 | 示例 | 用途 |
|---|---|---|
::before | p::before | 在内容前插入 |
::after | p::after | 在内容后插入 |
::first-line | p::first-line | 选中第一行 |
::first-letter | p::first-letter | 选中首字母 |
/* 引用装饰 */
.quote::before {
content: "\201C";
font-size: 2em;
color: #ccc;
}
/* 清除浮动(经典用法) */
.clearfix::after {
content: "";
display: table;
clear: both;
}
content 属性使用(::first-line 等例外)。没有 content,伪元素不会出现。
Part 4: 优先级
当多条规则冲突时,浏览器怎么知道听谁的?
层叠规则
浏览器默认 → 用户样式 → 外部样式 → 内联样式 → !important — 五级优先级。
特异性计算
内联(1000) > ID(100) > 类(10) > 元素(1) — 用权重数学决定同一来源内的胜负。
层叠规则
优先级从低到高,后面的覆盖前面的
1. 浏览器默认样式 (最低)
2. 用户样式表
3. 外部/内部样式表
4. 内联样式
5. !important (最高,慎用)
/* 正常情况下,后面的覆盖前面的 */
p { color: black; }
p { color: red; } /* 生效:红色 */
/* !important 可以打破一切规则 */
p { color: blue !important; } /* 强制蓝色 */
特异性计算
同一来源的规则冲突时,按选择器"权重"决定胜负
| 选择器类型 | 权重 |
|---|---|
| 内联样式 | 1000 |
ID 选择器 #id | 100 |
类/属性/伪类 .class | 10 |
元素/伪元素 p | 1 |
/* 0,0,0,1 — 权重 1 */
p { color: black; }
/* 0,0,1,0 — 权重 10 */
.error { color: red; }
/* 0,1,0,0 — 权重 100 */
#header { color: blue; }
/* 0,0,1,1 — 权重 11 → 胜出 */
div.error { color: green; }
内联 > ID > 类 > 元素。就像军衔——将军 > 校官 > 尉官 > 士兵。
Part 5: 盒模型
每个 HTML 元素都是一个矩形盒子。理解盒模型是理解 CSS 布局的基础。
两种盒模型
content-box(默认)width 只含内容,border-box(推荐)width 包含 padding 和 border。
全局最佳实践
* { box-sizing: border-box; } — 一行代码让所有元素使用 border-box,布局计算简单可靠。
两种盒模型
content-box 和 border-box 的区别,直接影响你的布局计算
content-box(默认)
width 只包含内容区。
.box {
width: 200px;
padding: 20px;
border: 5px solid;
}
/* 实际占用 = 200 + 40 + 10
= 250px */
加了 padding 和 border,盒子比 200px 宽。容易算错。
border-box(推荐)
width 包含内容 + padding + border。
.box {
box-sizing: border-box;
width: 200px;
padding: 20px;
border: 5px solid;
}
/* 实际占用 = 200px
内容区 = 200 - 40 - 10
= 150px */
width 就是最终宽度。再也不用算加法。
* { box-sizing: border-box; }。这样所有元素都用 border-box,布局计算简单可靠。
content-box(默认)
┌─ margin ──────────────────┐
│ ┌─ border ──────────────┐ │
│ │ ┌─ padding ─────────┐ │ │
│ │ │ ┌─ width = content ─┐ │ │ │
│ │ │ │ │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘
实际占宽 = content + padding + border + margin
你设置的 width 只管最内层内容区,加上 padding/border 后会比预期更宽。
border-box(推荐)
┌─ margin ──────────────────┐
│ ┌─ width ───────────────┐ │
│ │ ┌─ border ──────────┐ │ │
│ │ │ ┌─ padding ─────┐ │ │ │
│ │ │ │ content │ │ │ │
│ │ │ └───────────────┘ │ │ │
│ │ └───────────────────┘ │ │
│ └───────────────────────┘ │
└───────────────────────────┘
实际占宽 = width + margin
你设置的 width 就是肉眼可见的盒子宽度,padding/border 向内挤占内容区,布局更好算。
Part 6: CSS3 特性
CSS3 带来了渐变、过渡、变换和动画——让网页从静态变成生动。
渐变与过渡
linear-gradient 让背景有层次,transition 让交互有温度——悬停变色、按钮弹起。
变换与动画
translate/scale/rotate 让元素动起来,@keyframes 让元素按剧本表演。
渐变与过渡
渐变让背景有层次感,过渡让交互有温度
渐变
/* 线性渐变 */
.gradient {
background: linear-gradient(
45deg, #ff6b6b, #51cf66
);
}
/* 径向渐变 */
.radial {
background: radial-gradient(
circle, #ff9a9e, #fecfef
);
}
过渡
.button {
background: #007bff;
transition:
background 0.3s ease,
transform 0.2s;
}
.button:hover {
background: #0056b3;
transform: translateY(-2px);
}
transition-property 过渡哪个属性 ② transition-duration 持续多久 ③ transition-timing-function 缓动函数 ④ transition-delay 延迟时间。
变换与动画
transform 让元素动起来,animation 让元素按剧本表演
变换(Transform)
/* 位移 */
transform: translate(10px, -5px);
/* 缩放 */
transform: scale(1.2);
/* 旋转 */
transform: rotate(45deg);
/* 倾斜 */
transform: skew(10deg);
/* 组合使用 */
.icon {
transform: scale(1.1) rotate(5deg);
}
动画(Animation)
/* 定义关键帧 */
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
/* 应用动画 */
.fade-in {
animation: fadeIn 1s ease-in;
}
/* 弹跳动画 */
@keyframes bounce {
0% { transform: translateY(0); }
100% { transform: translateY(-20px); }
}
.bounce {
animation: bounce 0.6s
ease-in-out infinite alternate;
}
为什么需要自定义变量
一个颜色值在 20 个地方使用,改一次要搜遍整个 CSS?
手写常量
.button { background: #D06519; }
.title { color: #D06519; }
.link { border-color: #D06519; }
.badge { background: #D06519; }
/* ... 还有 16 处 */
/* 换品牌色?搜 #D06519 → 全替换 → 漏一个就翻车 */
🔴 维护噩梦:改一个颜色需要修改 N 处
用变量
:root {
--primary: #D06519;
}
.button { background: var(--primary); }
.title { color: var(--primary); }
.link { border-color: var(--primary); }
.badge { background: var(--primary); }
/* 换品牌色?改 :root 里的一行即可 */
🟢 一处定义,处处生效
声明与使用
定义在 :root 里的变量 = 全局可用
/* 在 :root 中声明 = 全局作用域 */
:root {
--primary: #D06519;
--text: #1A1A1A;
--bg: #F9F9F7;
--radius: 14px;
--font-body: 'DM Sans', sans-serif;
}
/* 使用 var() 引用 */
.card {
background: var(--bg);
color: var(--text);
border-radius: var(--radius);
}
.button {
background: var(--primary);
color: white;
padding: 10px 20px;
border-radius: var(--radius);
}
const primary = '#D06519',你已经会了!声明一次,使用一千次。
-- 开头,命名的是"意图"而非"值" —— --color-danger 比 --red-500 更可维护。
变量继承与 fallback
子元素可以覆盖父元素的变量,就像作用域
:root {
--card-bg: #fff;
}
.card {
background: var(--card-bg);
}
/* 暗色主题卡片:覆盖变量即可 */
.card.dark {
--card-bg: #1a1a1a;
color: #f0f0f0;
}
/* .card.dark 内部所有用 var(--card-bg) 的地方都变成暗色 */
fallback 默认值
/* 如果 --accent 没定义,就用 #D06519 */
color: var(--accent, #D06519);
/* 即使未声明变量,页面也不会报错 */
只换一行 = 主题切换
/* 全局亮色主题 */
:root { --bg: #fff; --text: #1a1a1a; }
/* 用户在设置里勾选暗色模式 */
body.dark {
--bg: #1a1a1a;
--text: #f0f0f0;
}
/* 所有用 --bg / --text 的组件自动切换 */
变量与设计系统
好的变量命名让样式表像说明书一样易读
:root {
/* —— 字号阶梯 —— */
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 2rem;
/* —— 间距系统 —— */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-6: 24px;
--space-8: 32px;
--space-12: 48px;
/* —— 圆角层级 —— */
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 16px;
--radius-full: 9999px;
/* —— 阴影层级 —— */
--shadow-card: 0 2px 8px rgba(0,0,0,0.08);
--shadow-modal: 0 10px 30px rgba(0,0,0,0.15);
--shadow-float: 0 4px 12px rgba(0,0,0,0.12);
}
常用属性速查
日常开发最常写的 CSS 属性,查这张表就够了
| 类别 | 属性 | 常见值 |
|---|---|---|
| 文本 | color | #333、red |
font-size | 1.2rem | |
font-weight | 400、700 | |
text-align | center、left | |
line-height | 1.6 | |
| 背景 | background | #f8f9fa、url() cover |
| 边框 | border | 1px solid #ddd |
border-radius | 8px、50% | |
box-shadow | 0 2px 8px rgba(0,0,0,0.1) |
动手练习
选择器练习
- 写 5 种不同的选择器,让同一个段落显示不同颜色,验证优先级
- 用
:nth-child实现表格隔行变色 - 用
::before给链接添加外链图标
盒模型练习
- 创建两个 200px 宽的盒子,分别用 content-box 和 border-box,对比实际宽度
- 给按钮添加 padding、border、border-radius 和 box-shadow
CSS3 练习
- 创建一个悬停时放大 + 变色的按钮
- 用
@keyframes实现文字从左滑入的效果 - 给页面添加一个渐变背景
本章学习完毕
你已经掌握了 CSS 的语法规则、选择器系统、优先级计算、盒模型和 CSS3 视觉特性。下一章进入布局系统。