:has() 案例研究

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

众所周知,CSS 一直没有办法根据 子项。多年来,这是开发者们呼声最高的功能。通过 现在,所有主流浏览器都支持 :has() 选择器,它可以解决此问题。之前 :has() 时,您通常需要链接较长的选择器或添加用于样式钩子的类。现在 您可以根据元素与其后代的关系来设置样式。了解详情 :has()选择器 CSS Wrapped 2023每个前端开发者都应该知道的 5 个 CSS 代码段

虽然此选择器看起来很小,但实际上却能支持大量应用场景。 本文介绍了电子商务公司使用 :has() 选择器。

:has()基准新发布的计划的一部分。

浏览器支持

  • Chrome:105。 <ph type="x-smartling-placeholder">
  • 边缘:105。 <ph type="x-smartling-placeholder">
  • Firefox:121。 <ph type="x-smartling-placeholder">
  • Safari:15.4. <ph type="x-smartling-placeholder">

来源

请参阅完整系列,其中介绍了 电子商务公司利用新的 CSS 和界面功能增强其网站。

政策集市

利用 :has() 选择器,我们得以消除基于 JavaScript 的验证 并替换为有效的 CSS 解决方案 提供与之前一样的体验。—Aman Soni,Policybazaar 技术主管

Policybazaar 的投资团队巧妙运用了 :has() 选择器, 为正在比较方案的用户提供清晰直观的指示下图 在比较界面中显示了两种方案(黄色和蓝色)。每个方案 只能与它自己的类型进行比较。使用 :has(),当用户选择一个项目时 方案类型,但无法选择另一方案类型。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
实现 :has() 以设置要创建的父元素及其子元素的样式 一种类别绑定选择功能。

代码

借助 :has(),您可以访问样式父元素及其子元素。通过 以下代码会检查父级容器是否设置了 .disabled-group 类。 如果是这样,该卡片就会灰显,并且“添加”选项按钮从 通过将 pointer-events 设置为 none 来响应点击。

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

Policybazaar 的健康团队已实施 略有不同。他们提供了内联测验供用户使用 :has(),查看题目的复选框状态,看看题目是否被 回答了这个问题。如果正确,系统会应用一个动画来过渡到下一个问题。

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
health.policybazaar.com/

代码

在方案比较示例中,:has() 用于检查是否存在 类。您还可以使用 :has(input:checked)。在显示测验的图片中, 紫色横幅是一个复选框Policybazaar 会核实相应问题 已使用 :has(input:checked) 回答;如果有,则使用以下代码触发动画: animation: quesSlideOut 0.3s 0.3s linear forwards即可滑动到下一项 问题。请查看以下代码,了解其工作原理。

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Tokopedia

Tokopedia 使用 :has() 创建了一张叠加层图片,如果图片显示商品缩略图, 包含视频。如果商品缩略图包含 .playIcon 类,则 CSS 提供商为 叠加层。在本例中,:has() 选择器与 & 结合使用 嵌套选择器,位于总体的 .thumbnailWrapper 类中,这适用于 所有缩略图这可以创建更模块化、更易读的 CSS。

<ph type="x-smartling-placeholder">
</ph> 使用 has 选择器前后的 Tokopedia 页面屏幕截图。
使用 :has() 前后。

代码

以下代码使用 CSS 选择器和组合器&>),并通过嵌套 :has() 设置缩略图的样式。 对于不支持 则使用常规的其他 CSS 类规则作为后备。通过 @supports selector(:has(*)) 规则还可用于检查浏览器是否支持。 因此,不同浏览器版本的整体体验是相同的。

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

使用 :has() 时的注意事项

:has() 与其他选择器结合使用可以创建更复杂的条件。查看 在 has() 家庭选择器中给出了一些示例。

资源:

请浏览本系列中的其他文章,这些文章介绍了 公司受益于新推出的 CSS 和界面功能,例如滚动驱动型 动画、视图转换、弹出式窗口和容器查询。