在前面的学习中,我们介绍了如何使用基础选择器,根据元素类型或属性来为页面设置样式。这些选择器在针对具体标签或属性定制样式时非常实用。但如果我们想根据元素在文档中的结构、状态或用户交互来实现更加灵活的样式,仅靠基础选择器就无法满足需求。
比如,你可能希望为表格的偶数行设置不同的背景色,让表单中被禁用的输入框表现出灰色状态,或者为必填项添加明显的视觉标识。这类需求,单靠普通选择器很难实现。此时,CSS的伪类和伪元素选择器就为我们提供了专业、强大的解决方案,让样式设计变得更加高效、自然且易于维护。

你可以把伪类选择器想象成“自动加上的标签”。这些标签不是我们在HTML里自己写的,而是浏览器根据元素当前的状态、在页面中的位置或者结构,自动帮我们贴上的。这样,CSS就能通过这些“标签”快速找到我们想要设置样式的元素了,就像浏览器帮你做了一次智能筛选。
伪类选择器总是只针对它所绑定的那个元素起作用,不会影响到其他元素。有些伪类听起来像是在选子元素,其实只是给当前元素加标签,别搞混了哟!
CSS中的伪类选择器可以大致分为几个主要类别,每个类别都有其特定的用途和应用场景:
除了伪类选择器,CSS还提供了伪元素选择器。如果说伪类选择器是为元素添加虚拟的类名,那么伪元素选择器就是为文档插入虚拟的元素。这些虚拟元素在HTML中并不存在,但浏览器会为它们创建样式,就像它们真的存在一样。
伪元素选择器使用双冒号(::)语法,比如::first-letter用于选择元素的第一个字母,::before用于在元素前插入内容。这些选择器让我们能够实现一些仅靠HTML无法实现的视觉效果。
在接下来的学习中,我们将详细探索这些强大的选择器,学习如何运用它们来创建更加精美和交互性更强的网页界面。
结构伪类选择器是CSS中最实用的一类选择器,它们能够根据元素在文档结构中的位置来选择元素。这些选择器特别适合处理有规律排列的内容,比如导航菜单、文章列表、数据表格等。
:root伪类选择器选择文档的根元素。在HTML文档中,根元素就是<html>元素。虽然我们可以直接选择html元素,但使用:root更加通用,因为它适用于任何XML语言。
让我们看一个简单的例子,为整个页面的根元素添加边框:
|<!DOCTYPE html> <html> <head> <style> :root { border: 5px solid #007bff; } </style> </head> <body> <p>:root选择器选择了文档的根元素(html元素)。</p> </
:empty伪类选择器选择没有任何子元素的元素,包括文本节点。这个选择器在内容管理系统(CMS)中特别有用,可以隐藏那些没有填充内容的空元素。
想象一个博客系统,有时候会生成空的段落标签,我们可以用:empty来隐藏它们:
|<!DOCTYPE html> <html> <head> <style> p:empty { display: none; } p { border: 1px solid #ddd; padding: 8px; margin: 5
:empty选择器只匹配真正空的元素,包含空格或文本的元素不会被匹配。
:only-child伪类选择器选择那些作为父元素唯一子元素的元素。这个选择器在创建特殊布局时非常有用。
假设我们有一个图片画廊,当某个图片是容器中的唯一元素时,我们希望给它添加特殊的边框效果:
|<!DOCTYPE html> <html> <head> <style> .gallery { display: flex; gap: 10px; margin: 10px; } .gallery img:only-child { border: 3px
:only-child选择器选择作为父元素唯一子元素的元素。
:first-child和:last-child伪类选择器分别选择父元素的第一个和最后一个子元素。这些选择器在创建导航菜单、文章列表等界面时非常常用。
让我们创建一个文章列表,为第一篇文章添加特殊样式,为最后一篇文章添加结束样式:
|<!DOCTYPE html> <html> <head> <style> .list div:first-child { background-color: #e3f2fd; } .list div:last-child { border-bottom: 2px solid #007bff; } .list div {
:first-child选择父元素的第一个子元素,:last-child选择最后一个子元素。
:nth-child() 伪类选择器是结构化样式中极为强大且灵活的工具。它使我们能够基于子元素在父容器中的具体顺序,有针对性地选中特定位置的元素。不像 :first-child 和 :last-child 只能选第一个或最后一个,:nth-child() 可以选中任何序号的子元素,甚至可以批量选择规则性序列(例如每隔两个、三个)。
这个选择器的参数非常灵活,可以是具体数字(如 3)、关键词(如 odd 表示奇数位,even 表示偶数位),也可以是带有运算规则的表达式(如 2n+1 选中所有奇数序号的元素,即第1、3、5...个)。
通俗来说,:nth-child() 就像给每个兄弟元素排了座位号,然后你可以用公式、自定义规则来选定一个或一批“编号”的孩子,非常适合高亮列表、表格的特定行,或做斑马条纹等批量化样式处理。
下面我们通过一个具体的列表例子来展示展示 :nth-child() 的不同用法:
|<!DOCTYPE html> <html> <head> <style> li:nth-child(odd) { background-color: #f8f9fa; } li:nth-child(3n) { color: #007bff; } ul { list-style:
:nth-child(odd)选择奇数位置的元素,:nth-child(3n)选择每3个元素。
使用:nth-child()时要注意,元素计数从1开始,不是从0开始。这与我们编程中的数组索引是不同的。
:nth-of-type()和:nth-last-of-type()伪类选择器与:nth-child()类似,但它们只计算相同类型的元素。这在处理混合内容时特别有用。
假设我们有一个包含标题和段落的文章,我们想要为每第二个段落添加特殊样式:
|<!DOCTYPE html> <html> <head> <style> p:nth-of-type(even) { background-color: #e3f2fd; } h2 { margin-top: 15px; } p { padding: 8px
:nth-of-type(even) 伪类选择器只会把属于同一个类型(比如都是 <p> 标签)的兄弟元素编号,并选择所有序号是偶数位(第2、4、6...)的那个类型的元素。其他类型的元素(比如 <h2>)在编号时会被自动跳过,不影响计数。
所以只要是父级下的偶数“同类元素”,都会被这个选择器选中,而不会管中间是否有其他类型的标签。
位置伪类选择器(也叫“链接伪类选择器”)是CSS中专门用于根据元素在文档中的特殊位置、状态(尤其是链接状态)来精准选取元素的高级工具。它们最常见的用途是为不同状态的链接(如未访问、已访问、鼠标悬停、激活等)或用于定位特殊元素(如第一个匹配项)赋予专属样式,从而提升网页的交互体验和可用性。
对于链接元素(<a>标签),浏览器会根据用户的操作和访问历史为其自动添加“状态标签”。这些状态包括:
利用这些伪类选择器,前端开发者可以非常灵活地针对链接的不同交互情况,设置醒目的视觉反馈。比如高亮当前页面、给已访问链接变色、鼠标移上去淡入淡出,等等。 比如,我们想做一个网页导航条,让未访问的链接显示为蓝色、访问过的显示为灰色、鼠标悬停显示为深蓝色。我们通过一个简单的导航菜单演示如何为不同状态的链接赋予不同的样式效果:
|<!DOCTYPE html> <html> <head> <style> a:link { color: #007bff; } a:visited { color: #666; } a:hover { color: #0056b3; }
:link选择未访问的链接,:visited选择已访问的链接,:hover选择鼠标悬停的链接。
链接状态伪类的顺序很重要。建议按照 link、visited、hover、active 的顺序来定义,这样可以确保样式正确应用。
:target 伪类选择器是 CSS 中一个非常实用且常见的结构伪类。它用于选中页面上当前与 URL 片段(也叫 hash,比如#section1)匹配的元素。当页面的地址栏带有某个锚点(如 #about),就会自动选中对应 id="about" 的元素,此时它会匹配 :target 伪类,从而触发你为它设置的样式。
通俗地讲,当你点击页面里的锚点链接时(如 <a href="#目标">),页面会滚动到对应的元素,并且该元素会自动拥有 “目标” 状态。这时你就可以用 :target 给当前被定位的元素添加高亮、动画等特殊视觉效果,让用户更容易集中注意力。
例如可以为它加背景色、加边框,让用户知道“我现在看到的,就是你刚刚点击要到达的部分”。
|<!DOCTYPE html> <html> <head> <style> h2:target { background-color: #fff3cd; border-left: 4px solid #ffc107; } a { color: #007bff; text-decoration: none;
:target选择器选择当前URL片段标识符匹配的元素。
用户交互伪类选择器,顾名思义,就是专门用来让网页元素根据“用户的操作”产生变化的选择器。它们能让网页变得“有生命”,对你的鼠标、键盘甚至是手机手指的操作做出立刻的视觉反应。你在网页上看见按钮变色、输入框高亮、菜单弹出等等,其实大多数都离不开这些伪类。
常见的用户交互伪类选择器有::hover、:active、:focus 等。这里我们先来仔细讲讲:hover和:active。
:hover 表示“悬停状态”,当你的鼠标指针放在一个元素上时,这个元素就会自动加上 :hover 伪类。常用于让按钮、链接等在鼠标移上去时产生高亮、变色的效果。例如网页上的按钮,鼠标没碰时是灰色,移上去马上变蓝,这就是:hover的功劳。:active 表示“激活状态”,也就是当你点击(鼠标左键按下但还没松开)或在手机上按住某个元素时,这个元素会临时变成:active。一般用于设计按下瞬间显示不同效果,让点击的手感更真实。让我们通过下面的案例来感受下:有两个按钮,鼠标移上去时按钮会变成蓝色,点击按住时颜色会再变深,感受一下这两个伪类的区别。
|<!DOCTYPE html> <html> <head> <style> button:hover { background-color: #007bff; color: white; } button:active { background-color: #0056b3; } button { padding
:hover在鼠标悬停时触发,:active在点击时触发。
:focus 伪类选择器会在元素“获得焦点”时触发。所谓“获得焦点”,就是你用鼠标点击一个输入框,或者用键盘(比如按 Tab)切换到输入框上时,这个输入框就进入了可以编辑、响应键盘输入的状态。这时候浏览器会自动帮你“上色”或者显示轮廓,方便你知道自己正在操作哪个元素。
这个特性不仅提升了用户体验,还对无障碍非常重要——比如视障用户依赖键盘操作页面时,能通过焦点样式判断当前输入位置。
另外还有个:focus-visible伪类,可以让你只在用户用键盘(而不是鼠标)切换焦点时显示特殊样式,这样不会让鼠标点击时不必要的装饰干扰界面。
下面我们用一个简单的例子来演示,输入框获得焦点时边框颜色会变蓝:
|<!DOCTYPE html> <html> <head> <style> input:focus { border-color: #007bff; outline: none; } input { padding: 8px; border: 2px solid #ddd
:focus选择器在元素获得键盘焦点时触发。
:focus-within 伪类选择器的作用是:只要某个元素自己或它里面的任意子元素获得了焦点(比如点击输入框、用 Tab 键切换到内部按钮等),它就会被选中,触发相应的样式。
举个通俗的例子:你可以把容器(如 <div>)想象成一个盒子,里面装了很多输入框。当我们在“盒子”里的任何一个输入框上点一下,这整个“盒子”就会被高亮,视觉上提示用户:“你现在正在操作这个区域”,而不仅仅是单独的输入框有变化。
这样做的好处是:只需要写一行 CSS,就能让整个表单分组在有焦点时改变背景色、高亮边框等,非常适合做表单分区高亮、复杂交互表单的焦点提示。
下面我们通过一个例子演示这种效果:当表单中的任意输入框获得焦点时,整个位于 .form 类的容器都会高亮显示。
|<!DOCTYPE html> <html> <head> <style> .form:focus-within { background-color: #e3f2fd; } .form { padding: 15px; border: 1px solid #ddd; margin: 10px
:focus-within在元素本身或其子元素获得焦点时触发。
UI状态伪类选择器是专门用来根据表单元素或者一些UI部件当前“状态”来选中它们的CSS选择器。简单来说,就是让你可以用CSS很方便地找到“正在用的”、“不能用的”、“选中的”、“必填的”等各种状态的控件,然后针对性地给它们加样式,让用户体验更友好。

比如下面这些场景,UI状态伪类选择器就非常有用:
这些选择器常见的有:enabled(启用)、:disabled(禁用)、:checked(已选中)、:required(必填)、:invalid(无效)等等。
先来看:enabled 和 :disabled。:enabled表示“可以正常操作”的表单元素,比如大部分输入框、按钮;:disabled表示“不能操作”的表单元素,就是你在页面上看到置灰、点不动的那些输入框或按钮。
对于用户来说,禁用(disabled)的元素一般显示为浅灰色,不能点也不能输入内容,而启用(enabled)的输入框则可以正常用、可以输入内容、点击按钮有响应。
我们来做个简单的例子:有两个输入框,一个是默认可以用的,另一个我们加上 disabled 属性让它变成禁用状态,通过伪类选择器分别对他们添加不同的样式,把“可用”和“不可用”这两种状态很直观地表现出来。
|<!DOCTYPE html> <html> <head> <style> input:enabled { background-color: white; border-color: #007bff; } input:disabled { background-color: #f8f9fa; border-color: #dee2e6; color
:enabled选择启用的表单元素,:disabled选择禁用的表单元素。
:checked 伪类选择器用来选中所有“已经被选中”的复选框或单选按钮。你可以理解为:当用户点选复选框或单选按钮后,浏览器自动帮它贴上:checked这个“被选中”的标签。这样我们就可以用 CSS 给这些已经被勾选的表单控件加上特别的样式,比如改变勾选颜色、显示特殊外观等。
通俗点说,你在网页上看到那些被打勾(✓)或者被选中的小圆点,都是通过:checked来识别和美化的。它专门用于 <input type="checkbox"> 和 <input type="radio"> 这些元素。
比如下面的例子,我们做了两个复选框,通过:checked让被选中的那一项显示蓝色勾选效果:
|<!DOCTYPE html> <html> <head> <style> input[type="checkbox"]:checked { accent-color: #007bff; } label { margin-left: 5px; } div { margin
:checked选择器选择被选中的复选框和单选按钮。
逻辑伪类选择器为现代 CSS 开发引入了强大的条件筛选能力,使开发者可以更加灵活、精准地选中或排除某些元素。利用这些伪类,可以根据各种逻辑条件自定义选择规则,提高样式定义的表达力和可维护性,在实际项目中非常重要,特别是在实现复杂样式需求时。
:not() 否定伪类选择器可以选中所有不符合特定条件的元素。通俗来说,它就像在选择器后面加了一个“除了……以外”的限定,让你可以很方便地排除某些元素,而不用单独指定它们。例如,如果你想让某种类型的元素都应用某种样式,但某几个特殊元素要例外,就可以用 :not() 来实现。
假设我们有一个项目列表,但有些列表项需要特别高亮显示(如加上 .special 类名的项目)。我们希望所有“不是特殊项目”的项目显示为蓝色,“特殊项目”显示为红色且加粗。这时就可以用 :not(.special) 来选中所有“非特殊项目”。
|<!DOCTYPE html> <html> <head> <style> li:not(.special) { color: #007bff; } .special { color: #ff6b6b; font-weight: bold; } ul {
:not()选择器选择不匹配指定条件的元素。
伪元素选择器(Pseudo-elements)是 CSS 选择器体系中的一种高级工具,它们与伪类选择器不同,并不是用来选中已经存在于 HTML 文档结构中的真实元素,而是用于创建并选中那些“虚拟”的元素片段,让开发者能够对元素内部的特定部分(如首字母、首行、内容前后等)进行精细的样式控制。
这些虚拟元素在 HTML 代码里看不到,但浏览器会根据 CSS 渲染出相应的效果。常见伪元素选择器语法为 ::xxx(如::before、::after),但部分浏览器也支持单冒号写法(如:before),不过推荐使用双冒号以和伪类:hover等区别。
::first-letter 伪元素用于选中一个块级元素(通常是段落 <p>、标题 <h1> 等)第一行的第一个字母,经常用于新闻、杂志网站等首字母放大设计(“首字下沉”)。::first-line 则选中元素的首行所有文本,而“首行”会根据容器宽度和具体字体渲染自动计算,不一定等同于 HTML 里的单行。这些伪元素帮助实现高级、优雅的排版效果,比如首字母大写、首行加粗、变色等。下面我们看个简单的例子,给段落的首字母添加特殊的装饰效果:
|<!DOCTYPE html> <html> <head> <style> p::first-letter { font-size: 2em; font-weight: bold; color: #007bff; } p { margin: 15px;
::first-letter选择器选择元素的第一个字母,::first-line选择第一行文本。
通过本部分的学习,你已经掌握了CSS伪类和伪元素选择器的功能。伪类选择器可以让我们根据元素的不同状态、位置和结构进行精准选中,比如结构相关的:first-child、:nth-child(),还有交互相关的:hover、:focus,以及更灵活的:not()、:has()等。
而伪元素选择器则能帮助我们添加虚拟元素,让页面更加丰富多彩,比如::first-letter、::before、::after等都为设计带来了更多的可能。
|<ul> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ul>
请写出CSS选择器来选择第一个列表项,并给它添加红色背景色。
|li:first-child { background-color: red; }
|<table> <tr><td>第1行</td></tr> <tr><td>第2行</td></tr> <tr><td>第3行</td></tr> <tr><td>第4行</td></tr> </table>
请写出CSS选择器来选择偶数位置的表格行,并给它们添加浅灰色背景。
|tr:nth-child(even) { background-color: #f8f9fa; }
|<div> <p>有内容的段落</p> <p></p> <p>另一个有内容的段落</p> <p> </p> </div>
请写出CSS选择器来隐藏所有空的段落(没有任何内容的段落)。
|p:empty { display: none; }
|<div> <a href="#home">首页</a> <a href="#about">关于</a> <a href="#contact">联系我们</a> </div>
请写出CSS选择器来选择所有未访问的链接,并给它们添加蓝色颜色。
|a:link { color: blue; }
|<div> <button>按钮1</button> <button>按钮2</button> </div>
请写出CSS选择器来选择鼠标悬停在按钮上时的状态,并给它们添加绿色背景色。
|button:hover { background-color: green; }
|<div> <input type="text" placeholder="启用的输入框"> <input type="text" placeholder="禁用的输入框" disabled> </div>
请写出CSS选择器来选择禁用的输入框,并给它们添加灰色背景色。
|input:disabled { background-color: #f8f9fa; }
|<div> <input type="checkbox" id="option1" checked> <label for="option1">选项1</label> <input type="checkbox" id="option2"> <label for="option2">选项2</label> </div>
请写出CSS选择器来选择被选中的复选框,并改变它们的颜色为蓝色。
|input[type="checkbox"]:checked { accent-color: blue; }
|<ul> <li>普通项目</li> <li class="special">特殊项目</li> <li>普通项目</li> <li>普通项目</li> </ul>
请写出CSS选择器来选择所有不是特殊类的列表项,并给它们添加蓝色文字颜色。
|li:not(.special) { color: blue; }
|<p>这是一个段落</p> <p>这是另一个段落</p>
请写出CSS选择器来选择每个段落的第一个字母,并让它变成红色和加粗。
|p::first-letter { color: red; font-weight: bold; }
|<div> <input type="text" placeholder="用户名"> <input type="password" placeholder="密码"> </div>
请写出CSS选择器来选择获得键盘焦点的输入框,并给它们添加蓝色边框。
|input:focus { border-color: blue; outline: none; }