首页 >web前端 >css教程 >使用:has()关系伪类创建动画,可点击的卡

使用:has()关系伪类创建动画,可点击的卡

Christopher Nolan
Christopher Nolan原创
2025-03-10 12:21:13399浏览

Creating Animated, Clickable Cards With the :has() Relational Pseudo Class

Chrome和Safari浏览器已完全支持CSS的:has()伪类,该伪类正逐步在许多浏览器中推出。它通常被称为“父选择器”——我们可以通过子选择器来选择和设置父元素的样式——但:has()的用途远不止于此。其中一个用途是重新设计许多人经常使用的可点击卡片模式。

我们将探讨:has()如何帮助我们处理链接卡片,但首先……

:has()伪类是什么?

已经有许多优秀的文章对:has()的用途进行了很好的解释,但它仍然比较新,因此我们也应该在这里简单介绍一下。

:has()是一个关系伪类,它是W3C选择器级别4工作草案的一部分。这就是括号的用途:匹配与特定子元素相关联(更准确地说,是包含特定子元素)的元素。

<code>/* 匹配包含图像元素的article元素 */
article:has(img) { }

/* 匹配article元素,其内部直接包含图像 */
article:has(> img) { }</code>

因此,您可以理解为什么我们可能将其称为“父”选择器。但是我们也可以将其与其他功能伪类结合使用以获得更具体的匹配。假设我们想要设置样式,使文章包含任何图像。我们可以将:has()的关系能力与:not()的否定能力结合起来实现这一点:

<code>/* 匹配不包含图像的article元素 */
article:not(:has(img)) { }</code>

但这只是我们可以结合各种能力来使用:has()实现更多功能的开始。在我们专门解决可点击卡片难题之前,让我们看看目前在不使用:has()的情况下处理它们的一些方法。

我们目前如何处理可点击卡片

如今,人们创建完全可点击卡片主要有三种方法,为了充分理解这个伪类的强大功能,对其进行总结很有必要。

“链接作为包装器”方法

这种方法经常使用。我从不使用这种方法,但我创建了一个快速演示来演示它:

这里有很多问题,尤其是在可访问性方面。当用户使用旋转器功能浏览您的网站时,他们会听到该<a></a>元素内的完整文本——标题、文本和链接。有些人可能不想听完所有这些。我们可以做得更好。从HTML5开始,我们可以在<a></a>元素内嵌套块元素。但这对我来说总感觉不对,尤其是因为这个原因。

优点:

  • 快速实现
  • 语义正确

缺点:

  • 可访问性问题
  • 文本不可选择
  • 覆盖默认链接中使用的样式非常麻烦

JavaScript方法

使用JavaScript,我们可以将链接附加到卡片,而不是将其写入标记中。我找到了costdev的这个很棒的CodePen演示,它还在此过程中使卡片文本可选择:

这种方法有很多好处。我们的链接在聚焦时是可访问的,我们甚至可以选择文本。但在样式方面有一些缺点。例如,如果我们想为这些卡片添加动画,我们必须在.card主包装器而不是链接本身添加:hover样式。当链接通过键盘制表键聚焦时,我们也不会从动画中受益。

优点:

  • 可以实现完美的可访问性
  • 可以选择文本

缺点:

  • 需要JavaScript
  • 无法右键单击(尽管可以通过一些额外的脚本修复)
  • 需要对卡片本身进行大量样式设置,这在聚焦链接时不起作用

::after选择器方法

此方法要求我们将卡片设置为相对定位,然后在链接的::after伪选择器上设置绝对定位。这不需要任何JavaScript,并且很容易实现:

这里有一些缺点,尤其是在选择文本方面。除非您在卡片主体上提供更高的z-index,否则您将无法选择文本,但如果您这样做,请注意点击文本不会激活您的链接。您是否想要可选择文本取决于您。我认为这可能是一个用户体验问题,但这取决于用例。文本仍然可以通过屏幕阅读器访问,但我对这种方法的主要问题是缺乏动画可能性。

优点:

  • 易于实现
  • 可访问的链接,没有冗余文本
  • 在悬停和聚焦时有效

缺点:

  • 文本不可选择
  • 您只能为链接设置动画,因为这是您悬停的元素。

一种新方法:将::after:has()结合使用

既然我们已经确定了可点击卡片的现有方法,我想展示一下如何将:has()添加到混合中以解决大多数这些缺点。

