首页与我联系

「基础」关于 :is, :where 和 :has 新伪类选择器的介绍

By 前端达人
Published in 2-CSS3
August 20, 2022
1 min read
「基础」�关于 :is, :where 和 :has 新伪类选择器的介绍

:is, :where 和 :has 这 3 个新的伪类选择器你在使用吗,除了 ie ,大多数现代浏览器都支持,在介绍之前我们先了解下什么是选择器。首先我们看看 W3C 怎么用英文定义的吧:

CSS selectors allow you to choose elements by type, attributes, or location within the HTML document. CSS 选择器允许您在 HTML 文档中按类型、属性或位置选择元素。

则伪类选择器以 HTML 元素的当前状态为目标。比如最常用的 :hover,它在光标移动到元素上时应用样式,因此它用于突出显示可点击的链接和按钮。其他受欢迎的选项包括:

  • :visited: 匹配已访问的链接
  • :target: 用来改变页面中锚链接URL所指向的元素的样式
  • :first-child: 匹配第一个子元素
  • :nth-child: 匹配指定的子元素,具体的第几个子元素
  • :empty: 这个伪类会匹配没有内容的元素或没有子元素
  • :checked: 匹配被用户选中的单选按钮Radio或复选按钮checkbox
  • :blank: 匹配空的输入框
  • :enabled: 匹配可以输入的表单元素
  • :disabled: 匹配不可以输入的表单元素
  • :required: 匹配必填的表单元素
  • :valid: 匹配验证通过的表单元素
  • :invalid: 匹配未验证通过的表单元素
  • :playing: 匹配正在播放的音频或视频元素

:is() 伪类介绍

比如以下代码是我们经常用到的场景,比如你要匹配 article section aside 标签下的 P 元素应用单独的颜色样式,如下所示:

/* default black */
p {
  color: #000;
}

/* gray in <article>, <section>, or <aside> */
article p,
section p,
aside p {
  color: #444;
}

这是一个简单的例子,但更复杂的页面会导致更复杂和冗长的选择器字符串。你可能在使用类似 Sass 这样的框架进行简化:

article, section, aside {

  p {
    color: #444;
  }

}

这样做会避免创建相同的 CSS 代码,减少输入工作量,并可以防止错误。但是嵌套可能会导致其他问题。构建深度嵌套的选择器很容易,这些选择器变得越来越难以阅读和输出冗长的 CSS。

但是使用 :is() 伪类选择器,你可以这样优化你的代码:

:is(article, section, aside) p {
  color: #444;
}

我们还可以多个 :is 一起使用,构建更复杂的选择器,比如 article 标签下的 section 标签中含有 .primary.secondary 样式下含有 h1,h2,p 的内容。

article section:not(:first-child):is(.primary, .secondary) :is(h1, h2, p) {
  color: green;
}

如果不使用 :is() 其效果等同如下的 CSS 效果:

article section.primary:not(:first-child) h1,
article section.primary:not(:first-child) h2,
article section.primary:not(:first-child) p,
article section.secondary:not(:first-child) h1,
article section.secondary:not(:first-child) h2,
article section.secondary:not(:first-child) p {
  color: green;
}

注意 :is() 不能匹配 ::before 和 ::after 伪元素,所以如下这段示例代码会失败:

div:is(::before, ::after) {
  display: block;
  content: '';
  width: 1em;
  height: 1em;
  color: blue;
}

:where 伪类介绍

:where() 选择器语法与 :is() 相同,并且在所有现代浏览器(不是 IE)中也受支持。如下段代码所示:

:where(article, section, aside) p {
  color: #444;
}

他们之间的区别在于优先级(Specificity),优先级是用于确定哪个 CSS 选择器应该覆盖所有其他选择器的逻辑。在以下示例中,article p 比单独的 p 更具体,因此 article 中的所有段落元素都将是灰色的:

article p { color: #444; }
p { color: #000; }

在 :is() 的情况下,优先级是在其参数中找到的最具体的选择器。在 :where() 的情况下,其优先级是最低的0。让我来看下段代码,你觉得段落显示什么颜色?

article p {
  color: black;
}

:is(article, section, aside) p {
  color: red;
}

:where(article, section, aside) p {
  color: blue;
}

:is() 选择器与 article p 具有相同的优先级,但它出现在 article p 的后面,因此文本变为红色。如果你想选择蓝色,有必要同时删除 article p 和 :is() 选择器以应用蓝色,因为 :where() 选择器没有任何一个选择器那么具体,优先级是最低的。

更多的代码库将使用 :is() 而不是 :where()。但是, :where() 的零优先级,对于 CSS 重置可能是实用的,它在没有特定样式可用时应用标准样式。通常,重置应用于默认字体、颜色、填充和边距。

:has 选择器

:has() 选择器使用与 :is() 和 :where() 类似的语法,但它以包含一组其他元素为目标。例如,下面是为包含一个或多个 img 或 section 标签的任何 a 链接,添加蓝色、两像素边框的样式:

/* style the <a> element */
a:has(img, section) {
  border: 2px solid blue;
}

这是几十年来最激动人心的 CSS 特性!开发人员终于有办法定位父元素了!

难以捉摸的“父选择器”一直是最受欢迎的 CSS 功能之一,但它给浏览器供应商带来了性能复杂性,简单的来说有以下几个原因:

  • 当元素在页面上绘制时,浏览器会将 CSS 样式应用于元素。因此,在添加更多子元素时,必须重新绘制整个父元素。
  • 在 JavaScript 中添加、删除或修改元素可能会影响整个页面的样式。

假设供应商已经解决了性能问题,那么 :has() 的引入,以前看来只能 JavaScript 脚本解决的问题,现在纯CSS也能实现。例如,当某些验证无法通过时,您可以设置外部表单 fieldset 和提交按钮的样式,提醒用户相关问题:

/* 红色边框,当验证未通过时 */
fieldset:has(:required:invalid) {
  border: 3px solid red;
}

/* 当验证未通过时,改变按钮的样式 */
fieldset:has(:required:invalid) + button[type='submit'] {
  opacity: 0.2;
  cursor: not-allowed;
}

1660641060form-fields.webp

关于子菜单样式的应用,如下段代码所示:

/* display sub-menu indicator */
nav li:has(ol, ul) a::after {
  display: inlne-block;
  content: ">";
}

或者您可以添加调试样式,例如突出显示所有 figure 元素中没有 img 的,示例代码如下:

/* where's my image?! */
figure:not(:has(img)) {
  border: 3px solid red;
}

1660641019missing-image.webp

注意:请注意 :has() 还是比较新,并且支持比 :is() 和 :where() 更有限。它可以在 Safari 15.4+ 和 Chrome 101+ 中使用,估计在 2023 更加得到广泛的支持。

总结

:is() 和 :where() 伪类选择器简化了 CSS 语法。减少了你使用第三方工具的语法嵌套。:has() 更具革命性和令人兴奋,我们可以精准的选择父元素了。

前端达人公众号.jpg

注:本文属于原创文章,版权属于「前端达人」公众号及 qianduandaren.com 所有,未经授权,谢绝一切形式的转载


Tags

cssbasic
Previous Article
使用亚马逊虚拟专用服务器部署Strapi + Gatsby 博客应用的踩坑笔记(下)
前端达人

前端达人

专注前端知识分享

Table Of Contents

1
:is() 伪类介绍
2
:where 伪类介绍
3
:has 选择器
4
总结

相关文章

「基础」CSS Blend Modes 混合模式的学习与整理(下)
August 24, 2022
1 min

前端站点

VUE官网React官网TypeScript官网

公众号:前端达人

前端达人公众号