总览
CSS 选择器容许你通过类型、属性、位于 HTML 文档中的地位来抉择元素。本教程论述了三个新选项
:is()
、:where()
和:has()
。
选择器通常在样式表中应用。上面的示例会找到所有 <p>
段落元素并将字重更改为粗体:
p {font-weight: bold;}
你也能够在 JavaScript 中应用选择器来找到 DOM 节点:
- document.querySelector()返回首个匹配的 HTML 元素。
- document.querySelectorAll()返回所有匹配的 HTML 元素,这些元素位于类数组 NodeList 中。
伪类选择器依据 HTML 元素的以后状态来定位它们。兴许最广为人知的是 :hover
,它在光标移到一个元素上时利用款式,所以它被用来高亮可点击的链接和按钮。
其余受欢迎的选项包含:
:visited
:匹配拜访过的链接:target
:匹配文档 URL 所指向的元素:first-child
:指向第一个子元素:nth-child
:抉择指定子元素:empty
:匹配没有内容或子元素的元素:checked
:匹配已勾选的复选框或单选按钮:blank
:抉择用户输出为空的输入框:enabled
:匹配一个被启用的输入框。如果一个元素可能被激活(如抉择、点击或承受文本输出),或者可能获取焦点,则该元素是启用的:disabled
:匹配一个被禁用的输入框。在被禁用时,元素不能被激活或获取焦点:required
:指向必填的输入框。所谓必填,就是在提交所属表单之前,用户必须为输入框指定一个值:valid
:匹配一个内容验证正确的输入框:invalid
:匹配一个内容未通过验证的输入框:playing
:指向一个正在播放的audio
或video
元素
浏览器最近又收到了三个伪类选择器…
:is 伪类选择器
留神:这最后被指定为 :matches()
和:any()
,但 :is()
曾经成为 CSS 规范。
MDN 解释::is()
CSS 伪类函数将选择器列表作为参数,并抉择该列表中任意一个选择器能够抉择的元素。这对于以更紧凑的模式编写大型选择器十分有用。
你常常须要在不止一个元素下面利用雷同的款式。比如说,<p>
段落文本色彩默认为彩色,然而当它位于<article>
,<section>
,<aside>
外面时,文本色彩为灰色:
/* default black */
p {color: #000;}
/* gray in <article>, <section>, or <aside> */
article p,
section p,
aside p {color: #444;}
这是一个简略的例子,但更简单的页面将导致更简单和更简短的选择器字符串。任何选择器的语法错误都会毁坏所有元素的款式。
像 Sass 这样的 CSS 预处理器容许嵌套(这也将呈现在原生 CSS 中)。
article, section, aside {
p {color: #444;}
}
这能够创立雷同的 CSS 代码,缩小打字的工作量,并能够避免谬误。然而:
- 在原生嵌套到来之前,你仍须要一个 CSS 构建工具。你可能想应用像 Sass 这样的计划,但这可能给一些开发团队引入复杂性。
- 嵌套可能会导致其余问题。构建深度嵌套的选择器是很容易的,但它会变得越来越难以浏览以及输入简短的 CSS。
:is()
提供了一个原生 CSS 解决方案。该个性已被所有古代浏览器反对(IE 除外)。
:is(article, section, aside) p {color: #444;}
单个选择器能够蕴含任意数量的 :is()
伪类。比如说,上面的简单选择器将绿色文本色彩利用于所有 <h1>
、<h2>
和<p>
元素,这些元素是 <section>
的子元素,其蕴含类 .primary
或.secondary
,并且不是 <article>
的第一个子元素。
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
伪元素,因而上面示例代码会不起作用:
/* NOT VALID - selector will not work */
div:is(::before, ::after) {
display: block;
content: '';
width: 1em;
height: 1em;
color: blue;
}
:where 伪类选择器
:where()
选择器语法与 :is()
雷同,也被所有古代浏览器反对(IE 除外)。这往往会导致雷同的款式。比方:
:where(article, section, aside) p {color: #444;}
不同点在于优先级。优先级是用来决定哪个 CSS 选择器应该笼罩所有其余选择器的算法。在上面的例子中,article p
比独自的 p
更加具体,因而所有位于 <article>
内的 p
元素的字体色彩将会是灰色:
article p {color: #444;}
p {color: #000;}
在 :is()
的状况下,优先级是在其参数中找到的最具体的选择器。在 :where()
的状况下,优先级为零。
思考上面的 CSS:
article p {color: black;}
:is(article, section, aside) p {color: red;}
:where(article, section, aside) p {color: blue;}
让咱们将这个 CSS 利用到上面的 HTML 中:
<article>
<p>paragraph text</p>
</article>
段落文本将被渲染为红色,点击链接查看 CodePen 示例。
:is()
选择器与 article p
具备雷同的优先级,但它在样式表的前面,所以文本变成了红色。如有必要能够同时删除 article p
和:is()
选择器来利用蓝色,因为 :where()
选择器的优先级比两者都低。
更多的代码库会应用 :is()
而不是 :where()
。然而,:where()
的零优先级对 CSS 重置来说是很实用的,它在没有特定款式的状况下利用规范款式的基线。通常状况下,重置会利用一个默认的字体、色彩、内边距和外边距。
这个 CSS 重置代码对 <h2>
题目利用了 1em
的上外边距,除非它们是 <article>
元素的首个子元素。
/* CSS reset */
h2 {margin-block-start: 1em;}
article :first-child {margin-block-start: 0;}
试图在样式表的前面设置一个自定义的 <h2>
上外边距是没有成果的,因为 article :first-child
有更高的优先级:
/* never applied - CSS reset has higher specificity */
h2 {margin-block-start: 2em;}
你能够用一个更高优先级的选择器来解决这个问题,但这须要更多的代码,而且对其余开发者来说不并不显著。你最终会遗记你为什么须要它。
/* styles now applied */
article h2:first-child {margin-block-start: 2em;}
你也能够通过对每个款式利用 !important
来解决这个问题,但请防止这样做!它使进一步的款式定义和开发变得更具挑战性。
/* works but avoid this option! */
h2 {margin-block-start: 2em !important;}
一个更好的抉择是在你的 CSS 重置中采纳 :where()
的零优先级。
/* reset */
:where(h2) {margin-block-start: 1em;}
:where(article :first-child) {margin-block-start: 0;}
当初,你能够笼罩任何 CSS 重置款式,无论其优先级如何;不须要进一步的选择器或!important
:
/* now works! */
h2 {margin-block-start: 2em;}
:has()伪类选择器
:has()
选择器应用了相似于 :is()
和:where()
的语法,但它的指标是一个蕴含其余元素的元素。比如说,这里是为任何蕴含一个或多个 <img>
或<section>
标签的 <a>
链接增加蓝色、两像素宽的边框的 CSS:
/* style the <a> element */
a:has(img, section) {border: 2px solid blue;}
这是几十年来最激动人心的 CSS 停顿!开发者们终于有了一种针对父元素的办法。
难以捉摸的 ” 父选择器 ” 始终是人们申请最多的 CSS 个性之一,但它给浏览器供应商带来了性能上的麻烦。因而,它曾经行将到来了很长时间。简而言之:
- 浏览器在页面上绘制元素时将 CSS 款式利用于该元素。因而,在进一步增加子元素时,整个父元素必须从新绘制。
- 在 JavaScript 中增加、删除或批改元素可能会影响整个页面的款式,直到闭合的
<body>
标签为止。
假如供应商曾经解决了性能问题,:has()
的引入容许过来没有 JavaScript 就不可能实现的成为可能。例如,当任何必填的外部字段没有校验通过时,你能够设置内部表单 <fieldset>
和上面的提交按钮的款式。
/* red border when any required inner field is invalid */
fieldset:has(:required:invalid) {border: 3px solid red;}
/* change submit button style when invalid */
fieldset:has(:required:invalid) + button[type='submit'] {
opacity: 0.2;
cursor: not-allowed;
}
这个例子增加了一个导航链接子菜单指示器,其中蕴含一个子菜单项的列表:
/* display sub-menu indicator */
nav li:has(ol, ul) a::after {
display: inlne-block;
content: ">";
}
或者,你能够增加调试款式,比方高亮显示所有没有外部 img
的<figure>
元素。
/* where's my image?! */
figure:not(:has(img)) {border: 3px solid red;}
在关上你的编辑器和重构你的 CSS 代码库之前,请留神 :has()
是很新的,反对比 :is()
和:where()
更无限。它在 Safari 15.4+ 和 Chrome 105+ 可用,然而到 2023 年应该能够宽泛应用。
总结
:is()
和 :where()
伪类选择器简化了 CSS 语法。你对嵌套和 CSS 预处理器的需要会缩小。
:has()
更具革命性和令人激动。父级抉择将迅速流行起来,咱们将遗记黑暗时代。
以上就是本文的所有内容,如果对你有所帮忙,欢送点赞珍藏转发~