面试可用:深入浅出CSS选择器

50 阅读7分钟

前言

想象一下,你是一个设计师,面前有一面巨大的、布满各种装饰品的墙(HTML文档)。如果你想只把左上角第二个架子上的红色花瓶变成蓝色,你会怎么做?你肯定不会把整面墙都刷蓝。这时,你需要一个精准的“指令”来找到那个特定的花瓶。CSS选择器就是这个“指令”。它定义了CSS规则将应用于哪些HTML元素。掌握选择器,就意味着你获得了精准控制页面样式的“超能力”。


一、 CSS选择器基础篇:初识门径

让我们从最简单的选择器开始,它们是构建复杂样式规则的积木。

1. 通用选择器(*)

通配符选择器,匹配页面中的每一个元素。

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box; /* 常用重置样式 */
}

应用场景:用于简单的CSS重置(Reset),清除所有元素的默认内外边距。但需谨慎使用,因为它会影响所有元素,可能带来性能开销。

2. 元素选择器(标签选择器)

根据HTML标签名称来选择元素。

p {
  color: #333;
  line-height: 1.6;
}

h1 {
  font-size: 2em;
  margin-bottom: 0.5em;
}

3. 类选择器(.class)

根据元素的 class属性来选择元素。这是最常用、最灵活的选择器之一。

<p class="warning">这是一条警告信息!</p>
.warning {
  color: red;
  font-weight: bold;
  background-color: #ffe6e6;
  padding: 10px;
  border-left: 4px solid red;
}

特点:一个元素可以有多个类,一个类也可以被多个元素使用,复用性极高。

4. ID选择器(#id)

根据元素的 id属性来选择元素。ID在文档中应该是唯一的。

<header id="main-header">网站主标题</header>
#main-header {
  background-color: #4CAF50;
  color: white;
  text-align: center;
  padding: 1rem;
}

注意:ID选择器的优先级非常高,过度使用会导致样式难以覆盖,应谨慎使用,通常用于唯一性的布局块。

5. 属性选择器([attr])

根据元素的属性及属性值来选择元素。

/* 选择有title属性的元素 */
[title] {
  border-bottom: 1px dotted #ccc;
}

/* 选择type属性为"text"的input元素 */
input[type="text"] {
  border: 1px solid #999;
}

/* 选择class属性中包含"logo"的元素(部分匹配) */
[class*="logo"] {
  font-weight: bold;
}

常用匹配模式

  • [attr]:存在该属性。
  • [attr=value]:属性值完全等于value。
  • [attr^=value]:属性值以value开头
  • [attr$=value]:属性值以value结尾
  • [attr*=value]:属性值包含value。

二、 CSS选择器进阶篇:组合的艺术

单个选择器能力有限,组合使用才能发挥巨大威力。

1. 后代选择器(空格)

选择指定元素内部的所有后代元素(子、孙、重孙...)。

article p {
  text-indent: 2em; /* 只缩进article里面的p标签 */
}

2. 子元素选择器(>)

只选择作为某元素直接子元素的元素(仅一代)。

ul > li {
  list-style-type: square; /* 只作用于ul的直接子li,不影响嵌套ul里的li */
}

3. 相邻兄弟选择器(+)

选择紧接在另一元素后的第一个兄弟元素。

h2 + p {
  margin-top: 0; /* 紧跟在h2后面的第一个p标签 */
}

4. 通用兄弟选择器(~)

选择某元素之后的所有指定兄弟元素。

h2 ~ p {
  color: #666; /* h2后面所有的p兄弟元素 */
}

三、 CSS选择器高级篇:伪类与伪元素

这是CSS选择器最强大和有趣的部分,它们允许我们基于文档树之外的信息(如状态)来选择元素,或者创建一些不在DOM中的元素。

1. 动态伪类

  • :link:未访问的链接。
  • :visited:已访问的链接。
  • :hover:鼠标悬停时的状态。
  • :active:被激活(如鼠标点击)时的状态。
  • :focus:获得焦点时的状态(如表单输入框)。

定义顺序建议(LoVe/HAte法则) : :link-> :visited-> :hover-> :active

a:link { color: blue; }
a:visited { color: purple; }
a:hover { color: red; text-decoration: none; }
a:active { color: yellow; }
button:focus {
  outline: 2px solid orange;
}

2. 结构伪类

