CSS 伪类与伪元素
伪类和伪元素是特殊的选择器,它们不选择 HTML 中实际存在的元素,而是选择元素的特定状态或文档中的虚拟部分。
伪类(Pseudo-classes)
伪类用单冒号 : 开头,表示元素的状态。它们随着用户交互或文档结构变化而动态生效。
用户交互伪类
最常用的一类伪类,响应鼠标、键盘等用户操作:
css
/* 鼠标悬停 */
a:hover {
color: #2563eb;
text-decoration: underline;
}
/* 获得焦点(Tab 导航或点击) */
input:focus {
outline: 2px solid #2563eb;
outline-offset: 2px;
}
/* 鼠标按下时 */
button:active {
transform: scale(0.97);
} 链接状态建议按 LVHA 顺序书写——:link → :visited → :hover → :active。:focus 不属于 LVHA 序列,可与 :hover 并列写在任意位置。常见组合是 :hover, :focus { ... }。
链接状态伪类
css
/* 未访问的链接 */
a:link {
color: #2563eb;
}
/* 已访问的链接 */
a:visited {
color: #7c3aed;
} 表单状态伪类
css
/* 选中的复选框/单选框 */
input:checked + label {
color: #2563eb;
font-weight: 500;
}
/* 禁用的表单控件 */
input:disabled {
background: #f1f5f9;
color: #94a3b8;
cursor: not-allowed;
}
/* 输入无效内容时 */
input:invalid {
border-color: #ef4444;
}
/* 可选(非必填)的输入框 */
input:optional {
border-style: dashed;
}
/* 必填字段 */
input:required {
border-left: 3px solid #2563eb;
} html
<form>
<label><input type="checkbox" checked> <span>已选中的复选框</span></label><br>
<label><input type="checkbox"> <span>未选中的复选框</span></label><br>
<input type="text" disabled value="禁用状态"><br>
<input type="text" required placeholder="必填字段"><br>
<input type="email" placeholder="输入邮箱(:optional)">
</form> 结构伪类
根据元素在文档树中的位置选择:
| 伪类 | 选中条件 |
|---|---|
:first-child | 父元素的第一个子元素 |
:last-child | 父元素的最后一个子元素 |
:nth-child(n) | 父元素的第 n 个子元素 |
:nth-child(odd) | 奇数位子元素 |
:nth-child(even) | 偶数位子元素 |
:only-child | 父元素的唯一子元素 |
:first-of-type | 同类型中的第一个 |
:last-of-type | 同类型中的最后一个 |
:nth-of-type(n) | 同类型中的第 n 个 |
css
/* 列表的偶数行加背景色(斑马条纹) */
tr:nth-child(even) {
background: #f8fafc;
}
/* 第一个段落加粗 */
p:first-child {
font-weight: 500;
}
/* 只有一张图片时占满宽度 */
img:only-child {
width: 100%;
}
/* 末尾元素去掉下边距 */
li:last-child {
margin-bottom: 0;
} :nth-child(n) 详解
n 从 0 开始计数,可以用公式表达:
css
/* 第 3 个 */
:nth-child(3)
/* 所有奇数:1, 3, 5, ... */
:nth-child(odd)
/* 所有偶数:2, 4, 6, ... */
:nth-child(even)
/* 每 3 个选 1 个:3, 6, 9, ... */
:nth-child(3n)
/* 从第 2 个开始每 3 个:2, 5, 8, ... */
:nth-child(3n+2)
/* 前 3 个:1, 2, 3 */
:nth-child(-n+3) 伪元素(Pseudo-elements)
伪元素用双冒号 :: 开头,创建文档中不存在的虚拟元素。
早期 CSS 中伪元素也用单冒号(如 :before),现代浏览器对两者都兼容。推荐使用双冒号以与伪类区分。
::before 和 ::after
最常用的两个伪元素,在元素内容之前/之后插入虚拟内容。必须配合 content 属性使用:
css
/* 在引用文字前后加引号 */
blockquote::before {
content: "「";
}
blockquote::after {
content: "」";
}
/* 给外部链接加图标 */
a[href^="https"]::after {
content: " ↗";
font-size: 0.8em;
opacity: 0.5;
}
/* 装饰性分割线 */
.section-divider::before {
content: "";
display: block;
width: 60px;
height: 3px;
background: #2563eb;
margin-bottom: 2rem;
} content 可以是文字、空字符串(用于纯装饰)、或 attr() 读取属性值:
css
/* 在链接后显示 URL */
a[href^="http"]::after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #94a3b8;
} html
<p>访问 <a href="https://coodocs.com">Coodocs</a> 了解更多。</p> 其他伪元素
| 伪元素 | 选中部分 |
|---|---|
::first-line | 文本的第一行 |
::first-letter | 文本的第一个字母 |
::selection | 用户选中的文本 |
::placeholder | input/textarea 的占位文字 |
::marker | 列表项的标记符号(圆点、数字等) |
css
/* 首字下沉 */
p.intro::first-letter {
font-size: 3rem;
font-weight: 700;
float: left;
margin-right: 0.25rem;
line-height: 1;
}
/* 选中文本的颜色 */
::selection {
background: #2563eb;
color: white;
}
/* 输入框占位文字样式 */
input::placeholder {
color: #94a3b8;
font-style: italic;
}
/* 列表标记颜色 */
li::marker {
color: #2563eb;
} 一个元素只能有一个 ::before 和一个 ::after。它们的 display 默认为 inline,需要设置 display: block 或 display: inline-block 才能使用宽高。