CSS には、子要素に基づいて親要素を直接選択する方法がないことが知られています。これは、長年にわたってデベロッパーからリクエストの多かった機能です。:has()
セレクタは、すべての主要ブラウザでサポートされており、この問題を解決します。:has()
より前は、長いセレクタを連結したり、スタイル設定フック用のクラスを追加したりすることがよくありました。これで、要素とその子孫の関係に基づいてスタイルを設定できるようになりました。:has()
セレクタについて詳しくは、CSS Wrapped 2023 と すべてのフロントエンド デベロッパーが知っておくべき 5 つの CSS スニペットをご覧ください。
このセレクタは小さいように見えますが、さまざまなユースケースを実現できます。この記事では、e コマース企業が :has()
セレクタで実現したユースケースをいくつか紹介します。
:has()
はベースラインの新規リリースの一部です。
この記事は、e コマース企業が新しい CSS と UI の機能を使用してウェブサイトを強化した方法について説明するシリーズ全体の一部です。
Policybazaar
:has()
セレクタにより、ユーザーの選択に対する JavaScript ベースの検証を排除し、以前と同じエクスペリエンスでシームレスに動作する CSS ソリューションに置き換えることができました。Aman Soni、Tech Lead、Policybazaar
Policybazaar の投資チームは、:has()
セレクタを巧みに適用して、プランを比較しているユーザーに明確な視覚的な指示を提供しています。次の図は、比較 UI 内の 2 種類のプラン(黄色と青)を示しています。各プランは、そのプランのタイプとのみ比較できます。:has()
を使用すると、ユーザーが 1 つのプランタイプを選択すると、他のプランタイプを選択できなくなります。
コード
: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()
を使用して質問のチェックボックスのステータスを確認し、質問に回答されたかどうかを確認します。選択されている場合は、アニメーションが適用され、次の質問に移行します。
コード
プランの比較の例では、: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 オーバーレイが追加されます。ここでは、すべてのサムネイルに適用される包括的な .thumbnailWrapper
クラス内の &
ネスト セレクタとともに、:has() セレクタが使用されています。これにより、モジュラー化され読みやすい CSS が作成されます。
コード
次のコードでは、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 Wrapped 2023
- :has(): ファミリー セレクタ
- デモ :has()
- バグの報告と新機能のリクエストのどちらをご希望ですか?皆様のご意見をお聞かせください。
スクロール ドリブンのアニメーション、ビュー遷移、ポップオーバー、コンテナ クエリなど、新しい CSS と UI 機能を使用して、e コマース企業がどのようにメリットを得たかについて、このシリーズの他の記事をご覧ください。