根据元素在DOM树中的位置来选择。

  • E:first-child:匹配父元素中的第一个子元素 E。
  • E:last-child:匹配父元素中的最后一个子元素 E。
  • E:nth-child(n):匹配父元素中的第 n 个子元素 E。

注意:匹配到的元素,必须是元素E,设置的样式才会生效

/* 表格斑马纹效果 */
tr:nth-child(even) { /* even: 偶数行 */
  background-color: #f2f2f2;
}
tr:nth-child(odd) {  /* odd: 奇数行 */
  background-color: #fff;
}

/* 选择前三个li */
li:nth-child(-n+3) {
  font-weight: bold;
}

/* 除了最后一个以外的所有li */
li:not(:last-child) {
  margin-bottom: 10px;
}

更推荐的方式:

  • E:first-of-type: 指定类型 E 的第一个
  • E:last-of-type: 指定类型 E 的最后一个
  • E:nth-of-type(n): 指定类型 E 的第 n 个

这种匹配方式指定的是E父元素下的第n个E元素,无需计算其他元素

3. 伪元素(::)

用于创建一些不在文档树中的元素,并为其添加样式。

  • ::before:在元素内容之前插入内容。
  • ::after:在元素内容之后插入内容。
  • ::first-letter:选择块级元素的首字母。
  • ::first-line:选择块级元素的首行。
blockquote::before {
  content: "“";
  font-size: 3em;
  color: #ccc;
}
blockquote::after {
  content: "”";
  font-size: 3em;
  color: #ccc;
}

p::first-letter {
  font-size: 2em;
  float: left;
  margin-right: 5px;
}

注意content属性对于 ::before和 ::after必须的,即使设置为空字符串 content: ""


四、 实战演练:一个优雅列表的实现

让我们用上面学到的知识,创建一个漂亮的待办事项列表。

<ul class="todo-list">
  <li class="completed">学习HTML基础</li>
  <li class="important">掌握CSS选择器</li>
  <li>探索JavaScript奥秘</li>
  <li>喝一杯水</li>
</ul>
.todo-list {
  list-style: none;
  padding: 0;
  width: 300px;
}
.todo-list li {
  padding: 12px 15px;
  margin-bottom: 8px;
  background-color: #f9f9f9;
  border-left: 4px solid #ddd;
  border-radius: 4px;
  transition: all 0.3s ease;
}
.todo-list li:hover {
  background-color: #edf7ff;
  transform: translateX(5px);
}
.todo-list li.completed {
  color: #999;
  text-decoration: line-through;
  border-left-color: #4CAF50;
}
.todo-list li.important {
  font-weight: bold;
  border-left-color: #FF9800;
}
.todo-list li:last-child {
  margin-bottom: 0;
}
.todo-list li::before {
  content: "☐ ";
  margin-right: 8px;
}
.todo-list li.completed::before {
  content: "☑ ";
}

效果预览:你会得到一个带有悬停效果、完成状态、重要标识的优雅列表。

image.png


五、 选择器优先级

优先级计算(权重)

当多条规则作用于同一元素时,CSS通过一套优先级规则决定最终样式。规则!important内联样式​ > ID选择器​ > 类/属性/伪类选择器​ > 元素/伪元素选择器​ > 通用选择器可以近似用 (a, b, c)的分数来比较:

  • !important声明:最高优先级
  • 行内样式(style属性):权重1000
  • ID选择器:权重100
  • 类选择器/属性选择器/伪类:权重10
  • 元素选择器/伪元素:权重1

比较时,从左到右逐位比较。例如:

  • #header(1,0,0) > .nav li.active(0,2,1)
  • div#main .content(1,1,1) > #main p(1,0,1)

建议:尽量避免使用 !important和过多的ID选择器,保持选择器简洁,利于维护。


总结

选择器类型示例核心作用
基础选择器p.class#id精准定位单个或一类元素
组合选择器div > ph2 + p表达元素间的层级与关系
伪类:hover:nth-child()基于状态或位置进行动态选择
伪元素::before::first-letter创建或装饰不在DOM中的内容

CSS选择器是CSS语言的精髓所在。从简单地改变颜色,到创建复杂的交互效果和布局,都离不开它。希望这篇指南能成为你CSS学习之路上的得力助手!


你觉得最难理解或最实用的CSS选择器是哪一个?在评论区分享你的想法吧! 欢迎点赞⭐收藏 ➕关注!你的支持是我持续创作的最大动力!