一、元素选择器(标签选择器)

概念:直接用 HTML 标签名选中元素,页面中所有该标签都会被选中。
语法:标签名 { ... }
常用场景:统一设置某类标签的默认样式。
👇 演示:所有 p 都变成红色

我是段落内容

我也是段落内容

1/* CSS */ 2p { 3 color: red; 4 font-size: 16px; 5} 6 7/* HTML */ 8<p>我是段落内容</p> 9<p>我也是段落内容</p>

二、类选择器(class 选择器)

概念:通过 class="xxx" 属性选中元素,可以重复使用
语法:.类名 { ... }
常用场景:给多个元素设置相同样式(最常用的选择器之一)。
👇 演示:加了 class="highlight" 的文字变橙色加粗

我是普通文字

我是高亮文字(.highlight)

我是蓝色文字(.text-blue)

我也是普通文字

1/* CSS */ 2.highlight { 3 color: orange; 4 font-weight: bold; 5} 6 7.text-blue { 8 color: blue; 9} 10 11/* HTML */ 12<p>普通文字</p> 13<p class="highlight">高亮文字</p> 14<p class="text-blue">蓝色文字</p>

三、ID 选择器

概念:通过 id="xxx" 属性选中元素,一个 ID 只能用一次
语法:#id名 { ... }
常用场景:选中页面中唯一的元素(如导航栏、页脚)。
👇 演示:id="special" 的 p 变成紫色大号

我是普通段落