事实上,让我们将这种方法基于我们最后查看的使用链接元素上的::after的方法。我们实际上可以在那里使用:has()来克服该方法的动画限制。

让我们从标记开始:

<code>/* 匹配包含图像元素的article元素 */
article:has(img) { }

/* 匹配article元素,其内部直接包含图像 */
article:has(> img) { }</code>

为了保持简单,我将直接在CSS中定位元素,而不是使用类。

对于此演示,我们将为卡片添加图像缩放和阴影以进行悬停,并为链接添加动画,使箭头弹出并更改链接的文本颜色。为了简化操作,我们将为卡片添加一些作用域自定义属性。这是基本的样式:

<code>/* 匹配包含图像元素的article元素 */
article:has(img) { }

/* 匹配article元素,其内部直接包含图像 */
article:has(> img) { }</code>

很好!我们为图像添加了初始缩放比例(--img-scale: 1.001)、卡片标题的初始颜色(--title-color: black)以及一些我们将用于使箭头从链接中弹出的额外属性。我们还设置了box-shadow声明的空状态,以便稍后对其进行动画处理。这为我们现在需要创建的可点击卡片设置了基础,因此让我们通过将这些自定义属性添加到我们想要设置动画的元素来添加一些重置和样式:

<code>/* 匹配不包含图像的article元素 */
article:not(:has(img)) { }</code>

让我们对用户友好一些,并在链接后面添加一个隐藏在屏幕阅读器中的类:

<img src="/static/imghwm/default1.png" data-src="https://img.php.cn/" class="lazy" alt="Creating Animated, Clickable Cards With the :has() Relational Pseudo Class "><div clas="article-body">
    <h2>Some Heading</h2>
    <p>Curabitur convallis ac quam vitae laoreet. Nulla mauris ante, euismod sed lacus sit amet, congue bibendum eros. Etiam mattis lobortis porta. Vestibulum ultrices iaculis enim imperdiet egestas.</p>
    <a href="https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15b">
      Read more
       <svg fill="currentColor" viewbox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M12.293 5.293a1 1 0 011.414 0l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414-1.414L14.586 11H3a1 1 0 110-2h11.586l-2.293-2.293a1 1 0 010-1.414z" fill-rule="evenodd"></path></svg></a>
  </div>

我们的卡片开始看起来很漂亮了。是时候为它添加一些魔法了。使用:has()伪类,我们现在可以检查我们的链接是否处于悬停或聚焦状态,然后更新我们的自定义属性并添加box-shadow。使用这少量CSS代码,我们的卡片真正栩栩如生:

/* 卡片元素 */
article {
  --img-scale: 1.001;
  --title-color: black;
  --link-icon-translate: -20px;
  --link-icon-opacity: 0;

  position: relative;
  border-radius: 16px;
  box-shadow: none;
  background: https://www.php.cn/link/93ac0c50dd620dc7b88e5fe05c70e15bfff;
  transform-origin: center;
  transition: all 0.4s ease-in-out;
  overflow: hidden;
}
/* 链接的::after伪元素 */
article a::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline: 0;
  cursor: pointer;
}

看到上面的内容了吗?现在,如果卡片中的任何子元素处于悬停或聚焦状态,我们都会获得更新的样式。即使链接元素是唯一可以在::after可点击卡片方法中包含悬停或聚焦状态的元素,我们也可以使用它来匹配父元素并应用转换。

就是这样。:has()选择器的另一个强大的用例。我们不仅可以通过声明其他元素作为参数来匹配父元素,还可以使用伪类来匹配和设置父元素的样式。

优点:

  • 可访问的
  • 可设置动画
  • 不需要JavaScript
  • 在正确的元素上使用:hover

缺点:

  • 文本不容易选择。
  • 浏览器支持仅限于Chrome和Safari(在Firefox中,它在标志后面受支持)。

这是一个使用此技术的演示。您可能会注意到卡片周围有一个额外的包装器,但这只是我在使用容器查询时进行的一些尝试,这只是所有主要浏览器中正在推出的其他一些很棒的功能之一。

您是否有一些其他示例想要分享?评论部分非常欢迎其他解决方案或想法。

以上是使用:has()关系伪类创建动画,可点击的卡的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
上一篇:Is There Too Much CSS Now?下一篇:暂无