第三章:精准定位:从基础到高级选择器
第三章:精准定位:从基础到高级选择器
Prorise第三章:精准定位:从基础到高级选择器
摘要: 本章将是 CSS 选择器的完全指南。我们将从回顾基础选择器开始,深入学习如何通过组合、属性、状态和结构来构建强大的选择器,实现对任何元素的精准定位。本章的重点是伪类和伪元素,它们是实现交互效果和高级 UI 设计的关键。最后,我们将通过一个实战案例,将所学知识融会贯通。
在本章中,我们将解锁 CSS 的“精确制导”能力:
- 首先,我们将快速 回顾基础与组合选择器,巩固已有知识。
- 接着,我们将学习 属性选择器,根据元素的“身份证”信息来定位它。
- 然后,我们将深入本章的第一个核心——伪类选择器,让页面能够响应用户的交互和状态。
- 之后,我们将掌握第二个核心——伪元素选择器,学会在不改变 HTML 的情况下创建和装饰虚拟元素。
- 最后,我们将进入 实战环节,综合运用所学知识,构建一个带分隔线的导航菜单效果。
3.1. 基础与组合选择器回顾
上一章我们对核心选择器有了一定认识,现在来快速回顾。
基础选择器:
- 标签选择器:如
p
,能选中页面中所有<p>
标签元素,方便统一设置某类标签样式。 - 类选择器:像
.container
,可选中所有 class 属性值为“container”的元素,在日常样式设置中使用频率高,能对不同标签应用相同样式。 - ID 选择器:
#main
,用于选中唯一 ID 为“main”的元素,一个页面中 ID 应唯一,常配合 JavaScript 操作特定元素。 - 通配符选择器:
*
,会选中页面所有元素,不过使用时要谨慎,以免影响性能。
组合选择器:
- 后代选择器:
nav a
,能选中<nav>
元素内部所有<a>
元素,不管嵌套多深,方便对特定容器内元素设置样式。 - 子元素选择器:
ul > li
,仅选中<ul>
元素的直接子元素<li>
,不会选中更深层级的<li>
,精准控制直接子元素。 - 相邻兄弟选择器:
h1 + p
,选中紧跟在<h1>
元素后的第一个<p>
元素,当需要为特定元素后的紧邻元素设置样式时很有用。 - 通用兄弟选择器:
h1 ~ p
,选中在<h1>
元素之后的所有<p>
元素,只要在源文档顺序上在<h1>
之后即可,不要求紧邻 。
3.2. 属性选择器:根据标签属性定位
属性选择器允许我们根据 HTML 元素的属性(如 href
, target
, type
)及其值来应用样式,这在处理表单或特定链接时非常有用,如果这里您学过正则表达式,那么理解起来会十分轻松,我们只需要记住 ^
代表开头,$
代表全选,*
代表包含即可
写法 | 说明 | 示例 |
---|---|---|
[attr] | 选中拥有 attr 属性的元素 | a[title] |
[attr=val] | 选中 attr 属性值 完全等于 val 的元素 | a[target=_blank] |
[attr^=val] | 选中 attr 属性值以 val 开头 的元素 | a[href^="https"] |
[attr$=val] | 选中 attr 属性值以 val 结尾 的元素 | a[href$=".pdf"] |
[attr*=val] | 选中 attr 属性值 包含 val 的元素 | a[href*="google"] |
痛点背景: 你希望为网站上所有指向外部网站的链接(在新窗口打开)和所有指向 PDF 文件的链接自动添加一个特殊的小图标,以提示用户。
解决方案: 我们可以完美地利用属性选择器来实现这个需求,而无需手动为这些链接添加特定的类。
1 | <style> |
3.3. 伪类选择器:响应用户交互与状态
伪类是 CSS 的一大特色,它允许我们为元素的某些 特殊状态(如鼠标悬停、链接被访问)或 特殊位置(如第一个子元素)应用样式。伪类以单个冒号 :
开头。
3.3.1. 动态与链接伪类
这些伪类与用户的行为和浏览历史相关,是实现 UI 交互效果的基础。
伪类 | 描述 |
---|---|
:hover | (最常用) 鼠标指针悬停在元素上时。 |
:active | 元素被用户激活时(如鼠标按下未松开)。 |
:focus | 元素获得焦点时(如通过 Tab 键选中的输入框)。 |
:link | 特指 <a> 标签,匹配未被访问过的链接。 |
:visited | 特指 <a> 标签,匹配已被访问过的链接。 |
LVHA 顺序: 在为链接定义样式时,建议遵循 :link
-> :visited
-> :hover
-> :active
的书写顺序。这是一个经典的记忆法则 “LoVe HAte”,可以确保 :hover
和 :active
的效果不会被 :link
或 :visited
覆盖掉。
1 | <style> |
3.3.2. 结构性伪类
这类伪类根据元素在 DOM 树中的位置或结构关系来选择元素,非常强大。
伪类 | 描述 |
---|---|
:first-child | 匹配作为其父元素的 第一个 子元素的元素。 |
:last-child | 匹配作为其父元素的 最后一个 子元素的元素。 |
:nth-child(n) | 匹配作为其父元素的 第 n 个 子元素的元素。 |
:nth-of-type(n) | 匹配作为其父元素的 第 n 个同类型 的元素。 |
:not(selector) | 匹配不符合 selector 的所有元素。 |
n
可以是数字、关键字 (odd(奇数)
, even(偶数)
) 或公式 (3n+1
)。
1 |
|
li:nth-child(2)
和 li:nth-of-type(2)
有什么区别?它们看起来很像。
这是一个非常关键的区别!
li:nth-child(2)
的意思是:“找到一个元素,它必须是其父元素的 第 2 个 孩子,并且它自己 恰好 还是一个 <li>
元素”。如果第 2 个孩子是 <div>
,那么这个选择器就什么也选不中。
而 li:nth-of-type(2)
的意思是:“在其父元素的所有 <li>
孩子中,找到 第 2 个 <li>
”。它会忽略其他类型的兄弟元素。
简单说,nth-child
是“先定位,再看类型”,而 nth-of-type
是“先按类型分组,再定位”。在有混合类型兄弟元素的场景下,nth-of-type
通常更可靠。
示例: 实现一个“斑马条纹”表格,并为第一行和最后一行添加特殊样式。
1 | <style> |
3.4. 伪元素选择器:创建虚拟元素
伪元素与伪类不同,它不是为已有元素添加特殊状态,而是 创建出一个在 DOM 树中不存在的虚拟元素,并为其添加样式。伪元素在现代 CSS 中以双冒号 ::
开头,以区别于伪类。
伪元素 | 描述 |
---|---|
::before | 在选中元素内容的 前面 插入一个虚拟元素。 |
::after | 在选中元素内容的 后面 插入一个虚拟元素。 |
::first-letter(少用) | 选中块级元素内容的第一个字母。 |
::first-line(少用) | 选中块级元素内容的第一行。 |
::selection(少用) | 匹配用户鼠标选中的文本部分。 |
::placeholder(少用) | 匹配输入框的占位提示文本。 |
关键规则: ::before
和 ::after
创建的虚拟元素默认是 行内元素。它们必须包含 content
属性(即使是 content: '';
)才能生效。
示例: 使用 ::before
和 ::after
为引用文本添加装饰性的引号,并自定义选中文本的样式。
1 | <style> |
3.5. 实战应用:构建一个带分隔线的导航菜单 (修正版)
目标: 创建一个如下图所示的,干净、稳定、带分隔线的水平导航菜单。
动手思路
- HTML 结构: 使用
<ul>
和<li>
构建导航的语义化骨架。 - 水平布局: 为
<li>
设置display: inline-block;
实现水平排列,并移除<ul>
的默认列表样式。 - 交互样式: 为
<li>
添加:hover
伪类以改变背景色,并为<a>
设置padding
和基础样式。 - 添加分隔线: 为每个
<li>
添加border-right
来创建分隔线,这比使用伪元素更稳定。 - 移除末尾分隔线: 使用
:last-child
伪类,选中最后一个<li>
,并将其border-right
移除。
Html 结构如下:
1 | <nav class="main-nav"> |
3.6. 本章核心速查总结
分类 | 关键项 | 核心描述 |
---|---|---|
属性选择器 | [attr^=val] , [attr$=val] | 根据属性值的 开头 或 结尾 进行匹配,常用于链接样式。 |
动态伪类 | :hover , :focus , :active | 实现 UI 交互效果的三剑客。 |
结构性伪类 | :nth-child(n) | 先找第 n 个孩子,再判断类型是否匹配。 |
p:nth-of-type(n) | (推荐) 先按 p 类型分组,再找该类型的第 n 个。 | |
:not(selector) | 排除特定元素,非常实用。 | |
伪元素 | ::before , ::after | (核心) 创建虚拟的行内元素,必须包含 content 属性。 |
::selection | 自定义用户用鼠标选中文本时的背景和颜色。 | |
::placeholder | 自定义输入框占位文本的样式。 |