第06篇伪类详解状态与结构伪类是 CSS 选择器中最灵活、最强大的一类。它们让你能够根据元素的状态如鼠标悬停、获得焦点或结构位置如第一个子元素、奇数行来选择元素而无需修改 HTML。掌握伪类意味着你可以用更少的代码实现更丰富的交互效果。学习目标掌握链接伪类:link、:visited、:hover、:active及其使用顺序掌握用户交互伪类:hover、:focus、:focus-visible、:active、:disabled掌握表单状态伪类:checked、:indeterminate、:required、:valid、:invalid掌握结构伪类:first-child、:last-child、:nth-child()、:nth-of-type()等掌握现代伪类:is()、:where()、:not()、:has()理解伪类的权重计算规则核心知识点一、什么是伪类伪类Pseudo-class用于选中处于特定状态或具有特定结构位置的元素。/* 选中鼠标悬停时的按钮 */.btn:hover{background:#357abd;}/* 选中列表中的第一个子元素 */li:first-child{border-top:none;}/* 选中获得焦点的输入框 */input:focus{border-color:#4a90d9;}语法特征以冒号:开头紧跟伪类名称如:hover、:nth-child(2n1)。与伪元素的区别伪类伪元素:单冒号::双冒号CSS3 规范选中已有元素的特定状态在元素前后创建虚拟内容:hover、:nth-child()::before、::after二、链接伪类Link Pseudo-classes专门用于a标签的四个伪类被称为“LoVe HAte”规则/* L - :link - 未访问过的链接 */a:link{color:#4a90d9;}/* V - :visited - 已访问过的链接 */a:visited{color:#764ba2;}/* H - :hover - 鼠标悬停时 */a:hover{color:#e74c3c;text-decoration:underline;}/* A - :active - 鼠标按下瞬间 */a:active{color:#c0392b;}顺序很重要必须按:link→:visited→:hover→:active的顺序书写否则后面的规则会覆盖前面的。记忆口诀LoVe HAte爱恨/* ✅ 正确顺序 */a:link{color:blue;}a:visited{color:purple;}a:hover{color:red;}a:active{color:orange;}/* ❌ 错误顺序hover 在 link 前面link 会覆盖 hover */a:hover{color:red;}/* 先定义 */a:link{color:blue;}/* 后定义权重相同会覆盖 hover */简化写法现代浏览器中直接写a和a:hover通常就够了/* 简洁实用的链接样式 */a{color:#4a90d9;text-decoration:none;transition:color 0.2s;}a:hover{color:#e74c3c;text-decoration:underline;}a:visited{color:#764ba2;/* 可选区分已访问链接 */}三、用户交互伪类User Action Pseudo-classes:hover— 鼠标悬停/* 基础用法 */.btn:hover{background:#357abd;}/* 悬停时显示子元素下拉菜单 */.dropdown:hover .dropdown-menu{display:block;}/* 悬停时放大图片 */.card:hover img{transform:scale(1.05);}/* 悬停时添加阴影 */.card:hover{box-shadow:0 8px 24pxrgba(0,0,0,0.15);}注意:hover在触摸屏设备上没有悬停概念通常表现为点击时的瞬间状态。不要依赖:hover展示关键内容。:focus— 获得焦点当元素通过鼠标点击或键盘 Tab 键获得焦点时触发。/* 输入框获得焦点时的样式 */input:focus, textarea:focus, select:focus{outline:none;/* 移除浏览器默认轮廓 */border-color:#4a90d9;box-shadow:0 0 0 3pxrgba(74,144,217,0.2);}/* 按钮获得焦点时的样式 */button:focus{outline:2px solid #4a90d9;outline-offset:2px;}:focus-visible— 仅在键盘聚焦时显示现代浏览器支持/* 键盘 Tab 切换时显示轮廓鼠标点击时不显示 */button:focus-visible{outline:2px solid #4a90d9;outline-offset:2px;}优势解决了一个长期困扰——鼠标点击按钮时出现 ugly 的 outline但键盘导航时又需要 outline。:active— 激活状态元素被鼠标按下但尚未释放的瞬间或键盘 Enter/Space 按下时。/* 按钮按下时的反馈 */.btn:active{transform:translateY(1px);box-shadow:inset 0 2px 4pxrgba(0,0,0,0.1);}:disabled— 禁用状态/* 禁用状态的输入框和按钮 */input:disabled, button:disabled{background:#f0f0f0;color:#999;cursor:not-allowed;opacity:0.6;}四、表单状态伪类Form State Pseudo-classesformclassdemo-forminputtypetextrequiredplaceholder必填项inputtypeemailplaceholder邮箱inputtypecheckboxcheckedinputtyperadionamegenderbuttontypesubmit提交/button/form/* :checked - 选中的复选框/单选框 */input[typecheckbox]:checked label{color:#2ecc71;font-weight:bold;}/* :required - 必填字段 */input:required{border-left:3px solid #e74c3c;}/* :optional - 可选字段非必填 */input:optional{border-left:3px solid #2ecc71;}/* :valid - 输入合法时 */input:valid{border-color:#2ecc71;}/* :invalid - 输入不合法时 */input:invalid{border-color:#e74c3c;}/* :placeholder-shown - 占位符显示时未输入内容 */input:placeholder-shown{border-style:dashed;}/* :indeterminate - 不确定状态如复选框的半选状态 */input[typecheckbox]:indeterminate{background:#ffc107;}表单验证样式实战/* 优雅的表单验证反馈 */.form-field{margin-bottom:16px;}.form-field input{width:100%;padding:10px 14px;border:2px solid #ddd;border-radius:6px;transition:all 0.3s;}/* 未填写且获得焦点时 */.form-field input:focus:placeholder-shown{border-color:#ffc107;}/* 填写且合法 */.form-field input:valid{border-color:#2ecc71;}/* 填写且不合法 */.form-field input:focus:invalid{border-color:#e74c3c;}五、结构伪类Structural Pseudo-classes结构伪类根据元素在 DOM 树中的位置来选择无需添加类名。基础结构伪类/* :first-child - 第一个子元素 */li:first-child{border-top:none;}/* :last-child - 最后一个子元素 */li:last-child{border-bottom:none;}/* :only-child - 唯一的子元素 */.sidebar-widget:only-child{margin:0;}/* :empty - 没有子元素包括文本的元素 */.error-message:empty{display:none;/* 空错误提示自动隐藏 */}:nth-child()— 最强大的结构伪类/* :nth-child(n) - 第 n 个子元素 */li:nth-child(3){background:#e3f2fd;/* 第三个 li 高亮 */}/* :nth-child(2n) 或 :nth-child(even) - 偶数项 */li:nth-child(even){background:#f5f5f5;}/* :nth-child(2n1) 或 :nth-child(odd) - 奇数项 */li:nth-child(odd){background:#ffffff;}/* :nth-child(3n) - 每第 3 个 */.gallery-item:nth-child(3n){margin-right:0;}/* :nth-child(-n3) - 前 3 个 */.top-list li:nth-child(-n3){font-weight:bold;color:#e74c3c;}/* :nth-child(n4) - 从第 4 个开始的所有 */.list li:nth-child(n4){color:#999;}/* :nth-last-child(2) - 倒数第 2 个 */li:nth-last-child(2){border-bottom:2px solid #ffc107;}:nth-child()公式速查表公式含义选中项nth-child(3)第 3 个3nth-child(even)/2n偶数2, 4, 6, 8…nth-child(odd)/2n1奇数1, 3, 5, 7…nth-child(3n)每第 3 个3, 6, 9, 12…nth-child(3n1)从 1 开始每第 3 个1, 4, 7, 10…nth-child(-n3)前 3 个1, 2, 3nth-child(n4)从第 4 个开始4, 5, 6, 7…nth-child(n3):nth-child(-n5)第 3 到第 5 个3, 4, 5:nth-of-type()— 按类型计数:nth-child()计数时不区分元素类型:nth-of-type()只统计同类型的兄弟元素。articleh2标题 1/h2p段落 1/pp段落 2/ph2标题 2/h2p段落 3/p/article/* ❌ 这样写不会选中 段落 2因为 h2 占了第 1 个位置 */article p:nth-child(2){color:red;}/* 实际上选中了 段落 1因为它是 article 的第 2 个子元素 *//* ✅ 用 :nth-of-type() 只数 p 元素 */article p:nth-of-type(2){color:red;/* 正确选中 段落 2 */}/* 给每个 h2 后面的第一个 p 加样式 */article h2 p{font-size:1.1em;}:nth-child()vs:nth-of-type()对比/* 场景表格的斑马纹 */tr:nth-child(even){}/* 偶数行包括 thead/tr */tr:nth-of-type(even){}/* 同类型中的偶数行 *//* 场景只给段落设置斑马纹 */article p:nth-of-type(odd){}/* ✅ 正确 */article p:nth-child(odd){}/* ❌ 可能被其他元素打乱 */六、现代伪类Modern Pseudo-classes:not()— 否定伪类选中不匹配选择器的元素。/* 选中所有非 disabled 的按钮 */button:not(:disabled){cursor:pointer;}/* 选中所有不含 .active 类的 li */li:not(.active){opacity:0.7;}/* 选中不是第一个也不是最后一个的 li */li:not(:first-child):not(:last-child){margin:8px 0;}/* CSS4 支持传入选择器列表现代浏览器 */li:not(:first-child, :last-child){margin:8px 0;}注意:not()不能嵌套伪元素且内部的复杂选择器在现代浏览器才支持。:is()— 匹配列表中的任意一个简化复杂的选择器群组。/* ❌ 冗长的写法 */h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover{color:#e74c3c;}/* ✅ 用 :is() 简化 */:is(h1, h2, h3, h4) a:hover{color:#e74c3c;}/* 减少重复 */article :is(h1, h2, h3){color:#1a1a2e;line-height:1.3;}/* 相当于 article h1, article h2, article h3 { color: #1a1a2e; line-height: 1.3; } */:is()与:where()的区别:is():where()权重取参数中最高的权重权重永远为0用途简化选择器并保持权重简化选择器且不增加权重/* :is() 的权重 .class (10) */:is(h1, .title, #header){}/* 权重 0-1-0 10 *//* :where() 的权重 0 */:where(h1, .title, #header){}/* 权重 0-0-0 0 */:has()— 父选择器现代浏览器支持选中包含特定子元素的父元素——这是 CSS 长期以来的重大突破/* 选中包含 img 的 figure 元素 */figure:has(img){border:1px solid #ddd;padding:10px;}/* 选中包含 figcaption 的 figure */figure:has(figcaption){background:#f8f9fa;}/* 选中后面紧跟 ul 的 li二级菜单项 */li:has( ul){position:relative;}/* 选中后面紧跟 ul 的 li 的 a有下拉菜单的导航项 */li:has( ul) a::after{content: ▼;font-size:0.8em;}/* 表单验证选中包含非法输入的字段容器 */.form-field:has(input:invalid) .error-msg{display:block;}七、伪类的优先级权重伪类如:hover、:nth-child()的权重等同于类选择器即10。/* 权重计算 */.btn:hover{}/* 10 10 20 */li:first-child{}/* 1 10 11 */input:focus:invalid{}/* 1 10 10 21 */:is(#header, .nav){}/* 取最高 100ID 的权重 */:where(#header){}/* 权重 0 */动手练习练习 1导航栏悬停效果实现一个导航栏要求普通链接为灰色鼠标悬停时变为蓝色并出现下划线动画下划线从中间向两侧展开当前页面链接.active为蓝色且始终显示下划线已访问过的链接为紫色但不超过 10% 的透明度区别练习 2斑马纹表格给定以下 HTML用:nth-child实现斑马纹效果tableclassdata-tabletheadtrth姓名/thth年龄/thth城市/th/tr/theadtbodytrtd张三/tdtd25/tdtd北京/td/trtrtd李四/tdtd30/tdtd上海/td/tr!-- 更多行... --/tbody/tabletbody 中的行奇偶不同背景色鼠标悬停时行高亮第一列的文字加粗练习 3:has()实战用:has()实现以下效果如果浏览器不支持用其他方式回退包含图片的.card有更大的上内边距.form-group中有input:invalid时对应的label变红色选中后面紧跟.details的.summary并添加箭头图标常见误区 ⚠️误区真相“:hover在手机上也能用”触摸屏没有悬停概念:hover在手机上表现不一致不要依赖它展示关键内容“:focus和:focus-visible是一回事”:focus-visible只在键盘聚焦时触发鼠标点击时不触发更适合现代交互“:nth-child(2n)和:nth-of-type(2n)效果一样”当父元素中有多种类型子元素时两者结果完全不同“:not()可以嵌套任何选择器”:not()内部传统上只能写一个简单选择器现代浏览器支持选择器列表“:is()和:where()完全一样”:is()取参数中最高权重:where()权重永远为 0“:visited可以设置任意样式”出于隐私保护浏览器限制:visited只能设置color、background-color、border-color、outline-color“:has()可以无限嵌套”:has()不能嵌套:has()且性能开销较大应谨慎使用“结构伪类会动态更新”当 DOM 变化时结构伪类会自动重新计算不需要刷新页面速查卡片 链接伪类顺序LoVe HAtea:link{}/* L - 未访问 */a:visited{}/* V - 已访问 */a:hover{}/* H - 悬停 */a:active{}/* A - 按下 */结构伪类速查伪类选中:first-child第一个子元素:last-child最后一个子元素:only-child唯一的子元素:nth-child(n)第 n 个子元素:nth-last-child(n)倒数第 n 个子元素:first-of-type同类型中的第一个:last-of-type同类型中的最后一个:nth-of-type(n)同类型中的第 n 个:empty无子元素含文本:nth-child()公式速查公式效果even/2n偶数项odd/2n1奇数项3n每第 3 个-n3前 3 个n4从第 4 个开始现代伪类伪类作用权重:is()匹配列表中任意一个取最高:where()匹配列表中任意一个0:not()排除匹配的元素取参数权重:has()包含特定子元素的父元素复杂扩展阅读MDN: 伪类MDN: :nth-child()MDN: :has() — 父选择器MDN: :is()CSS-Tricks: :nth-child() recipes英文Can I Use :has() — 查询浏览器支持配套代码CODE/06/pseudo-class-states.html — 状态伪类交互演示CODE/06/pseudo-class-structure.html — 结构伪类布局演示下一步进入 第07篇伪元素详解学习用::before和::after创建虚拟内容。
第06篇:伪类详解:状态与结构
发布时间:2026/6/14 5:47:06
第06篇伪类详解状态与结构伪类是 CSS 选择器中最灵活、最强大的一类。它们让你能够根据元素的状态如鼠标悬停、获得焦点或结构位置如第一个子元素、奇数行来选择元素而无需修改 HTML。掌握伪类意味着你可以用更少的代码实现更丰富的交互效果。学习目标掌握链接伪类:link、:visited、:hover、:active及其使用顺序掌握用户交互伪类:hover、:focus、:focus-visible、:active、:disabled掌握表单状态伪类:checked、:indeterminate、:required、:valid、:invalid掌握结构伪类:first-child、:last-child、:nth-child()、:nth-of-type()等掌握现代伪类:is()、:where()、:not()、:has()理解伪类的权重计算规则核心知识点一、什么是伪类伪类Pseudo-class用于选中处于特定状态或具有特定结构位置的元素。/* 选中鼠标悬停时的按钮 */.btn:hover{background:#357abd;}/* 选中列表中的第一个子元素 */li:first-child{border-top:none;}/* 选中获得焦点的输入框 */input:focus{border-color:#4a90d9;}语法特征以冒号:开头紧跟伪类名称如:hover、:nth-child(2n1)。与伪元素的区别伪类伪元素:单冒号::双冒号CSS3 规范选中已有元素的特定状态在元素前后创建虚拟内容:hover、:nth-child()::before、::after二、链接伪类Link Pseudo-classes专门用于a标签的四个伪类被称为“LoVe HAte”规则/* L - :link - 未访问过的链接 */a:link{color:#4a90d9;}/* V - :visited - 已访问过的链接 */a:visited{color:#764ba2;}/* H - :hover - 鼠标悬停时 */a:hover{color:#e74c3c;text-decoration:underline;}/* A - :active - 鼠标按下瞬间 */a:active{color:#c0392b;}顺序很重要必须按:link→:visited→:hover→:active的顺序书写否则后面的规则会覆盖前面的。记忆口诀LoVe HAte爱恨/* ✅ 正确顺序 */a:link{color:blue;}a:visited{color:purple;}a:hover{color:red;}a:active{color:orange;}/* ❌ 错误顺序hover 在 link 前面link 会覆盖 hover */a:hover{color:red;}/* 先定义 */a:link{color:blue;}/* 后定义权重相同会覆盖 hover */简化写法现代浏览器中直接写a和a:hover通常就够了/* 简洁实用的链接样式 */a{color:#4a90d9;text-decoration:none;transition:color 0.2s;}a:hover{color:#e74c3c;text-decoration:underline;}a:visited{color:#764ba2;/* 可选区分已访问链接 */}三、用户交互伪类User Action Pseudo-classes:hover— 鼠标悬停/* 基础用法 */.btn:hover{background:#357abd;}/* 悬停时显示子元素下拉菜单 */.dropdown:hover .dropdown-menu{display:block;}/* 悬停时放大图片 */.card:hover img{transform:scale(1.05);}/* 悬停时添加阴影 */.card:hover{box-shadow:0 8px 24pxrgba(0,0,0,0.15);}注意:hover在触摸屏设备上没有悬停概念通常表现为点击时的瞬间状态。不要依赖:hover展示关键内容。:focus— 获得焦点当元素通过鼠标点击或键盘 Tab 键获得焦点时触发。/* 输入框获得焦点时的样式 */input:focus, textarea:focus, select:focus{outline:none;/* 移除浏览器默认轮廓 */border-color:#4a90d9;box-shadow:0 0 0 3pxrgba(74,144,217,0.2);}/* 按钮获得焦点时的样式 */button:focus{outline:2px solid #4a90d9;outline-offset:2px;}:focus-visible— 仅在键盘聚焦时显示现代浏览器支持/* 键盘 Tab 切换时显示轮廓鼠标点击时不显示 */button:focus-visible{outline:2px solid #4a90d9;outline-offset:2px;}优势解决了一个长期困扰——鼠标点击按钮时出现 ugly 的 outline但键盘导航时又需要 outline。:active— 激活状态元素被鼠标按下但尚未释放的瞬间或键盘 Enter/Space 按下时。/* 按钮按下时的反馈 */.btn:active{transform:translateY(1px);box-shadow:inset 0 2px 4pxrgba(0,0,0,0.1);}:disabled— 禁用状态/* 禁用状态的输入框和按钮 */input:disabled, button:disabled{background:#f0f0f0;color:#999;cursor:not-allowed;opacity:0.6;}四、表单状态伪类Form State Pseudo-classesformclassdemo-forminputtypetextrequiredplaceholder必填项inputtypeemailplaceholder邮箱inputtypecheckboxcheckedinputtyperadionamegenderbuttontypesubmit提交/button/form/* :checked - 选中的复选框/单选框 */input[typecheckbox]:checked label{color:#2ecc71;font-weight:bold;}/* :required - 必填字段 */input:required{border-left:3px solid #e74c3c;}/* :optional - 可选字段非必填 */input:optional{border-left:3px solid #2ecc71;}/* :valid - 输入合法时 */input:valid{border-color:#2ecc71;}/* :invalid - 输入不合法时 */input:invalid{border-color:#e74c3c;}/* :placeholder-shown - 占位符显示时未输入内容 */input:placeholder-shown{border-style:dashed;}/* :indeterminate - 不确定状态如复选框的半选状态 */input[typecheckbox]:indeterminate{background:#ffc107;}表单验证样式实战/* 优雅的表单验证反馈 */.form-field{margin-bottom:16px;}.form-field input{width:100%;padding:10px 14px;border:2px solid #ddd;border-radius:6px;transition:all 0.3s;}/* 未填写且获得焦点时 */.form-field input:focus:placeholder-shown{border-color:#ffc107;}/* 填写且合法 */.form-field input:valid{border-color:#2ecc71;}/* 填写且不合法 */.form-field input:focus:invalid{border-color:#e74c3c;}五、结构伪类Structural Pseudo-classes结构伪类根据元素在 DOM 树中的位置来选择无需添加类名。基础结构伪类/* :first-child - 第一个子元素 */li:first-child{border-top:none;}/* :last-child - 最后一个子元素 */li:last-child{border-bottom:none;}/* :only-child - 唯一的子元素 */.sidebar-widget:only-child{margin:0;}/* :empty - 没有子元素包括文本的元素 */.error-message:empty{display:none;/* 空错误提示自动隐藏 */}:nth-child()— 最强大的结构伪类/* :nth-child(n) - 第 n 个子元素 */li:nth-child(3){background:#e3f2fd;/* 第三个 li 高亮 */}/* :nth-child(2n) 或 :nth-child(even) - 偶数项 */li:nth-child(even){background:#f5f5f5;}/* :nth-child(2n1) 或 :nth-child(odd) - 奇数项 */li:nth-child(odd){background:#ffffff;}/* :nth-child(3n) - 每第 3 个 */.gallery-item:nth-child(3n){margin-right:0;}/* :nth-child(-n3) - 前 3 个 */.top-list li:nth-child(-n3){font-weight:bold;color:#e74c3c;}/* :nth-child(n4) - 从第 4 个开始的所有 */.list li:nth-child(n4){color:#999;}/* :nth-last-child(2) - 倒数第 2 个 */li:nth-last-child(2){border-bottom:2px solid #ffc107;}:nth-child()公式速查表公式含义选中项nth-child(3)第 3 个3nth-child(even)/2n偶数2, 4, 6, 8…nth-child(odd)/2n1奇数1, 3, 5, 7…nth-child(3n)每第 3 个3, 6, 9, 12…nth-child(3n1)从 1 开始每第 3 个1, 4, 7, 10…nth-child(-n3)前 3 个1, 2, 3nth-child(n4)从第 4 个开始4, 5, 6, 7…nth-child(n3):nth-child(-n5)第 3 到第 5 个3, 4, 5:nth-of-type()— 按类型计数:nth-child()计数时不区分元素类型:nth-of-type()只统计同类型的兄弟元素。articleh2标题 1/h2p段落 1/pp段落 2/ph2标题 2/h2p段落 3/p/article/* ❌ 这样写不会选中 段落 2因为 h2 占了第 1 个位置 */article p:nth-child(2){color:red;}/* 实际上选中了 段落 1因为它是 article 的第 2 个子元素 *//* ✅ 用 :nth-of-type() 只数 p 元素 */article p:nth-of-type(2){color:red;/* 正确选中 段落 2 */}/* 给每个 h2 后面的第一个 p 加样式 */article h2 p{font-size:1.1em;}:nth-child()vs:nth-of-type()对比/* 场景表格的斑马纹 */tr:nth-child(even){}/* 偶数行包括 thead/tr */tr:nth-of-type(even){}/* 同类型中的偶数行 *//* 场景只给段落设置斑马纹 */article p:nth-of-type(odd){}/* ✅ 正确 */article p:nth-child(odd){}/* ❌ 可能被其他元素打乱 */六、现代伪类Modern Pseudo-classes:not()— 否定伪类选中不匹配选择器的元素。/* 选中所有非 disabled 的按钮 */button:not(:disabled){cursor:pointer;}/* 选中所有不含 .active 类的 li */li:not(.active){opacity:0.7;}/* 选中不是第一个也不是最后一个的 li */li:not(:first-child):not(:last-child){margin:8px 0;}/* CSS4 支持传入选择器列表现代浏览器 */li:not(:first-child, :last-child){margin:8px 0;}注意:not()不能嵌套伪元素且内部的复杂选择器在现代浏览器才支持。:is()— 匹配列表中的任意一个简化复杂的选择器群组。/* ❌ 冗长的写法 */h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover{color:#e74c3c;}/* ✅ 用 :is() 简化 */:is(h1, h2, h3, h4) a:hover{color:#e74c3c;}/* 减少重复 */article :is(h1, h2, h3){color:#1a1a2e;line-height:1.3;}/* 相当于 article h1, article h2, article h3 { color: #1a1a2e; line-height: 1.3; } */:is()与:where()的区别:is():where()权重取参数中最高的权重权重永远为0用途简化选择器并保持权重简化选择器且不增加权重/* :is() 的权重 .class (10) */:is(h1, .title, #header){}/* 权重 0-1-0 10 *//* :where() 的权重 0 */:where(h1, .title, #header){}/* 权重 0-0-0 0 */:has()— 父选择器现代浏览器支持选中包含特定子元素的父元素——这是 CSS 长期以来的重大突破/* 选中包含 img 的 figure 元素 */figure:has(img){border:1px solid #ddd;padding:10px;}/* 选中包含 figcaption 的 figure */figure:has(figcaption){background:#f8f9fa;}/* 选中后面紧跟 ul 的 li二级菜单项 */li:has( ul){position:relative;}/* 选中后面紧跟 ul 的 li 的 a有下拉菜单的导航项 */li:has( ul) a::after{content: ▼;font-size:0.8em;}/* 表单验证选中包含非法输入的字段容器 */.form-field:has(input:invalid) .error-msg{display:block;}七、伪类的优先级权重伪类如:hover、:nth-child()的权重等同于类选择器即10。/* 权重计算 */.btn:hover{}/* 10 10 20 */li:first-child{}/* 1 10 11 */input:focus:invalid{}/* 1 10 10 21 */:is(#header, .nav){}/* 取最高 100ID 的权重 */:where(#header){}/* 权重 0 */动手练习练习 1导航栏悬停效果实现一个导航栏要求普通链接为灰色鼠标悬停时变为蓝色并出现下划线动画下划线从中间向两侧展开当前页面链接.active为蓝色且始终显示下划线已访问过的链接为紫色但不超过 10% 的透明度区别练习 2斑马纹表格给定以下 HTML用:nth-child实现斑马纹效果tableclassdata-tabletheadtrth姓名/thth年龄/thth城市/th/tr/theadtbodytrtd张三/tdtd25/tdtd北京/td/trtrtd李四/tdtd30/tdtd上海/td/tr!-- 更多行... --/tbody/tabletbody 中的行奇偶不同背景色鼠标悬停时行高亮第一列的文字加粗练习 3:has()实战用:has()实现以下效果如果浏览器不支持用其他方式回退包含图片的.card有更大的上内边距.form-group中有input:invalid时对应的label变红色选中后面紧跟.details的.summary并添加箭头图标常见误区 ⚠️误区真相“:hover在手机上也能用”触摸屏没有悬停概念:hover在手机上表现不一致不要依赖它展示关键内容“:focus和:focus-visible是一回事”:focus-visible只在键盘聚焦时触发鼠标点击时不触发更适合现代交互“:nth-child(2n)和:nth-of-type(2n)效果一样”当父元素中有多种类型子元素时两者结果完全不同“:not()可以嵌套任何选择器”:not()内部传统上只能写一个简单选择器现代浏览器支持选择器列表“:is()和:where()完全一样”:is()取参数中最高权重:where()权重永远为 0“:visited可以设置任意样式”出于隐私保护浏览器限制:visited只能设置color、background-color、border-color、outline-color“:has()可以无限嵌套”:has()不能嵌套:has()且性能开销较大应谨慎使用“结构伪类会动态更新”当 DOM 变化时结构伪类会自动重新计算不需要刷新页面速查卡片 链接伪类顺序LoVe HAtea:link{}/* L - 未访问 */a:visited{}/* V - 已访问 */a:hover{}/* H - 悬停 */a:active{}/* A - 按下 */结构伪类速查伪类选中:first-child第一个子元素:last-child最后一个子元素:only-child唯一的子元素:nth-child(n)第 n 个子元素:nth-last-child(n)倒数第 n 个子元素:first-of-type同类型中的第一个:last-of-type同类型中的最后一个:nth-of-type(n)同类型中的第 n 个:empty无子元素含文本:nth-child()公式速查公式效果even/2n偶数项odd/2n1奇数项3n每第 3 个-n3前 3 个n4从第 4 个开始现代伪类伪类作用权重:is()匹配列表中任意一个取最高:where()匹配列表中任意一个0:not()排除匹配的元素取参数权重:has()包含特定子元素的父元素复杂扩展阅读MDN: 伪类MDN: :nth-child()MDN: :has() — 父选择器MDN: :is()CSS-Tricks: :nth-child() recipes英文Can I Use :has() — 查询浏览器支持配套代码CODE/06/pseudo-class-states.html — 状态伪类交互演示CODE/06/pseudo-class-structure.html — 结构伪类布局演示下一步进入 第07篇伪元素详解学习用::before和::after创建虚拟内容。