CSS 高级伪类指南::has、:is、:where 等 8 个实用选择器解析

更新日期: 2026-03-25 阅读: 25 标签: 伪类

除了常用的 :hover、:active、:focus,css 中还有一些冷门但非常实用的伪类,可以帮助你更优雅地处理各种交互场景。本文整理了 8 个值得掌握的 CSS 伪类,附带代码示例和兼容性说明。


1. :has() — 父级选择器

:has() 是 CSS 中一项重要的特性,允许根据子元素的存在与否来选择父元素,一定程度上可以减少对 JavaScript 的依赖。

/* 选择包含错误提示子元素的卡片 */
.card:has(.error) {
  border: 2px solid red;
}

/* 选择包含图片的链接 */
a:has(img) {
  text-decoration: none;
}

/* 选择表单中有无效输入的容器 */
.form-group:has(:invalid) {
  background: #ffeeee;
}

实际应用:

/* 当卡片内没有图片时,调整布局 */
.card:not(:has(img)) {
  grid-template-columns: 1fr;
}

/* 当标题超长时,隐藏描述 */
.card:has(h1.long-title) .description {
  display: none;
}

兼容性:Chrome 105+ | Safari 15.4+ | Firefox 121+


2. :is() 和 :where() — 选择器分组

这两个伪类用于简化复杂选择器的写法,提升代码可读性。

/* 传统写法 */
.card h1,
.card h2,
.card h3 {
  color: #333;
  margin-top: 0;
}

/* :is() 一行搞定 */
.card :is(h1, h2, h3) {
  color: #333;
  margin-top: 0;
}

:is() 与 :where() 的区别

/* :is() 优先级正常 */
.card :is(h1, h2) {
  color: red;   /* 优先级 (0,1,1) */
}

/* :where() 优先级为 0,可被覆盖 */
.card :where(h1, h2) {
  color: blue;  /* 优先级 (0,0,0) */
}

/* 后面的样式可以覆盖 :where() */
.card h1 {
  color: green; /* 覆盖成功 */
}

/* 但不能覆盖 :is() */
.card h1 {
  color: green; /* 无法覆盖 */
}

应用场景:

  • :is():需要保持选择器优先级时使用

  • :where():用于重置样式或降低优先级时使用

兼容性:Chrome 88+ | Firefox 78+ | Safari 14+


3. :not() — 否定选择器

:not() 用于排除特定元素,支持多参数。

/* 选择所有段落,排除 .intro 和 .footer */
p:not(.intro, .footer) {
  margin-bottom: 1rem;
}

/* 选择所有 input,排除 checkbox 和 radio */
input:not([type="checkbox"]):not([type="radio"]) {
  width: 100%;
}

/* 选择所有链接,排除 .external 和 #homepage */
a:not(.external, #homepage) {
  color: blue;
}

实际案例:

/* 隐藏所有元素,除了活动项 */
.list-item:not(.active) {
  display: none;
}

/* 所有按钮加样式,排除禁用的 */
button:not(:disabled) {
  cursor: pointer;
  opacity: 1;
}

/* 非空元素添加边框 */
*:not(:empty) {
  border: 1px solid #eee;
}

兼容性:广泛支持(多参数需 Chrome 88+ | Firefox 84+ | Safari 9+)


4. :target — URL 锚点定位

:target 根据 URL 中的 # 锚点改变样式,可实现无 JavaScript 的页面内跳转高亮。

/* 当用户访问 #section1 时 */
#section1:target {
  background: yellow;
  padding: 20px;
}

/* 当访问任何锚点时 */
:target {
  animation: highlight 2s ease;
}

@keyframes highlight {
  0% { background: yellow; }
  100% { background: transparent; }
}

实际应用:

<div id="intro">内容...</div>
<div id="details">内容...</div>
/* 当用户访问 #details 时,显示详情面板 */
#details:target .panel {
  display: block;
  animation: slideIn 0.3s ease;
}

/* 高亮当前章节 */
[id]:target {
  border-left: 4px solid #4fd1c5;
  padding-left: 16px;
}

适用场景:

  • 无 JavaScript 的 Tab 切换

  • FAQ 展开/折叠

  • 文档章节高亮

兼容性:所有现代浏览器


5. :focus-within — 子元素获得焦点

当元素自身或子元素获得焦点时触发,适合实现容器级的焦点反馈。

/* 输入框获得焦点时,容器也触发样式 */
.form-control:focus-within {
  border-color: #4fd1c5;
  background: #f0f9ff;
}

/* 当表单内有任何输入框获得焦点时 */
form:focus-within button[type="submit"] {
  background: #4fd1c5;
  transform: scale(1.05);
}

实际案例:

/* 搜索框聚焦时,显示下拉建议 */
.search-container:focus-within .suggestions {
  display: block;
}

/* 模态框内的输入框聚焦时,模态框高亮 */
.modal:focus-within {
  box-shadow: 0 0 0 4px rgba(79, 209, 197, 0.2);
}

/* 导航菜单聚焦时,显示子菜单 */
.nav-item:focus-within .submenu {
  opacity: 1;
  transform: translateY(0);
}

兼容性:Chrome 60+ | Firefox 52+ | Safari 10.1+


6. :checked — 复选框状态

:checked 用于选中状态的复选框或单选框,可实现无 JavaScript 的交互效果。

/* 复选框选中时,改变样式 */
input[type="checkbox"]:checked + label {
  text-decoration: line-through;
  color: #999;
}

