学习目标
- 掌握CSS3属性选择器的语法及使用场景
- 理解并应用常见伪类选择器(如
:nth-child()
、:not()
等) - 能够结合属性选择器与伪类实现复杂选择逻辑
概念讲解
CSS3选择器是样式定位的核心工具,属性选择器和伪类选择器极大扩展了选择能力。属性选择器允许通过HTML元素的属性或属性值筛选元素,而伪类选择器则针对元素的特定状态或位置进行选择,两者结合可实现精准的样式控制。
属性选择器的价值
传统类选择器依赖固定class命名,而属性选择器可直接基于元素固有的属性(如type
、href
)或自定义属性(如data-*
)进行选择,减少冗余class,提升代码语义化。
伪类的分类
- 状态伪类:基于元素状态(如
:hover
、:active
、:focus
) - 结构伪类:基于DOM树位置(如
:nth-child()
、:first-child
) - 否定伪类:排除特定元素(
:not(selector)
)
语法参考
属性选择器语法
选择器格式 | 描述 | 示例 |
---|---|---|
[attr] |
选择所有包含attr 属性的元素 |
input[required] 选择必填输入框 |
[attr=value] |
选择attr 属性值完全等于value 的元素 |
input[type="email"] 选择邮箱输入框 |
[attr^=value] |
选择attr 属性值以value 开头的元素 |
a[href^="https"] 选择HTTPS链接 |
[attr$=value] |
选择attr 属性值以value 结尾的元素 |
img[src$=".png"] 选择PNG图片 |
[attr*=value] |
选择attr 属性值包含value 子串的元素 |
div[class*="card"] 选择含"card"类的div |
[attr~=value] |
选择attr 属性值包含value 单词的元素(空格分隔) |
p[class~="intro"] 选择class含"intro"单词的p元素 |
常用伪类语法
伪类选择器 | 描述 | 示例 |
---|---|---|
:nth-child(n) |
选择父元素的第n个子元素(n从1开始) | ul li:nth-child(2) 选择列表中第2个li |
:nth-child(even) |
选择偶数位置子元素 | tr:nth-child(even) 选择表格偶数行 |
:nth-child(2n+1) |
选择奇数位置子元素 | div:nth-child(2n+1) 选择奇数div |
:first-child |
选择父元素的第一个子元素 | p:first-child 选择第一个p元素 |
:last-child |
选择父元素的最后一个子元素 | li:last-child 选择列表最后一个li |
:not(selector) |
排除匹配selector 的元素 |
input:not([type="submit"]) 排除提交按钮 |
:focus |
选择获得焦点的元素 | input:focus 选择聚焦的输入框 |
:hover |
选择鼠标悬停的元素 | a:hover 鼠标悬停的链接 |
实战示例
示例1:属性选择器应用(表单美化)
<!-- HTML结构 -->
<form class="register-form">
<input type="text" name="username" placeholder="用户名" required>
<input type="email" name="email" placeholder="邮箱" required>
<input type="password" name="password" placeholder="密码" required>
<input type="text" name="phone" placeholder="手机号" data-tip="请输入11位手机号">
<button type="submit">注册</button>
</form>
<style>
/* 属性选择器美化表单 */
/* 1. 所有必填输入框添加红色边框提示 */
.register-form input[required] {
border-left: 3px solid #ff4d4f;
}
/* 2. 邮箱输入框添加图标前缀(结合伪元素) */
.register-form input[type="email"] {
padding-left: 30px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='%23999' viewBox='0 0 16 16'%3E%3Cpath d='M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: 8px center;
}
/* 3. 自定义属性data-tip添加提示文本 */
.register-form input[data-tip] {
position: relative;
}
.register-form input[data-tip]:hover::after {
content: attr(data-tip);
position: absolute;
top: -30px;
left: 0;
background: #333;
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
}
</style>
示例2:伪类选择器应用(列表隔行变色与悬停效果)
<!-- HTML结构 -->
<ul class="news-list">
<li>HTML5语义化标签最佳实践</li>
<li>CSS3 Flexbox布局完全指南</li>
<li>响应式设计断点设置技巧</li>
<li>CSS动画性能优化策略</li>
<li>Grid布局与Flexbox对比分析</li>
</ul>
<style>
/* 伪类选择器应用 */
.news-list {
list-style: none;
padding: 0;
margin: 0;
}
.news-list li {
padding: 12px 16px;
border-bottom: 1px solid #eee;
transition: background 0.3s ease;
}
/* 1. 隔行变色(奇数行) */
.news-list li:nth-child(odd) {
background-color: #f9f9f9;
}
/* 2. 鼠标悬停效果 */
.news-list li:hover {
background-color: #f0f7ff;
transform: translateX(4px);
}
/* 3. 排除最后一个元素的下边框 */
.news-list li:last-child {
border-bottom: none;
}
/* 4. 选择第一个和第三个元素添加特殊标记 */
.news-list li:first-child::before,
.news-list li:nth-child(3)::before {
content: "🔔 ";
color: #faad14;
}
</style>
注意事项
1. 属性选择器的性能考量
- 避免过度复杂的属性选择器:如
[class*="item-"]
会遍历所有元素的class属性,大型页面可能影响性能,优先使用类选择器 - 优先匹配具体属性值:
[type="text"]
比[type^="t"]
性能更好,因为后者需要前缀匹配
2. 伪类的浏览器兼容性
:nth-child()
的参数兼容性:IE9及以下不支持nth-child(n)
的表达式(如2n+1
),可使用:first-child
、:last-child
等基础伪类替代:not()
的限制:IE9及以下不支持:not()
伪类,复杂否定逻辑需通过JavaScript实现
3. 选择器优先级规则
- 属性选择器与类选择器优先级相同(权重10),如
[class="active"]
与.active
优先级一致,后定义的样式会覆盖先定义的 - 伪类选择器权重与类选择器相同(权重10),如
:hover
与.hover
优先级一致
4. 常见错误案例
- ❌ 错误:使用
[class=active]
匹配class为"active item"的元素(应使用[class~=active]
或.active
) - ❌ 错误:
nth-child(0)
(n从1开始,0无意义) - ❌ 错误:
:nth-child(2)
与:nth-of-type(2)
混淆(前者考虑所有子元素,后者仅考虑同类型元素)
自测题
如何选择所有
type
属性为"password"且包含required
属性的输入框?/* 答案 */ input[type="password"][required]
请写出选择ul中第2个li元素,且该li不是最后一个子元素的选择器。
/* 答案 */ ul li:nth-child(2):not(:last-child)
如何使用属性选择器选择所有
data-status
属性值为"completed"或"processing"的div元素?/* 答案 */ div[data-status="completed"], div[data-status="processing"]
评论