51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

CSS基础拓展:解析CSS 中的 :has() 选择器

作为"父选择器"的先驱,:has()伪类的范围远比仅仅为元素的祖先设置样式大得多。凭借其在 Safari 15.4+ 和 Chromium 105+ 中的可用性,以及在 Firefox 中的标志,现在是您熟悉:has()其用例的好时机。

作为一个伪类,它的基本功能:has()是设置它所附加的元素的样式------也就是所谓的"目标"元素。这类似于其他伪类,如:hoveror :activea:hover旨在为<a>处于活动状态的元素设置样式。

然而,:has()也类似于:is(), :where(), 和:not(),因为它接受括号内的相对选择器列表。这允许:has()创建复杂的标准来测试,使其成为一个非常强大的选择器。

为了感受它是如何:has()工作的,让我们看一个如何应用它的例子。在下面的选择器中,我们测试一个<article>元素是否有一个<img>子元素:

article:has(img) {}

此选择器的可能结果如下图所示。显示了三个文章元素,其中两个包含图像,并且都具有浅绿色背景和与没有图像的元素不同的填充。

image.png


只要<img>元素存在于该<article>元素的任何位置,上面的选择器就会应用------无论是作为直接子元素还是作为其他嵌套元素的后代。

如果我们想确保规则仅适用于元素<img>的直接(非嵌套)子元素<article>,我们还可以包含子组合器:

article:has(> img) {}

此更改的结果如下图所示。显示了相同的三张卡片,但这次只有图像是 的直接子代的那一张<article>具有浅绿色背景和填充。

image.png


在这两个选择器中,我们定义的样式都应用于目标元素,即<article>. 这就是为什么人们经常称其为:has()"父级"选择器:如果某些元素以某种方式存在,则它们的"父级"会收到指定的样式。

注意::has()伪类本身不会为选择器添加任何特异性权重。:is()和一样:not(), 的特异性:has()等于选择器列表中特异性最高的选择器。例如,:has(#id, p, .class)将具有赋予id. 要复习特异性,请查看 CSS Master, 3rd Edition 中关于特异性的部分。

如果目标元素后跟特定的兄弟元素,我们还可以使用相邻兄弟组合器 ( +) 选择目标元素。在下面的例子中,我们<h1>只选择一个紧跟 an 的元素<h2>


h1:has(+ h2) {}

在下图中,<article>显示了两个元素。在第一个中,因为<h1>后面跟着一个<h2>,所以<h1>应用了浅绿色背景。

image.png

使用通用兄弟组合器 ( ~),我们可以检查特定元素是否是目标后面任何位置的兄弟。在这里,我们正在检查某处是否有一个<p>元素作为 的兄弟元素<ul>

ul:has(~ p) {}

下图显示了两个<article>元素,每个元素都包含一个无序列表。第二篇文章的列表后面是一段,所以它应用了浅绿色背景。

image.png

到目前为止,我们使用的选择器为附加到 的目标元素设置了样式:has(),例如<ul>in ul:has(~ p)。与常规选择器一样,我们的:has()选择器可以扩展得更复杂,例如为不直接附加到选择:has()器的元素设置样式条件。

在下面的选择器中,样式适用于作为 an本身具有 an作为相邻兄弟姐妹<p>的兄弟姐妹的任何元素:<h2>``<h3>

h2:has(+ h3) ~ p

在下图中,<article>显示了两个元素。在第二个中,段落的样式为淡绿色背景和增加的左边距,因为这些段落是 an 的兄弟姐妹,<h2>后面跟着<h3>``。

image.png


:has()注意:如果我们对可用的 CSS 选择器有很好的理解,我们使用起来会更成功。MDN 提供了选择器的简明概述,我已经编写了一个由两部分组成的关于选择器的系列文章,其中包含更多实际示例。

请记住,:has()可以接受一个选择器列表,我们可以将其视为OR条件。让我们选择一个段落,如果它包含<a>or <strong>or <em>

p:has(a, strong, em) {}

在下图中,有两个段落。因为第二段包含一个<strong>元素,所以它具有浅绿色背景。

image.png

我们也可以链式:has()选择器来创造AND条件。在下面的复合选择器中,我们正在测试 an<img>是 的第一个子节点<article>,并且 the<article>包含 an<h1>后跟 an <h2>


article:has(> img:first-child):has(h1 + h2) {}

下图显示了三个<article>元素。第二篇文章有浅绿色背景(以及其他样式),因为它包含作为第一个子项的图像和<h1>后跟一个<h2>``。

image.png

最后可以预览下DEMO:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS has 知识 | Web前端之家www.jiangweishan.com</title>
    <style>
        #example-1 article:has(img) {
  background-color: palegreen;
  padding: 0 0 2rem;
}
#example-1 article:has(img) img {
  border-radius: 0.5rem 0.5rem 0 0;
}
#example-1 article:has(img) > *:not(img) {
  padding-inline: 1.5rem;
}

