CSS miste notoir een manier om een bovenliggend element direct te selecteren op basis van zijn onderliggende elementen. Dit was al jaren een veelgevraagde ontwikkeling. De :has()
:has()
selector, die nu door alle grote browsers wordt ondersteund, biedt hiervoor een oplossing. Voorheen koppelde je vaak lange selectoren aan elkaar of voegde je klassen toe voor stylinghooks. Nu kun je stylen op basis van de relatie van een element met zijn onderliggende elementen. Lees meer over de :has()
selector in CSS Wrapped 2023 en 5 CSS-fragmenten die elke frontendontwikkelaar zou moeten kennen .
Hoewel deze selector klein lijkt, kan hij een enorm aantal use cases mogelijk maken. Dit artikel laat een aantal use cases zien die e-commercebedrijven hebben ontgrendeld met de :has()
selector.
:has()
is onderdeel van Baseline Newly Available .
Bekijk de volledige serie waar dit artikel deel van uitmaakt, waarin wordt besproken hoe e-commercebedrijven hun websites hebben verbeterd met nieuwe CSS- en UI-functies.
Policybazaar
Met de
:has()
selector konden we de op JavaScript gebaseerde validatie van de selectie van de gebruiker elimineren en vervangen door een CSS-oplossing die naadloos voor ons werkt, met dezelfde ervaring als voorheen. — Aman Soni , Tech Lead, Policybazaar
Het beleggingsteam van Policybazaar heeft de selector :has()
slim toegepast om gebruikers die plannen vergelijken een duidelijke visuele indicatie te geven. De volgende afbeelding toont twee soorten plannen in de vergelijkingsinterface (geel en blauw). Elk plan kan alleen met zijn eigen type worden vergeleken. Door :has()
te gebruiken, kan een gebruiker, wanneer hij één type plan selecteert, het andere plantype niet selecteren.
:has()
om het bovenliggende element en zijn onderliggende elementen te stylen en zo een categorie-gebonden selectiefunctionaliteit te creëren. Code
:has()
geeft je toegang tot stijlelementen van bovenliggende elementen en hun onderliggende elementen. De volgende code controleert of een bovenliggende container een klasse .disabled-group
heeft. Zo ja, dan wordt de kaart grijs weergegeven en reageert de knop 'Toevoegen' niet op klikken door pointer-events
in te stellen op 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);
}
Het gezondheidsteam van Policybazaar implementeerde een iets andere use case. Ze hebben een inline quiz voor de gebruiker en gebruiken :has()
om de status van het selectievakje te controleren om te zien of de vraag is beantwoord. Zo ja, dan wordt er een animatie toegepast om naar de volgende vraag te gaan.
Code
In het voorbeeld van de planvergelijking werd :has()
gebruikt om de aanwezigheid van een klasse te controleren. Je kunt ook de status van een invoerelement, zoals een selectievakje, controleren met :has(input:checked)
. In de afbeelding van de quiz is elke vraag in de paarse banner een selectievakje. Policybazaar controleert of de vraag is beantwoord met :has(input:checked)
en activeert, indien dit het geval is, een animatie met animation: quesSlideOut 0.3s 0.3s linear forwards
om naar de volgende vraag te gaan. Zie hoe dit werkt in de volgende code.
.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 gebruikte :has()
om een overlay-afbeelding te maken als de productminiatuur een video bevatte. Als de productminiatuur een .playIcon
-klasse bevatte, werd een CSS-overlay toegevoegd. Hier werd de :has()-selector samen met de &
-nestingselector gebruikt binnen de overkoepelende .thumbnailWrapper
-klasse, die van toepassing was op alle miniaturen. Dit zorgde voor meer modulaire en leesbare CSS.

:has()
. Code
De volgende code gebruikt de CSS-selectors en -combinators ( &
en >
) en nesting met :has()
om de thumbnail te stylen. Voor browsers die deze niet ondersteunen, wordt de reguliere extra CSS-klasseregel als fallback gebruikt. De regel @supports selector(:has(*))
wordt ook gebruikt om te controleren op browserondersteuning. Daarom is de algehele ervaring in alle browserversies hetzelfde.
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;
}
}
`;
Waar u op moet letten bij het gebruik van :has()
Combineer :has()
met andere selectoren om een complexere voorwaarde te creëren. Bekijk enkele voorbeelden in has() van de familieselector .
Bronnen:
- CSS Wrapped 2023
- :has(): de familieselector
- Demo's :has()
- Wil je een bug melden of een nieuwe functie aanvragen? We horen graag van je !
Ontdek de andere artikelen in deze serie die gaan over hoe e-commercebedrijven profiteren van nieuwe CSS- en UI-functies zoals scroll-animaties, weergaveovergangen, popovers en containerquery's.