伪类选择器
概述
伪类选择器(Pseudo-class Selectors)用于选择处于特定状态的元素,例如:hover、:focus、:active 等。伪类以冒号 : 开头。
语法
选择器:伪类 {
属性: 值;
}常用伪类分类
1. 链接伪类
:link - 未访问的链接
a:link {
color: blue;
}:visited - 已访问的链接
a:visited {
color: purple;
}:hover - 鼠标悬停
a:hover {
color: red;
text-decoration: underline;
}:active - 激活状态(点击时)
a:active {
color: orange;
}注意事项: 链接伪类必须按照以下顺序声明(LVHA 原则):
a:link { /* L */ }
a:visited { /* V */ }
a:hover { /* H */ }
a:active { /* A */ }2. 用户交互伪类
:focus - 获得焦点
input:focus {
border-color: #3498db;
outline: none;
box-shadow: 0 0 5px rgba(52, 152, 219, 0.5);
}:focus-within - 子元素获得焦点
.form-group:focus-within {
border-color: #3498db;
}:focus-visible - 有焦点指示器时
button:focus-visible {
outline: 2px solid #3498db;
}3. 表单伪类
:checked - 选中的复选框/单选框
input[type="checkbox"]:checked + label {
color: #3498db;
font-weight: bold;
}:disabled - 禁用的表单元素
input:disabled {
background-color: #f5f5f5;
color: #999;
cursor: not-allowed;
}:enabled - 启用的表单元素
input:enabled {
background-color: #fff;
}:required - 必填字段
input:required {
border-color: #e74c3c;
}:optional - 可选字段
input:optional {
border-color: #95a5a6;
}:valid - 验证通过
input:valid {
border-color: #27ae60;
}:invalid - 验证失败
input:invalid {
border-color: #e74c3c;
}
input:invalid::after {
content: "✗";
color: #e74c3c;
}:in-range - 在范围内
input[type="number"]:in-range {
border-color: #27ae60;
}:out-of-range - 超出范围
input[type="number"]:out-of-range {
border-color: #e74c3c;
}:read-only - 只读
input:read-only {
background-color: #f5f5f5;
cursor: not-allowed;
}:read-write - 可读写
input:read-write {
background-color: #fff;
}4. 结构伪类
:first-child - 第一个子元素
li:first-child {
color: red;
}:last-child - 最后一个子元素
li:last-child {
color: blue;
}:nth-child(n) - 第 n 个子元素
/* 第2个子元素 */
li:nth-child(2) {
background-color: yellow;
}
/* 奇数位置的子元素 */
li:nth-child(odd) {
background-color: #f9f9f9;
}
/* 偶数位置的子元素 */
li:nth-child(even) {
background-color: #f0f0f0;
}
/* 每第3个元素 */
li:nth-child(3n) {
background-color: #eee;
}
/* 3的倍数 + 1 */
li:nth-child(3n+1) {
color: red;
}
/* 前3个元素 */
li:nth-child(-n+3) {
color: blue;
}
/* 从第4个开始 */
li:nth-child(n+4) {
color: green;
}:nth-last-child(n) - 倒数第 n 个子元素
/* 倒数第2个元素 */
li:nth-last-child(2) {
background-color: yellow;
}:first-of-type - 同类型的第一个子元素
p:first-of-type {
font-weight: bold;
}:last-of-type - 同类型的最后一个子元素
p:last-of-type {
color: blue;
}:nth-of-type(n) - 同类型的第 n 个子元素
/* 第2个p元素 */
p:nth-of-type(2) {
color: red;
}
/* 奇数位置的p元素 */
p:nth-of-type(odd) {
background-color: #f9f9f9;
}:nth-last-of-type(n) - 同类型的倒数第 n 个子元素
/* 倒数第2个p元素 */
p:nth-last-of-type(2) {
color: red;
}:only-child - 唯一的子元素
li:only-child {
background-color: yellow;
}:only-of-type - 唯一同类型子元素
p:only-of-type {
font-weight: bold;
}5. 目标伪类
:target - 当前锚点目标
#section1:target {
background-color: #fff3cd;
border-left: 4px solid #ffc107;
}<a href="#section1">跳转到第一节</a>
<div id="section1">第一节内容</div>6. 否定伪类
:not(selector) - 不匹配选择器
/* 选择不是禁用的输入框 */
input:not(:disabled) {
background-color: #fff;
}
/* 选择第一个之外的列表项 */
li:not(:first-child) {
margin-top: 10px;
}
/* 选择不是第一和最后一个的元素 */
li:not(:first-child):not(:last-child) {
padding: 0 20px;
}7. 语言伪类
:lang(language) - 特定语言
p:lang(zh) {
font-family: "Microsoft YaHei", sans-serif;
}
p:lang(en) {
font-family: Arial, sans-serif;
}<p lang="zh">中文内容</p>
<p lang="en">English content</p>8. UI 状态伪类
:default - 默认选项
input[type="radio"]:default + label {
font-weight: bold;
}:indeterminate - 不确定状态
input[type="checkbox"]:indeterminate {
opacity: 0.5;
}9. 空状态伪类
:empty - 空元素
.box:empty {
display: none;
}
.box:empty::after {
content: "暂无内容";
color: #999;
}权重计算
伪类选择器的权重为 10:
a:hover {
/* 权重 = 1(a) + 10(:hover) = 11 */
color: red;
}
.box:nth-child(2) {
/* 权重 = 10(.box) + 10(:nth-child) = 20 */
background-color: blue;
}
input:focus:invalid {
/* 权重 = 1(input) + 10(:focus) + 10(:invalid) = 21 */
border-color: red;
}常见应用场景
1. 交互效果
/* 按钮悬停效果 */
.button:hover {
background-color: #3498db;
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
/* 按钮点击效果 */
.button:active {
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}2. 表单验证
/* 验证成功 */
input:valid {
border-color: #27ae60;
}
input:valid::after {
content: "✓";
color: #27ae60;
}
/* 验证失败 */
input:invalid:not(:placeholder-shown) {
border-color: #e74c3c;
}
input:invalid:not(:placeholder-shown)::after {
content: "✗";
color: #e74c3c;
}
/* 必填字段 */
input:required::before {
content: "*";
color: #e74c3c;
}3. 列表样式
/* 斑马纹效果 */
tr:nth-child(even) {
background-color: #f9f9f9;
}
/* 第一行和最后一行特殊样式 */
tr:first-child {
background-color: #f0f0f0;
font-weight: bold;
}
tr:last-child {
border-bottom: 2px solid #333;
}4. 卡片布局
/* 卡片悬停效果 */
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
/* 第一个卡片 */
.card:first-child {
margin-top: 0;
}
/* 最后一个卡片 */
.card:last-child {
margin-bottom: 0;
}5. 图片效果
/* 图片悬停放大 */
img:hover {
transform: scale(1.1);
transition: transform 0.3s ease;
}
/* 图片聚焦 */
img:focus {
outline: 3px solid #3498db;
}6. 自定义复选框
/* 隐藏原生复选框 */
input[type="checkbox"] {
display: none;
}
/* 自定义样式 */
input[type="checkbox"] + label {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid #ccc;
border-radius: 4px;
cursor: pointer;
}
/* 选中状态 */
input[type="checkbox"]:checked + label {
background-color: #3498db;
border-color: #3498db;
}
input[type="checkbox"]:checked + label::after {
content: "✓";
color: white;
display: block;
text-align: center;
line-height: 20px;
}7. 标签页切换
/* 标签项 */
.tab-item {
padding: 10px 20px;
background: #f5f5f5;
cursor: pointer;
}
/* 激活状态 */
.tab-item:target {
background: #fff;
border-bottom: 2px solid #3498db;
color: #3498db;
}8. 图片画廊
/* 图片容器 */
.gallery-item {
position: relative;
overflow: hidden;
}
/* 悬停显示遮罩 */
.gallery-item:hover::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.5);
opacity: 0;
transition: opacity 0.3s ease;
}
.gallery-item:hover::before {
opacity: 1;
}实战案例
案例1: 选项卡组件
/* 选项卡按钮 */
.tab-btn {
padding: 10px 20px;
background: #f5f5f5;
border: none;
cursor: pointer;
transition: all 0.3s ease;
}
.tab-btn:hover {
background: #e0e0e0;
}
.tab-btn:active {
background: #d0d0d0;
}
.tab-btn:focus {
outline: 2px solid #3498db;
}案例2: 表单样式
/* 表单组 */
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.form-group input {
width: 100%;
padding: 10px;
border: 2px solid #ddd;
border-radius: 4px;
transition: border-color 0.3s ease;
}
/* 焦点状态 */
.form-group input:focus {
border-color: #3498db;
outline: none;
box-shadow: 0 0 5px rgba(52, 152, 219, 0.3);
}
/* 验证状态 */
.form-group input:valid {
border-color: #27ae60;
}
.form-group input:invalid:not(:placeholder-shown) {
border-color: #e74c3c;
}
/* 禁用状态 */
.form-group input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}案例3: 产品列表
/* 产品卡片 */
.product-card {
padding: 20px;
background: #fff;
border-radius: 10px;
transition: all 0.3s ease;
}
.product-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}
.product-card:active {
transform: translateY(-2px);
}
/* 产品标题 */
.product-card h3 {
font-size: 18px;
margin-bottom: 10px;
}
/* 产品描述 */
.product-card p {
color: #666;
line-height: 1.6;
margin-bottom: 15px;
}
/* 按钮样式 */
.product-card .btn {
display: inline-block;
padding: 8px 20px;
background: #3498db;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s ease;
}
.product-card .btn:hover {
background: #2980b9;
}
.product-card .btn:focus {
outline: 2px solid #2980b9;
}案例4: 新闻列表
/* 新闻项 */
.news-item {
padding: 20px;
border-bottom: 1px solid #eee;
transition: background 0.3s ease;
}
.news-item:hover {
background: #f9f9f9;
}
/* 第一个新闻项 */
.news-item:first-child {
border-top: 1px solid #eee;
}
/* 最后一个新闻项 */
.news-item:last-child {
border-bottom: none;
}
/* 新闻标题 */
.news-item h3 {
font-size: 20px;
margin-bottom: 10px;
}
.news-item h3 a {
color: #333;
transition: color 0.3s ease;
}
.news-item h3 a:hover {
color: #3498db;
}
.news-item h3 a:active {
color: #2980b9;
}注意事项
- 链接伪类顺序: 必须按 LVHA 顺序声明
- 权重相同: 伪类权重都是 10,与类选择器相同
- 兼容性: 部分新伪类在旧浏览器中不支持
- 性能: 复杂的伪类选择器可能影响性能
- 可读性: 过度使用伪类会降低代码可读性
最佳实践
- 合理使用: 只在需要时使用伪类
- 性能优化: 避免过度复杂的伪类选择器
- 渐进增强: 提供回退方案
- 代码注释: 复杂伪类添加注释
- 测试兼容性: 浏览器兼容性测试
- 组合使用: 与其他选择器配合使用
- 交互反馈: 提供良好的用户反馈
- 可访问性: 考虑键盘导航和屏幕阅读器
总结
伪类选择器是 CSS 中非常强大的功能,能够根据元素的不同状态应用样式。掌握各种伪类的使用方法,可以帮助我们创建更丰富、更交互的网页效果。在实际开发中,要合理使用伪类,确保代码的可维护性和性能。