#example-2 article:has(> img) {   background-color: palegreen;   padding: 0 0 2rem; } #example-2 article:has(> img) img {   border-radius: 0.5rem 0.5rem 0 0; } #example-2 article:has(> img) > *:not(img) {   padding-inline: 1.5rem; }

#example-3 h1:has(+ h2) {   font-size: 3rem;   background-color: palegreen; } #example-3 h1:has(+ h2) + h2 {   -webkit-margin-before: 0.15em;           margin-block-start: 0.15em;   color: #797979;   font-weight: 500;   font-style: italic; }

#example-4 ul:has(~ p) {   background-color: palegreen;   -webkit-margin-after: 2rem;           margin-block-end: 2rem; }

#example-5 h2:has(+ h3) ~ p {   background-color: palegreen;   -webkit-margin-start: 2em;           margin-inline-start: 2em; }

#example-6 p:has(a, strong, em) {   background-color: palegreen; }

#example-7 article:has(> img:first-child):has(h1 + h2) {   background-color: palegreen;   padding: 0 0 2rem; } #example-7 article:has(> img:first-child):has(h1 + h2) img {   border-radius: 0.5rem 0.5rem 0 0; } #example-7 article:has(> img:first-child):has(h1 + h2) > *:not(img) {   padding-inline: 1.5rem; } #example-7 article:has(> img:first-child):has(h1 + h2) :is(h1, h2) {   font-weight: 500; } #example-7 article:has(> img:first-child):has(h1 + h2) h1 {   font-family: Georgia, serif;   font-size: 1.75rem;   font-style: italic; } #example-7 article:has(> img:first-child):has(h1 + h2) h2 {   -webkit-margin-before: 0.15em;           margin-block-start: 0.15em;   font-size: 1.25rem; }

:root {   --body-bg: whitesmoke; }

body {   font-size: 0.9rem; }

