众所周知,CSS 缺乏直接根据子元素选择父元素的方法。多年来,这一直是开发者最迫切的要求。现在所有主流浏览器都支持 :has()
选择器,可以解决此问题。在 :has()
之前,您通常需要链接长选择器或添加样式钩子的类。现在,您可以根据元素与其后代的关系来设置样式。如需详细了解 :has()
选择器,请参阅 CSS Wrapped 2023 和每位前端开发者都应知道的 5 个 CSS 代码段。
虽然此选择器看起来很小,但可以实现大量的用例。本文介绍了电子商务公司使用 :has()
选择器解锁的一些用例。
:has()
是新推出的基准的一部分。
查看本文所属的完整系列文章,其中探讨了电子商务公司如何使用新的 CSS 和界面功能增强其网站。
政策集市
借助
:has()
选择器,我们能够避免基于 JavaScript 的用户选择验证,代之以一个 CSS 解决方案,这种解决方案可为我们顺畅运行,且体验与以前相同。- Aman Soni,Policybazaar 技术主管
Policybazaar 的投资团队巧妙应用了 :has()
选择器,为正在比较方案的用户提供清晰的视觉指示。下图显示了比较界面中的两种方案(黄色和蓝色)。每个方案只能与其自己的类型进行比较。使用 :has()
时,当用户选择其中一种方案时,无法选择另一种方案。
: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 的 health 团队实现了一个略有不同的用例。它们为用户提供了内嵌测验,并使用 :has()
检查问题复选框状态,看看问题是否已回答。如果是,则会应用动画过渡到下一个问题。
代码
在方案比较示例中,: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。
![Tokopedia 页面的屏幕截图,使用“has”选择器前后。](https://developer.chrome.google.cn/static/blog/css-ui-ecommerce-has/image/has-before-after.png?authuser=6&hl=ro)
: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() 族选择器。
资源:
- 2023 年 CSS 封装
- :has():系列选择器
- 演示 :has()
- 要报告 bug 或请求新功能吗?我们期待收到您的反馈意见!
请浏览本系列中的其他文章,探讨电子商务公司如何利用新的 CSS 和界面功能(如滚动驱动的动画、视图过渡、弹出式窗口和容器查询)获益。