我是特殊段落(#special)

我也是普通段落

1/* CSS */ 2#special { 3 color: purple; 4 font-size: 18px; 5} 6 7/* HTML */ 8<p>普通段落</p> 9<p id="special">特殊段落</p>

四、通配符选择器

概念:* 选中页面中所有元素
语法:* { ... }
常用场景:清除默认边距(reset),但要慎用,可能影响性能。
👇 演示:所有元素的 margin 和 padding 被清零

这段文字紧贴边缘(margin: 0; padding: 0 生效)

1/* CSS — 通常放在最前面 */ 2* { 3 margin: 0; 4 padding: 0; 5 box-sizing: border-box; 6}

五、后代选择器

概念:选中某个元素内部所有符合条件的后代(不限层级)。
语法:祖先 后代 { ... }(中间用空格隔开)
常用场景:限定某个容器内的元素样式。
👇 演示:.ancestor 里面所有 span 都变绿(不管嵌套多深)
直接子 span → 绿色
孙辈 span → 也是绿色
1/* CSS */ 2.ancestor span { 3 color: green; 4 font-weight: bold; 5} 6 7/* HTML */ 8<div class="ancestor"> 9 <span>直接子 span</span> 10 <div> 11 <span>孙辈 span</span> <!-- 也被选中 --> 12 </div> 13</div>

六、子元素选择器

概念:只选中直接子元素(只隔一层)。
语法:父元素 > 子元素 { ... }(中间用 > 隔开)
对比:后代选择器选所有层级,子元素选择器只选亲儿子。
👇 演示:.parent 的直接子 p 变红,孙辈 p 不变

直接子 p → 红色

孙辈 p → 不变色

1/* CSS */ 2.parent > p { 3 color: red; 4} 5 6/* HTML */ 7<div class="parent"> 8 <p>直接子 p → 红色</p> 9 <div> 10 <p>孙辈 p → 不变</p> 11 </div> 12</div>

七、相邻兄弟选择器

概念:选中紧跟在某元素后面的第一个兄弟元素。
语法:元素A + 元素B { ... }(中间用 + 隔开)
常用场景:紧跟在标题后面的第一个段落特殊处理。
👇 演示:紧跟 h3 后面的第一个 p 变紫色

标题

紧跟标题的 p → 紫色加粗

第二个 p → 不变

1/* CSS */ 2.adjacent h3 + p { 3 color: purple; 4 font-weight: bold; 5} 6 7/* HTML */ 8<h3>标题</h3> 9<p>紧跟的 p → 紫色</p> 10<p>第二个 p → 不变</p>

八、通用兄弟选择器

概念:选中某元素后面所有符合条件的兄弟元素。
语法:元素A ~ 元素B { ... }(中间用 ~ 隔开)
对比:+ 只选第一个,~ 选后面所有。
👇 演示:h3 后面所有 p 都变蓝

标题

第一个 p → 蓝色

第二个 p → 蓝色

第三个 p → 蓝色

1/* CSS */ 2.sibling h3 ~ p { 3 color: blue; 4} 5 6/* HTML */ 7<h3>标题</h3> 8<p>第一个 p → 蓝色</p> 9<p>第二个 p → 蓝色</p> 10<p>第三个 p → 蓝色</p>

九、分组选择器

概念:同时选中多个元素,给它们设置相同的样式
语法:选择器1, 选择器2, 选择器3 { ... }(中间用逗号隔开)
常用场景:减少重复代码。
👇 演示:h3 和 p 同时变成橙色

我是标题

我是段落

我是 span(不受影响)
1/* CSS */ 2.group h3, 3.group p { 4 color: orange; 5} 6 7/* HTML */ 8<h3>标题 → 橙色</h3> 9<p>段落 → 橙色</p> 10<span>span → 不变</span>

十、属性选择器

概念:根据元素的属性来选中元素。
常见语法:
[属性名] — 有该属性就选中
[属性名="值"] — 属性值完全匹配
[属性名^="值"] — 属性值以...开头
[属性名$="值"] — 属性值以...结尾
[属性名*="值"] — 属性值包含...
👇 演示:不同属性选择器的效果
1/* CSS */ 2[title] { border: 2px solid red; } 3[type="text"] { border: 2px solid blue; } 4[href^="https"] { color: green; font-weight: bold; } 5[href$=".pdf"] { color: red; } 6[href*="github"] { color: purple; text-decoration: underline; } 7 8/* HTML */ 9<p title="提示">有 title 的段落</p> 10<input type="text"> 11<a href="https://github.com">GitHub</a> 12<a href="file.pdf">PDF 文件</a>

十一、:hover 伪类

概念:当鼠标悬停在元素上时触发。
语法:元素:hover { ... }
常用场景:按钮悬停变色、链接悬停效果。
👇 演示:鼠标悬停在下面的框上
鼠标悬停我试试 → 背景变蓝
1/* CSS */ 2.hover-box { 3 padding: 15px; 4 background: #ecf0f1; 5 transition: all 0.3s; 6} 7 8.hover-box:hover { 9 background: #3498db; 10 color: white; 11 transform: scale(1.02); 12}

十二、:active 伪类

概念:当元素被点击瞬间(鼠标按下未松开)时触发。
语法:元素:active { ... }
常用场景:按钮点击反馈效果。
👇 演示:鼠标按下不松开试试
点击我(按住不放) → 背景变红
1/* CSS */ 2.active-box:active { 3 background: red; 4 color: white; 5 transform: scale(0.98); 6}

十三、:focus 伪类

概念:当元素获得焦点时触发(如点击输入框、Tab 键切换)。
语法:元素:focus { ... }
常用场景:输入框聚焦时高亮边框。
👇 演示:点击输入框,边框变蓝并有光晕
1/* CSS */ 2.focus-input { 3 border: 2px solid #bdc3c7; 4 outline: none; 5 transition: border 0.3s; 6} 7 8.focus-input:focus { 9 border-color: #3498db; 10 box-shadow: 0 0 8px rgba(52, 152, 219, 0.3); 11}

十四、:first-child / :last-child

概念::first-child 选中父元素的第一个子元素:last-child 选中最后一个
语法:元素:first-child { ... }
常用场景:列表首尾项特殊样式。
👇 演示:第一个 li 红色,最后一个 li 蓝色
  • 第一个 → 红色加粗
  • 第二个
  • 第三个
  • 第四个 → 蓝色加粗
1/* CSS */ 2li:first-child { color: red; font-weight: bold; } 3li:last-child { color: blue; font-weight: bold; } 4 5/* HTML */ 6<ul> 7 <li>第一个 → 红色</li> 8 <li>第二个</li> 9 <li>第三个</li> 10 <li>第四个 → 蓝色</li> 11</ul>

十五、:nth-child

概念:按位置选中子元素。
:nth-child(odd) — 奇数项(第1、3、5...)
:nth-child(even) — 偶数项(第2、4、6...)
:nth-child(n) — 第 n 个(n 从 1 开始)
常用场景:斑马纹表格、隔行变色。
👇 演示:奇数行蓝底,偶数行橙底,第3个红色加粗
  • 第1个(奇数)→ 蓝底
  • 第2个(偶数)→ 橙底
  • 第3个 → 红色加粗
  • 第4个(偶数)→ 橙底
  • 第5个(奇数)→ 蓝底
1/* CSS */ 2li:nth-child(odd) { background: #ebf5fb; } 3li:nth-child(even) { background: #fdebd0; } 4li:nth-child(3) { color: red; font-weight: bold; }

十六、:not 伪类

概念:排除符合条件的元素,选中"除了这个以外"的所有元素。
语法:元素:not(.类名) { ... }
常用场景:给所有元素加样式,但排除某个特殊的。
👇 演示:所有 p 都是绿色加粗,除了 .skip

我是普通 p → 绿色加粗

我是 .skip → 灰色(被排除)

我也是普通 p → 绿色加粗

1/* CSS */ 2p { color: gray; } 3p:not(.skip) { color: green; font-weight: bold; } 4 5/* HTML */ 6<p>普通 p → 绿色</p> 7<p class="skip">.skip → 灰色</p> 8<p>普通 p → 绿色</p>

十七、::before / ::after 伪元素

概念:在元素内容的前面/后面插入额外内容,必须配合 content 属性使用。
语法:元素::before { content: "..."; }
常用场景:添加图标、装饰符号、计数器。
👇 演示:每个 p 前后自动加符号

我是段落内容

我也是段落内容

1/* CSS */ 2p::before { 3 content: "👉 "; 4} 5 6p::after { 7 content: " 👈"; 8} 9 10/* HTML */ 11<p>我是段落内容</p> 12/* 渲染结果:👉 我是段落内容 👈 */

十八、::first-letter 伪元素

概念:选中元素的第一个字符,可以单独设置样式。
语法:p::first-letter { ... }
常用场景:段首大字效果(类似报纸排版)。
👇 演示:第一个字是红色大号

hello world,这是第一个字符的演示效果。

1/* CSS */ 2p::first-letter { 3 font-size: 32px; 4 color: red; 5 font-weight: bold; 6} 7 8/* HTML */ 9<p>hello world</p> 10/* 渲染结果:第一个字母 h 变成红色大号 */

十九、::first-line 伪元素

概念:选中元素的第一行文字,根据浏览器窗口宽度动态变化。
语法:p::first-line { ... }
注意:只能用于块级元素,且只对文字生效。
👇 演示:第一行是蓝色加粗(缩放窗口会变化)

这是一段比较长的文字,用来演示 ::first-line 的效果。无论窗口多宽,只有第一行会变成蓝色加粗。当你改变浏览器窗口宽度时,第一行的内容会动态变化,蓝色加粗的范围也会跟着变。

1/* CSS */ 2p::first-line { 3 color: blue; 4 font-weight: bold; 5} 6 7/* HTML */ 8<p>这是一段比较长的文字...</p> 9/* 只有第一行变蓝,窗口宽度变化时范围动态调整 */

二十、::selection 伪元素

概念:选中文字被高亮选中时的样式。
语法:p::selection { ... }
常用场景:自定义选中文字的背景色和文字色。
👇 演示:用鼠标选中下面的文字,背景是黄色

用鼠标选中我试试,选中后的背景色是黄色,文字是深色。

1/* CSS */ 2p::selection { 3 background: #f1c40f; 4 color: #2c3e50; 5} 6 7/* HTML */ 8<p>选中我试试</p>

二十一、:root 伪类

概念::root 选中根元素(即 html),常用于定义 CSS 变量。
语法::root { --变量名: 值; }
常用场景:全局主题色、统一管理颜色/间距。
👇 演示:用 CSS 变量控制颜色

这段文字的颜色由 :root 定义的 --main-color 控制

1/* CSS */ 2:root { 3 --main-color: #3498db; 4} 5 6p { 7 color: var(--main-color); 8} 9 10/* 修改 :root 中的变量,所有使用它的地方都会变 */

二十二、:empty 伪类

概念:选中没有任何内容的元素(包括子元素和文本)。
语法:元素:empty { ... }
常用场景:空容器提示、表单空值警告。
👇 演示:空的 div 有红色背景提示
我有内容,正常显示
我也有内容
1/* CSS */ 2div:empty { 3 background: #fadbd8; 4} 5div:empty::after { 6 content: "这个 div 是空的"; 7 color: red; 8} 9 10/* HTML */ 11<div>有内容</div> 12<div></div> <!-- 空的,会变红 --> 13<div>有内容</div> 14<div></div> <!-- 空的,会变红 -->

二十三、:checked 伪类

概念:选中被勾选的复选框或单选按钮。
语法:input:checked + label { ... }
常用场景:自定义复选框样式、勾选后文字变化。
👇 演示:勾选后文字变绿并加删除线


1/* CSS */ 2input[type="checkbox"]:checked + label { 3 color: green; 4 font-weight: bold; 5 text-decoration: line-through; 6} 7 8/* HTML */ 9<input type="checkbox" id="c1"> 10<label for="c1">学习 HTML</label>

二十四、:disabled / :enabled

概念::disabled 选中被禁用的元素,:enabled 选中可用的元素。
语法:input:disabled { ... }
👇 演示:禁用的输入框是灰色,可用的是蓝色边框
1/* CSS */ 2input:disabled { background: #ecf0f1; cursor: not-allowed; } 3input:enabled { border: 2px solid blue; } 4 5/* HTML */ 6<input type="text" value="可用"> 7<input type="text" value="禁用" disabled>

二十五、:valid / :invalid

概念::valid 选中输入内容合法的表单元素,:invalid 选中不合法的。
语法:input:valid { ... } / input:invalid { ... }
常用场景:表单实时验证、输入框边框变色提示。
👇 演示:输入邮箱,合法绿色边框,不合法红色边框
1/* CSS */ 2input:valid { border: 2px solid green; } 3input:invalid { border: 2px solid red; } 4 5/* HTML */ 6<input type="email" placeholder="输入邮箱"> 7/* 输入 abc → 红色(不合法)*/ 8/* 输入 abc@123.com → 绿色(合法)*/

二十六、:only-child 伪类

概念:选中是其父元素唯一子元素的元素。
语法:元素:only-child { ... }
常用场景:单独一个子元素时特殊处理。
👇 演示:只有一个 li 的 ul 会被特殊标记
  • 我是唯一的 li → 红色加粗(:only-child)
  • 我有兄弟
  • 我也有兄弟
1/* CSS */ 2li:only-child { 3 color: red; 4 font-weight: bold; 5 background: #fadbd8; 6} 7 8/* HTML */ 9<ul> 10 <li>唯一的 li → 红色</li> 11</ul> 12<ul> 13 <li>有兄弟</li> 14 <li>也有兄弟</li> 15</ul>

二十七、:first-of-type / :last-of-type

概念::first-of-type 选中父元素中第一个同类型的子元素,:last-of-type 选中最后一个。
语法:p:first-of-type { ... }
对比::first-child 要求是第一个子元素,:first-of-type 只要是第一个 p 就行,前面可以有其他标签。
👇 演示:第一个 p 绿色,最后一个 p 紫色

这是标题

第一个 p → 绿色加粗(:first-of-type)

第二个 p

第三个 p → 紫色加粗(:last-of-type)

1/* CSS */ 2p:first-of-type { color: green; font-weight: bold; } 3p:last-of-type { color: purple; font-weight: bold; } 4 5/* HTML */ 6<h3>标题</h3> 7<p>第一个 p → 绿色</p> 8<p>第二个 p</p> 9<p>第三个 p → 紫色</p>

二十八、:nth-of-type

概念:按类型选择子元素,只计算同类型的元素。
:nth-of-type(odd) — 同类型中的奇数项
:nth-of-type(even) — 同类型中的偶数项
对比::nth-child 计算所有子元素,:nth-of-type 只计算同类型。
👇 演示:p 标签奇数行蓝底,偶数行橙底

标题不参与计算

第一个 p(奇数)→ 蓝底

第二个 p(偶数)→ 橙底

第三个 p(奇数)→ 蓝底

1/* CSS */ 2p:nth-of-type(odd) { background: #ebf5fb; } 3p:nth-of-type(even) { background: #fdebd0; } 4 5/* HTML */ 6<h3>标题不参与计算</h3> 7<p>第一个 p(奇数)</p> 8<p>第二个 p(偶数)</p> 9<p>第三个 p(奇数)</p>

二十九、:required / :optional

概念::required 选中必填的表单元素,:optional 选中选填的。
语法:input:required { ... }
判断依据:有 required 属性就是必填,没有就是选填。
👇 演示:必填红色边框,选填绿色边框
1/* CSS */ 2input:required { border: 2px solid red; } 3input:optional { border: 2px solid green; } 4 5/* HTML */ 6<input type="text" required> <!-- 必填 → 红色 --> 7<input type="text"> <!-- 选填 → 绿色 -->

三十、选择器优先级

概念:当多个选择器选中同一个元素时,按优先级决定谁生效。
优先级从低到高:
1. 元素选择器(p)→ 权重 1
2. 类选择器(.class)→ 权重 10
3. ID 选择器(#id)→ 权重 100
4. inline 样式 → 权重 1000
口诀:ID > 类 > 元素,权重高的覆盖权重低的。
👇 演示:同一个 p 元素被三个选择器选中,最终 #id 生效

我是同一个 p,最终显示红色加粗(ID 优先级最高)

1/* CSS — 三个选择器都选中了这个 p */ 2p { color: gray; } /* 权重 1 */ 3.specific { color: blue; } /* 权重 10 */ 4#very-specific { color: red; font-weight: bold; } /* 权重 100 ✓ */ 5 6/* HTML */ 7<p id="very-specific" class="specific">最终显示红色</p> 8 9/* 如果要强制覆盖,可以用 !important(但不推荐滥用)*/ 10/* p { color: gray !important; } */