[id] {   display: grid;   place-content: center;   gap: 4vmax;   min-height: 100vh;   padding: 5vmax; } [id]:not(:first-child) {   border-top: 1px dashed #797979; } [id] *:not([id] > h2, code, .columns) {   outline: 1px dashed #797979; } [id] > h2 {   text-align: center; }

[data-tag] {   position: relative; } [data-tag]::before {   content: attr(data-tag);   position: absolute;   font-family: system-ui;   font-style: normal;   background-color: mediumvioletred;   letter-spacing: 0.03em;   padding: 0.25em;   font-size: 1.05rem;   font-weight: 500;   color: #fff;   top: 0;   left: 0;   transform: translate(-1ch, -33%);   border-radius: 0.25rem; }

h1 {   font-size: 2rem;   line-height: 1.1; }

code {   color: mediumvioletred;   letter-spacing: -0.03em; }

article {   background-color: #fff;   border-radius: 0.5rem;   padding: 2rem; } article > img:first-child {   width: 100%;   -o-object-fit: cover;      object-fit: cover; } article > * + *, article ul li + li {   -webkit-margin-before: 1em;           margin-block-start: 1em; }

img {   max-width: 100%;   display: block; }

.columns {   width: min(80ch, 100vw - 2rem);   display: grid;   grid-template-columns: repeat(auto-fit, minmax(22ch, 1fr));   gap: 2vmax;   align-items: start; }     </style> </head> <body>     <div id="example-1">         <h2><code>article:has(img)</code></h2>               <div class="columns">           <article data-tag="article">             <h3>Lorem, ipsum dolor.</h3>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <img src='https://images.unsplash.com/photo-1554692901-e16f2046918a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwNzc0OTg&ixlib=rb-4.0.3&q=80&w=400' alt=''>             <h3>Lorem, ipsum dolor.</h3>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <h3>Lorem, ipsum dolor.</h3>             <p><img src='https://images.unsplash.com/photo-1638445533129-65aaf55fb94c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwNzc5MjE&ixlib=rb-4.0.3&q=80&w=20' alt=''> Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>         </div>       </div>             <div id="example-2">         <h2><code>article:has(> img)</code></h2>               <div class="columns">           <article data-tag="article">             <h3>Lorem, ipsum dolor.</h3>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <img src='https://images.unsplash.com/photo-1554692901-e16f2046918a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwNzc0OTg&ixlib=rb-4.0.3&q=80&w=400' alt=''>             <h3>Lorem, ipsum dolor.</h3>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <h3>Lorem, ipsum dolor.</h3>             <p><img src='https://images.unsplash.com/photo-1638445533129-65aaf55fb94c?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwNzc5MjE&ixlib=rb-4.0.3&q=80&w=20' alt=''> Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>         </div>       </div>             <div id="example-3">         <h2><code>h1:has(+ h2)</code></h2>               <article>           <h1 data-tag="h1">Lorem, ipsum dolor.</h1>           <h2>Sit amet consectetur adipisicing elit.</h2>           <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati odit reprehenderit culpa.</p>         </article>         <article>           <h1 data-tag="h1">Lorem, ipsum dolor.</h1>           <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Obcaecati odit reprehenderit culpa.</p>         </article>       </div>             <div id="example-4">         <h2><code>ul:has(~ p)</code></h2>               <div class="columns">           <article>             <ul data-tag="ul">               <li>Lorem, ipsum dolor.</li>               <li>Fugiat, officiis sint!</li>               <li>Sit, facere ratione!</li>             </ul>           </article>           <article>             <ul data-tag="ul">               <li>Lorem, ipsum dolor.</li>               <li>Labore, a blanditiis!</li>               <li>Tempora, amet consectetur.</li>             </ul>             <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit.</p>           </article>         </div>       </div>             <div id="example-5">         <h2><code>h2:has(+ h3) ~ p</code></h2>         <div class="columns">           <article>             <h2 data-tag="h2">Lorem, ipsum dolor.</h2>             <p data-tag="p">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima placeat quo omnis.</p>             <p data-tag="p">Expedita est consectetur pariatur in, sint maiores molestiae temporibus vitae deleniti recusandae.</p>           </article>           <article>             <h2 data-tag="h2">Sit amet consectetur</h2>             <h3 data-tag="h3">Porro delectus maxime ea</h3>             <p data-tag="p">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Quod rerum quo nam.</p>             <p data-tag="p">Corrupti incidunt similique unde iste alias nostrum sit quae natus pariatur impedit?</p>           </article>         </div>       </div>             <div id="example-6">         <h2><code>p:has(a, strong, em)</code></h2>               <div class="columns">           <article>             <p data-tag="p">Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque non corporis nesciunt mollitia natus. Harum.</p>           </article>           <article>             <p data-tag="p">Eaque voluptatum <strong>soluta sit ipsam</strong> nihil vel optio ratione numquam magnam. Beatae amet velit odio?</p>           </article>         </div>       </div>             <div id="example-7">         <h2><code>article:has(> img:first-child):has(h1 + h2)</code></h2>               <div class="columns">           <article data-tag="article">             <h1 data-tag="h1">Lorem, ipsum dolor.</h1>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <img src='https://images.unsplash.com/photo-1554692901-e16f2046918a?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwNzc0OTg&ixlib=rb-4.0.3&q=80&w=400' alt=''>             <h1 data-tag="h1">Lorem, ipsum dolor.</h1>             <h2 data-tag="h2">Consectetur adipisicing elit</h2>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>           <article data-tag="article">             <img src='https://images.unsplash.com/photo-1526137966266-60618b40bcd4?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwzMjM4NDZ8MHwxfHJhbmRvbXx8fHx8fHx8fDE2NzQwODM1Nzc&ixlib=rb-4.0.3&q=80&w=400' alt=''>             <h1 data-tag="h1">Lorem, ipsum dolor.</h1>             <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>           </article>         </div>       </div> </body> </html>




赞(4)
未经允许不得转载:工具盒子 » CSS基础拓展:解析CSS 中的 :has() 选择器