学习目标

  • 掌握CSS3属性选择器的语法及使用场景
  • 理解并应用常见伪类选择器(如:nth-child():not()等)
  • 能够结合属性选择器与伪类实现复杂选择逻辑

概念讲解

CSS3选择器是样式定位的核心工具,属性选择器伪类选择器极大扩展了选择能力。属性选择器允许通过HTML元素的属性或属性值筛选元素,而伪类选择器则针对元素的特定状态或位置进行选择,两者结合可实现精准的样式控制。

属性选择器的价值

传统类选择器依赖固定class命名,而属性选择器可直接基于元素固有的属性(如typehref)或自定义属性(如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)混淆(前者考虑所有子元素,后者仅考虑同类型元素)

自测题

  1. 如何选择所有type属性为"password"且包含required属性的输入框?

    /* 答案 */
    input[type="password"][required]
    
  2. 请写出选择ul中第2个li元素,且该li不是最后一个子元素的选择器。

    /* 答案 */
    ul li:nth-child(2):not(:last-child)
    
  3. 如何使用属性选择器选择所有data-status属性值为"completed"或"processing"的div元素?

    /* 答案 */
    div[data-status="completed"],
    div[data-status="processing"]