/* 实现开关 */
.toggle-switch input[type="checkbox"]:checked + .slider {
  background: #4fd1c5;
}

.toggle-switch input[type="checkbox"]:checked + .slider:before {
  transform: translateX(26px);
}

高级应用:手风琴菜单

.accordion input[type="radio"]:checked ~ .content {
  max-height: 500px;
  padding: 20px;
}

.accordion input[type="radio"]:checked ~ .header .icon {
  transform: rotate(180deg);
}
html
<div class="accordion">
  <input type="radio" name="accordion" id="item1" checked>
  <label class="header" for="item1">
    标题 1 <span class="icon">▼</span>
  </label>
  <div class="content">内容...</div>
</div>

兼容性:所有现代浏览器


7. :placeholder-shown — 占位符显示状态

:placeholder-shown 用于匹配占位符可见的输入框,常用于实现浮动标签效果。

/* 当占位符显示时(空输入框) */
input:placeholder-shown + label {
  position: absolute;
  top: 12px;
  font-size: 16px;
}

/* 当占位符消失时(有内容) */
input:not(:placeholder-shown) + label {
  position: absolute;
  top: -8px;
  font-size: 12px;
  background: white;
  padding: 0 4px;
  color: #4fd1c5;
}

实际案例:浮动标签

.input-group input:placeholder-shown ~ .label {
  transform: translateY(0);
}

.input-group input:not(:placeholder-shown) ~ .label,
.input-group input:focus ~ .label {
  transform: translateY(-24px);
  font-size: 12px;
  color: #4fd1c5;
}

兼容性:Chrome 47+ | Firefox 52+ | Safari 9+


8. :blank — 空内容选择

:blank 用于选择没有内容的元素(包括空白节点),适用于隐藏空元素或显示占位内容。

/* 选择空段落 */
p:blank {
  display: none;
}

/* 空单元格加虚线边框 */
td:blank {
  border: 1px dashed #ccc;
}

实际应用:

/* 空列表项隐藏 */
li:blank {
  display: none;
}

/* 空提示框显示占位文字 */
.message:blank::before {
  content: "暂无消息";
  color: #999;
}

兼容性:实验性特性,目前 Chrome 和 Firefox 部分版本需启用实验性 Web 平台特性才支持


结语

以上 8 个 CSS 伪类在不同场景下各有用途,合理使用可以简化代码结构、减少 JavaScript 依赖。可以根据项目需求逐步尝试引入。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13502

相关推荐

css获取除第一个之外的子元素

有时候我们需要用CSS选择非第一个子元素,例如下面这样的HTML,希望让两个span之间间隔一定的距离,但又不希望简单的给每个span设置margin-right(会导致最后一个span也有margin-right,可能影响之后元素的排版)。

如何使用JS操纵伪元素

获取伪元素的属性值可以使用window.getComputedStyle()方法,获取伪元素的CSS样式声明对象。然后利用getPropertyValue方法或直接使用键值访问都可以获取对应的属性值。 更换class来实现伪元素属性值的更改、使用CSSStyleSheet的insertRule来为伪元素修改样式、

css否定伪类:not(s)

:not(X)是CSS中的一个否定伪类(选择器),并且接受一个简单的选择器作为参数。本质上,可以使任一其他选择器(作为参数)。:not(选择器)匹配传递参数选择器未选择的元素。传递参数或许不包括增加的选择器或者伪元素选择器。

css中:visited怎么不起作用?

css定义超链接四个状态也是有顺序的,对于这4个伪类的设置,有一点需要特别注意,那就是它们的先后顺序,要让它们遵守一个顺序原则,也就是link ~ visited ~ hover ~ active 。

快速了解:User-valid和:User-invalid

最近,Chrome 119 终于正式对:user-valid和:user-invalid这两个验证伪类进行了支持。看名称,似乎和:valid和:invalid有点相似,那么有什么区别呢?快速了解一下吧

css伪选择器使用总结——css中关于伪类和伪元素的知识总汇

CSS 伪类用于向某些选择器添加特殊的效果,而CSS引入伪类和伪元素的概念是为了实现基于文档树之外的信息的格式化。这里讲总结关于css伪类和伪元素的相关使用

善用CSS伪类,不用JS也能做出选项卡功能

本篇文章的技术给予选项卡UI另一种开发的选择,Radio button的特性还有很多应用可以做(如Switcher),只要善用HTML表单元素与CSS的一些技巧,也能玩出很多有趣的功能,甚至替代JavaScript的部份工作.

CSS3新增的伪类有哪些 与 居中div的多种方法

CSS3新增伪类有那些?p:first-of-type:选择属于其父元素的首个<p>元素,p:last-of-type:选择属于其父元素的最后<p>元素,p:only-of-type:属于父元素的特定类型的唯一子元素,p:only-child:属于父元素的唯一子元素的每个<p>元素;p:nth-child(2)

为什么是link-visited-hover-active

通常我们在设置链接的一些伪类(link,visited,hover,active)样式时,要让不同的状态显示正确的样式,我们需要按一定的顺序设置这些伪类的样式。这里我就按CSS2规范中推荐的顺序进行介绍,即 link-visited-hover-active

中间文字,两边横线的css3伪类的使用

CSS伪类是用来添加一些选择器的特殊效果。使用了css3的伪类,即相当于是在一个div中写入文字,然后在它前后各加了一个div,然后进行位置及宽高的调节。代码中只写一个div,然后在css样式中,对该div设置flex布局

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!