主题
CSS 选择器(Day6 4/4)
本页对应 Day06_CSS,共 5 段视频,约 54 分钟。
学习目标
- 能区分并正确书写交集选择器与并集选择器,说明二者匹配条件、分隔符差异,并通过示例验证选择结果。
- 能使用标签名、类名、ID及层级选择器组合成交集选择器,正确处理标签名在前、伪类在后等书写位置限制。
- 能使用
:link、:visited、:hover、:active设置元素状态样式,说明各伪类触发条件及适用元素范围。 - 能按
link → visited → hover → active顺序书写多个伪类选择器,并解释该顺序对样式覆盖和用户体验的影响。 - 能计算组合选择器权重:先比较 ID 数量,再比较类与伪类数量,最后比较标签名数量;权重相同时后写覆盖先写。
- 能识别并集选择器不合并权重、行内样式优先级最高,并使用浏览器开发者工具检查伪类状态与样式覆盖关系。
知识点
交集选择器:两个条件必须同时满足
为什么需要:有时只想选中“既是 p 标签、又带 item 类名”的元素,单写 p 或 .item 都会选多。
怎么想:把多个选择器紧挨着写,表示“并且”。p.item 就是标签名是 p,类名是 item,缺一不可。
怎么做:
html
<div class="wrapper">
<p class="item">段落一</p>
<p class="item active">段落二</p>
</div>
<p class="item">段落三</p>css
.wrapper { padding: 20px; width: 600px; background: #ccc; }
p { width: 560px; background: #aaa; }
p.item { background: #900; color: #fff; }
.wrapper p.item { /* 从 .wrapper 后代中找既是 p 又是 .item 的元素 */ }
.item.active { font-size: 2em; }p.item 只命中前两个在 .wrapper 里的 p;外面那个只有类名、标签名不对,不命中。交集还能和层级组合:.wrapper p.item。类名和类名也能交集:.item.active,顺序无所谓。
易错点:标签名参与交集时必须写前面,.item p 不是交集;写成 p .item 中间加空格就变成后代选择器。标签名和标签名不能做交集,因为一个元素只有一个标签名。
并集选择器:逗号分隔,各选各的
为什么需要:想让多个不同选择器共享同一组样式,比如所有标题都不加粗。
怎么想:逗号表示“或者”,选择器一选中的、选择器二选中的,全都要。
怎么做:
css
p, li { border: 2px solid #900; }
h1, h2, h3, h4 { font-weight: normal; }也可以混着写:.item, p。
易错点:并集不是把多个选择器合成一个整体去比权重,而是拆开各自计算。h1, h2 不能算成“两个标签名”来压别人。
伪类选择器:根据状态选元素
为什么需要:超链接有未访问、已访问、鼠标悬停、按下未抬起等状态,普通选择器选不到“状态”。
怎么想:伪类就是“当元素处于某种状态时”再选中它。四个常用状态::link 未访问超链接,:visited 已访问超链接,:hover 鼠标悬停,:active 鼠标按下未抬起。
怎么做:
css
a:link { color: pink; }
a:visited { color: #099; }
a:hover { color: #990; }
a:active { color: red; }
.news li:hover { background: #ccc; color: #fff; }:hover、:active 不挑元素,其他元素也能用;但通常写成交集,如 a:hover、.news li:hover,否则 :hover 会命中任何被悬停的元素。
易错点::link、:visited 主要针对超链接;伪类与其他选择器做交集时,伪类要写在后边,a:hover 不能写成 :hover a。调试时可在开发者工具里给元素强制 :hover、:active 状态,观察哪些规则命中、哪些被删除线覆盖。
多个伪类一起写:顺序影响体验
为什么需要:一个超链接可能同时满足 :visited 和 :hover,样式冲突时后写的覆盖先写的。
怎么想:权重相同,就看书写顺序。越不容易发生的状态,越应写后面,让用户操作后能看到反馈。
怎么做:按 LVHA 写:
css
a:link { color: pink; }
a:visited { color: #099; }
a:hover { color: #990; }
a:active { color: red; }易错点:把 :hover 写在 :visited 前,鼠标放上去仍显示已访问颜色;把 :active 写在 :hover 前,按下时会被 :hover 覆盖。记忆法可记“love hate”:L-V-H-A。语法上并非强制,但为了用户体验应这样排。
选择器权重:先比 ID,再比类/伪类,再比标签
为什么需要:多个规则选中同一元素且样式冲突时,必须知道谁生效。
怎么想:逐级比较数量:先比 ID 数量,多者赢;ID 相同再比“类 + 伪类”数量;还相同再比标签名数量;最后仍相同,后写的覆盖先写的。
怎么做:
css
.news-item { color: red; }
ul li { color: green; } /* 类干不过 .news-item */
#book { background: #990; }
.news li.news-item.active { background: #099; } /* ID 数量多,赢 */伪类和类权重相同。并集要拆开各自算;行内 style 优先级最高。
易错点:不要用 100/10/1 硬加分数,遇到多个 ID 时按“逐级数量比较”更稳;权重相同才看先后,且只覆盖冲突属性,不冲突的样式会层叠保留。
作业说明与完成范围
本节笔记是两次作业提交:一是“背景图片固定案例”,二是“列表效果案例”。笔记只给了案例链接和一条关键提示:ul、ol 自带 40px 左内边距 padding-left。转写稿主要讲的是交集选择器、并集选择器、伪类选择器、伪类书写顺序和选择器权重,与“背景图片固定”没有直接对应内容;其中可直接用于本节作业的,是列表默认缩进、list-style 重置以及 :hover 调试这一段。因此下面不虚构背景固定案例的课堂调试过程,只按作业目标给出验收思路;列表部分则结合转写稿中的做法展开。
本节笔记未提供图片,故不虚构图片;下面保留笔记中的两个作业链接,并给出列表练习中可复用的代码。
作业一:背景图片固定案例
为什么需要:页面滚动时,如果背景图跟着内容一起滚,视觉上会比较“晃”;把背景图固定住,可以让内容在背景上滚动,形成层次感。这个作业要练的是背景相关属性,而不是单纯换一张图。
怎么想:先明确“固定”指的是背景图相对视口固定,不是让整个容器固定。实现时通常给带背景图的容器设置背景图片、背景位置、背景尺寸,再设置 background-attachment: fixed。检查时滚动页面,观察内容是否移动、背景图是否保持不动。
怎么做:按笔记链接完成页面:
https://example.fuming.site/HTML&CSS/04-%E8%83%8C%E6%99%AF%E5%9B%BE%E5%9B%BA%E5%AE%9A.html
完成后重点自检:背景图路径是否正确;容器是否有足够高度让页面产生滚动;滚动时背景是否固定;背景图是否被裁切或重复。由于转写稿没有该案例的具体代码,这里不补造课堂写法,只保留作业目标与验收点。
易错点:只写 background-image 而忘记 background-attachment: fixed;容器没有高度,页面滚不起来,看不出效果;图片路径写错;把 fixed 误解成“容器固定”;背景图尺寸没有配合 background-size,导致只看到局部。提交前一定要实际滚动页面验证。
作业二:列表效果案例
为什么需要:列表默认带有项目符号和左缩进,直接做新闻列表或导航时往往不符合设计稿。作业要练的是:会重置列表默认样式,会控制列表项间距,会用 :hover 做鼠标悬停反馈。
怎么想:转写稿里说得很清楚:列表往右缩进“其实就是一内边距,是 ul 自带的左内边距”。所以只写 list-style: none 只能去掉小圆点,不能去掉缩进;还要把 padding-left 归零。笔记也提示:ul、ol 自带 40px 左内边距 padding-left。想清楚这两层,列表重置就不会只做一半。
怎么做:按链接完成列表页:
https://example.fuming.site/HTML&CSS/05-%E5%88%97%E8%A1%A8.html
可复用转写稿中的列表练习写法:
css
.news {
list-style: none;
padding-left: 0;
width: 600px;
}
.news li {
padding: 10px;
}
.news li:hover {
background: #ccc;
}转写稿中的调试过程是:鼠标放到哪个 li 上,哪个 li 变色;鼠标离开后样式恢复。也可以在开发者工具中给元素临时加上 :hover 状态,检查选择器是否选中、样式是否生效。
易错点:只写 list-style: none,忘记 padding-left: 0;把 padding-left 写成 margin-left;:hover 前面不加限定,导致页面其他元素也被影响;选择器写错层级,例如把 .news li:hover 写成 .news:hover li;忘记检查鼠标离开后的恢复状态。提交前用开发者工具确认默认缩进来源,并实际悬停测试。
课堂画面





代码示例
示例一:交集选择器与并集选择器
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>交集选择器与并集选择器</title>
<style>
/* 并集选择器:逗号分隔,各算各的,谁符合谁生效 */
h1, h2, h3, h4 {
font-weight: normal;
}
.wrapper {
width: 600px;
padding: 20px;
background-color: #ccc;
}
p {
width: 560px;
padding: 10px;
background-color: #ccc;
}
/* 交集选择器:标签名 p 且 类名 item,缺一不可 */
p.item {
background-color: #900;
color: #fff;
}
/* 交集选择器与后代选择器组合:wrapper 后代中,既是 p 又是 .item */
.wrapper p.item {
background-color: #099;
}
/* 类名与类名组合:顺序无所谓,.active.item 效果一样 */
.item.active {
font-size: 2em;
}
</style>
</head>
<body>
<h1>标题一(不再加粗)</h1>
<h2>标题二(不再加粗)</h2>
<div class="wrapper">
<p>普通段落</p>
<p class="item">wrapper 内的 item 段落</p>
<p class="item active">wrapper 内的 item + active 段落</p>
</div>
<p>wrapper 外的普通段落</p>
<p class="item">wrapper 外的 item 段落</p>
<p class="item active">wrapper 外的 item + active 段落</p>
</body>
</html>关键行与易错点
p.item之间没有任何分隔符,表示“标签名是 p 且 类名是 item”;写成p .item(加空格)就变成后代选择器,意思完全变了。- 有标签名参与交集组合时,标签名只能写在前面:
p.item合法,.itemp会被当成类名,.item+ 空格 +p则是后代选择器。 - 类名与类名组合(
.item.active)顺序无所谓,因为两个都有.作分隔符。 .wrapper p.item权重(1 类 + 1 类 + 1 标签)高于p.item(1 类 + 1 标签),所以 wrapper 内的 item 段落背景最终是#099,不是#900——这就是“权重高者胜”。- 并集选择器
h1, h2, h3, h4只是简写,权重各自计算,不会叠加。
示例二:伪类选择器(超链接四态 + 列表 hover)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>伪类选择器</title>
<style>
/* 书写顺序:link → visited → hover → active,即 love hate 记忆法 */
a:link { color: #f0f; } /* 未访问过的超链接 */
a:visited { color: #099; } /* 已访问过的超链接 */
a:hover { color: #990; } /* 鼠标悬停 */
a:active { color: #f00; } /* 鼠标按下不松手 */
.news {
width: 600px;
list-style: none; /* 去掉小圆点 */
padding: 0; /* 去掉 ul 自带的 40px 左内边距 */
}
.news li {
padding: 10px;
}
/* 后代选择器 + 交集:.news 后代的 li,且鼠标悬停其上 */
.news li:hover {
background-color: #ccc;
color: #fff;
}
</style>
</head>
<body>
<a href="https://www.baidu.com">百度</a>
<a href="https://www.douban.com">豆瓣</a>
<a href="https://www.360.com">360</a>
<a href="https://www.4399.com">4399</a>
<ul class="news">
<li>新闻列表第一条新闻消息</li>
<li>新闻列表第二条新闻消息</li>
<li>新闻列表第三条新闻消息</li>
</ul>
</body>
</html>关键行与易错点
:link/:visited只对超链接有意义;:hover/:active是不挑元素的,任何元素都能用(如上例的li:hover)。- 伪类与其他选择器做交集组合时,伪类必须写在后面(
a:hover可以,:hovera不成立),这和标签名必须写前面的规则刚好相反。 - 直接裸写
:hover相当于*:hover,会让页面所有元素都响应,实际开发一定要加交集限定,如.news li:hover。 - 四个伪类同时写时按 LVHA(link → visited → hover → active) 顺序,否则会被同权重的后写规则覆盖:例如
a:visited写在a:hover后面,鼠标移上去颜色根本不变。 ul、ol自带 40px 的padding-left(列表缩进),要清掉就写padding: 0,同时list-style: none去掉项目符号。
示例三:组合选择器权重比较
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>选择器权重</title>
<style>
ul {
width: 600px;
padding: 0;
list-style: none;
}
li {
padding: 10px;
margin-top: 10px;
background-color: #ccc;
}
/* 权重:1 个类 = 10 */
.news-item {
color: #f00;
}
/* 权重:2 个标签名 = 2,干不过上面的 10,写后边也没用 */
ul li {
color: #080;
}
/* 权重:3 类 + 1 标签 = 31 */
.news li.news-item.active {
background-color: #099;
}
/* 权重:1 个 ID = 100,碾压上面所有组合 */
#book {
background-color: #990;
}
</style>
</head>
<body>
<ul class="news">
<li class="news-item">第一条新闻</li>
<li class="news-item active" id="book">第二条新闻</li>
<li class="news-item">第三条新闻</li>
</ul>
</body>
</html>关键行与易错点
- 权重速记:ID = 100,类 / 伪类 = 10,标签名 = 1,通配符
*不计;伪类和类权重相同。 - 比较规则是“逐级 PK”:先比 ID 数量,多者胜就结束;ID 打平再比类 + 伪类数量;还打平再比标签名数量;全打平则后写的覆盖先写的(仅限有冲突的样式,不冲突的会层叠共存)。
ul li虽然写在.news-item后面,但权重 2 < 10,所以文字还是红色——权重不够,位置再靠后也没用。.news li.news-item.active虽然类名堆到 31,仍然干不过一个#book的 100,所以第二条背景最终是#990。- 并集选择器(逗号)不参与合并计算,要拆开各自算权重;只有后代、子元素、交集这类组合才把权重加在一起。
- 行内
style和!important不属于选择器权重体系,优先级更高,不要和这里的比较规则混为一谈。
常见错误
- 现象:
p .item选中了错误元素或完全失效 → 原因:交集选择器中间多写空格,变成后代选择器 → 修法:写成p.item,选择器之间无分隔符。 - 现象:
a :hover悬停时父级/后代异常,目标链接不生效 → 原因:伪类前多空格,条件被拆成后代关系 → 修法:限制元素时紧贴写a:hover,需要多条件时用交集组合。 - 现象:超链接
:hover、:active明明写了却不显示 → 原因:四个伪类顺序不当,同权重时后写规则覆盖前写规则 → 修法:按:link、:visited、:hover、:active的顺序检查并调整。 - 现象:组合选择器权重判断错误,以为多个标签名能压过一个类名 → 原因:把权重当成固定十进制相加 → 修法:先比 ID 数量,再比类+伪类数量,再比标签名数量;仍相同才由后写覆盖。
- 现象:并集选择器整体参与权重比较,导致样式覆盖判断错误 → 原因:把逗号两侧当成一个组合选择器 → 修法:并集拆开,各自计算各自权重。
- 现象:列表案例左侧缩进、对齐与设计稿不一致 → 原因:忽略
ul、ol默认padding-left: 40px→ 修法:显式重置或重设padding-left,再调整list-style与间距。
练习
- 写一个交集选择器,只选中同时具有
item和active两个类名的li,为其设置背景色与文字颜色;验收:只有同时具备两个类名的列表项变化。 - 完成新闻列表悬停高亮:鼠标移到哪个
li,哪个li变色;验收:使用:hover交集写法,不能影响整个列表或其他后代元素。 - 给同一组超链接分别设置未访问、已访问、悬停、按下四种状态颜色;然后故意把
:active放到:hover前面,观察并记录差异,再恢复合理顺序。 - 比较以下两组选择器权重并说明判断到哪一步结束:
#book与.news li.item.active;.news li:hover与ul li。 - 修复一个列表案例:去掉
ul/ol默认 40px 左内边距造成的异常缩进,同时保留可读的项目符号与行距;验收:列表左对齐符合页面容器,不出现双重缩进。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 交集选择器 | 07:44 |
| 2 | 并集选择器 | 02:17 |
| 3 | 伪类选择器 | 15:17 |
| 4 | 伪类选择器书写顺序 | 12:03 |
| 5 | 选择器权重 | 17:20 |
小结
- 交集选择器靠“紧挨”表达同时满足,标签名参与时位置不能随意。
- 伪类用于状态选择,限制具体元素时通常要与其他选择器做交集。
- 超链接四伪类的书写顺序主要影响用户体验,不是语法硬性要求。
- 组合选择器权重比较应逐级看 ID、类+伪类、标签名数量,不要按十进制换算。
- 并集选择器要拆开分别计算权重,不能把逗号两侧合并比较。
- 列表默认样式会干扰布局,作业中应显式处理
padding-left、list-style等。 - 调试工具可强制元素进入
:hover、:active状态,便于定位伪类规则是否命中。