CSS3 基础语法

从语法结构到现代特性的系统讲解

让网页从"能用"变成"好看"

为什么需要 CSS

你写好了一个结构完美的 HTML 页面,但打开浏览器一看——白底黑字,丑得像 1995 年的网页

没有 CSS

<h1>标题</h1>
<p>普通文字。</p>
<a href="#">链接</a>
<button>按钮</button>

→ 白底黑字
→ 全靠浏览器默认样式
→ 看起来像记事本

有 CSS

<h1>渐变标题,大字体</h1>
<p>舒适的行高和间距</p>
<a href="#">悬停变色的链接</a>
<button>圆角阴影按钮</button>

→ 配色和谐
→ 布局清晰
→ 有交互反馈
CSS(Cascading Style Sheets)是声明式语言,用于控制 HTML 的表现形式。三层结构:HTML 骨架 → CSS 皮肤 → JavaScript 肌肉。

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 选择器#mainid="main" 的唯一元素
通配符*所有元素
p        { color: #333; }     /* 所有段落 */
.error   { color: red; }      /* class="error" */
#logo    { width: 150px; }    /* id="logo" */
*        { margin: 0; padding: 0; box-sizing: border-box; }
注意:类名可重复使用,ID 必须唯一。命名推荐语义化小写加连字符:.nav-item、.card-title。

组合选择器

用关系符号组合多个选择器,精确定位元素

选择器示例含义
后代选择器div pdiv 内的所有 p(含嵌套)
子元素选择器ul > liul 的直接子元素 li
相邻兄弟h1 + p紧接 h1 后的第一个 p
通用兄弟h1 ~ ph1 后面所有同级 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 中的虚拟元素,通常用于装饰

伪元素示例用途
::beforep::before在内容前插入
::afterp::after在内容后插入
::first-linep::first-line选中第一行
::first-letterp::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; }  /* 强制蓝色 */
慎用 !important:它会让代码难以维护。当你发现需要用 !important 时,通常说明选择器写得太弱了,应该改选择器而不是加 !important。

特异性计算

同一来源的规则冲突时,按选择器"权重"决定胜负

选择器类型权重
内联样式1000
ID 选择器 #id100
类/属性/伪类 .class10
元素/伪元素 p1
/* 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);
}
核心思想:变量里存的是"意图"(如 --shadow-modal),而非"值"(如 0 10px 30px...)。未来改 modal 阴影只需改一行,不用理解每个数字的含义。

常用属性速查

日常开发最常写的 CSS 属性,查这张表就够了

类别属性常见值
文本color#333、red
font-size1.2rem
font-weight400、700
text-aligncenter、left
line-height1.6
背景background#f8f9fa、url() cover
边框border1px solid #ddd
border-radius8px、50%
box-shadow0 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 视觉特性。下一章进入布局系统。

下一章:CSS3 布局系统 →

1 / 27