Er komen cascadelagen naar uw browser

Cascadelagen (de @layer CSS-regel ) komen naar Chromium 99, Firefox 97 en Safari 15.4 Bèta. Ze maken een explicietere controle over uw CSS-bestanden mogelijk om stijlspecifieke conflicten te voorkomen. Dit is vooral handig voor grote codebases, ontwerpsystemen en bij het beheren van stijlen van derden in applicaties.

Door uw CSS op een duidelijke manier in lagen te plaatsen, voorkomt u onverwachte stijloverschrijvingen en bevordert u een betere CSS-architectuur.

CSS-specificiteit en de cascade

CSS-specificiteit is hoe CSS beslist welke stijlen op welke elementen moeten worden toegepast. De verschillende selectors die u kunt gebruiken, bepalen de specificiteit van elke stijlregel. Elementen zijn bijvoorbeeld minder specifiek dan klassen of attributen, die op hun beurt minder specifiek zijn dan ID's. Dit is een essentieel onderdeel van het leren van CSS.

Mensen wenden zich tot CSS-naamgevingsconventies zoals BEM om te voorkomen dat de specificiteit onbedoeld wordt overschreven. Door alles een enkele klassenaam te geven, wordt alles op hetzelfde specificiteitsvlak geplaatst. Het is echter niet altijd mogelijk om zulke georganiseerde stijlen te behouden, vooral niet als je werkt met code en ontwerpsystemen van derden.

BEM-visual van een kaart met klassen
Een geïllustreerd voorbeeld van BEM-naamgeving van Keepuptodate.com.

Cascadelagen zijn bedoeld om dit probleem op te lossen. Ze introduceren een nieuwe laag in de CSS- cascade . Bij gelaagde stijlen is de prioriteit van een laag altijd belangrijker dan de specificiteit van een selector .

De selector .post a.link heeft bijvoorbeeld een hogere specificiteit dan .card a . Als u probeert een link in een kaart of in een bericht op te maken, zult u merken dat de specifiekere selector wordt toegepast.

Door @layer te gebruiken, kunt u explicieter zijn over de stijlspecificiteit van elke stijl, en ervoor zorgen dat de stijlen van uw kaartlink de stijlen van de postlink overschrijven, ook al zou de specificiteit numeriek lager kunnen zijn als al uw CSS zich op hetzelfde vlak bevond. Dit komt door de cascadevoorrang. Gelaagde stijlen creëren nieuwe cascade-"vlakken".

Illustratie uit een projectdemo van de uitbraak van de gebruikersinterface

@layer in actie

Demo met linkkleuren bij import
Zie demo op Codepen.

Dit voorbeeld toont de kracht van cascadelagen, met behulp van @layer . Er worden verschillende links getoond: sommige zonder dat er extra klassenamen zijn toegepast, één met een .link klasse en één met een .pink -klasse. De CSS voegt vervolgens drie lagen toe: base , typography en utilities , als volgt:

@layer base {
  a {
    font-weight: 800;
    color: red; /* ignored */
  }

  .link {
    color: blue; /* ignored */
  }
}

@layer typography {
  a {
    color: green; /* styles *all* links */
  }
}

@layer utilities {
  .pink {
    color: hotpink;  /* styles *all* .pink's */
  }
}

Uiteindelijk zijn alle schakels groen of roze. Dit komt omdat: hoewel .link een hogere specificiteit op selectorniveau heeft dan a , er een kleurstijl is op a in een @layer met hogere prioriteit. a { color: green } overschrijft .link { color: blue } wanneer de groene regel zich in een laag na de blauwe regel bevindt.

De prioriteit van de laag overtreft de specificiteit van het element.

Lagen organiseren

U kunt lagen rechtstreeks op de pagina ordenen, zoals hierboven weergegeven, of u kunt ze bovenaan een bestand ordenen.

De laagvolgorde wordt bepaald wanneer elke laagnaam voor het eerst in uw code verschijnt.

Dat betekent dat als u het volgende bovenaan het bestand toevoegt, de links allemaal rood verschijnen, en de link met class .link blauw:

@layer utilities, typography, base;

Dit komt omdat de volgorde van de lagen nu is omgekeerd, waarbij de hulpprogramma's op de eerste plaats komen te staan ​​en de basis op de laatste plaats. De stijlregels in de base zullen dus altijd een hogere specificiteit hebben dan de stijlregels in de typografielaag. Het worden geen groene schakels meer, maar rode of blauwe.

Screenshot van het Codepen-project
Zie demo op Codepen.

Het organiseren van import

Een andere manier om @layer te gebruiken is met importbestanden. U kunt dit rechtstreeks doen wanneer u stijlen importeert, met behulp van een layer() functie, zoals in het volgende voorbeeld:

/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */

/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */

/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */

Het bovenstaande codefragment heeft drie lagen: base , layouts en components . De normalisatie-, thema- en typografiebestanden in base , met een post in layouts , en cards en footer beide in components . Bij het importeren van het bestand worden de lagen geïnstantieerd met behulp van de laagfunctie. Een alternatieve aanpak zou zijn om uw lagen bovenaan het bestand te ordenen en ze vóór elke import te declareren:

@layer base,
       theme,
       layouts,
       components,
       utilities;

De volgorde waarin u uw stijlen @import , is niet van belang voor de laagvolgorde, omdat deze al is vastgelegd bij de eerste instantie van de laagnaam. Dat is een zorg minder. U kunt geïmporteerde bestanden nog steeds op specifieke lagen instellen, maar de volgorde is al vastgelegd.

Screenshot van het Codepen-project
Ontdek het project op Codepen.

Lagen en de cascade

Laten we een stap terug doen en kijken waar lagen worden gebruikt in relatie tot de bredere cascade:

Cascade-illustratie

De volgorde van prioriteit is als volgt:

  • User Agent normaal (laagste prioriteit)
  • Lokale gebruiker @layer
  • Lokale gebruiker normaal
  • Auteur @lagen
  • Auteur normaal
  • Auteur !belangrijk
  • Auteur @layer !belangrijk
  • Lokale gebruiker!belangrijk
  • User Agent !belangrijk** (hoogste prioriteit)

Het zal je hier misschien opvallen dat @layer !important -stijlen zijn omgekeerd. In plaats van minder specifiek te zijn dan niet-gelaagde (normale) stijlen, hebben ze een hogere prioriteit. Dit komt door de manier waarop !important werkt in de cascade: het verbreekt de normale cascadering in uw stylesheets en keert de normale specificiteit op laagniveau om (voorrang).

Geneste lagen

Lagen kunnen ook in andere lagen worden genest. Het volgende voorbeeld komt uit de Cascade Layers-uitleg van Miriam Suzanne:

@layer default {
  p { max-width: 70ch; }
}

@layer framework {
  @layer default {
    p { margin-block: 0.75em; }
  }

  p { margin-bottom: 1em; }
}

In het bovenstaande codefragment heeft u toegang tot framework.default met behulp van een . als een betekenaar van de default die binnen framework is genest. Je kunt dit ook in een beknopter formaat schrijven:

@layer framework.default {
  p { margin-block: 0.75em }
}

De resulterende lagen en laagvolgorde zijn:

  • standaard
  • framework.default
  • framework ongelaagd
  • ongelaagd

Dingen om op te letten

Cascadelagen kunnen geweldig zijn als u ze op de juiste manier gebruikt, maar ze kunnen ook voor extra verwarring en onverwachte resultaten zorgen. Let op het volgende als u met cascadelagen werkt:

Regel 1: Gebruik @layer niet voor scoping

Cascadelagen lossen scoping niet op. Als je een CSS-bestand hebt met een @layer , zeg card.css en je wilt alle links binnen de kaart opmaken, schrijf dan geen stijlen zoals:

a {
  
}

Dit zal ertoe leiden dat alle a -tags in uw bestand deze overschrijving krijgen. Het is nog steeds belangrijk om uw stijlen goed te bepalen :

.card a {
  
}

Regel 2: cascadelagen worden geordend achter niet-gelaagde CSS

Het is belangrijk op te merken dat een gelaagd CSS-bestand niet-gelaagde CSS niet zal overschrijven. Dit was een opzettelijke beslissing om het gemakkelijker te maken om lagen op een verstandigere manier te introduceren om met uw bestaande codebase te werken. Het gebruik van een reset.css bestand is bijvoorbeeld een goed startpunt en gebruiksscenario voor cascadelagen.

Regel 3: !important keert de cascadespecificiteit om

Hoewel gelaagde stijlen in het algemeen minder specifiek zijn dan niet-gelaagde stijlen, wordt dit met !important omgekeerd. In een laag zijn declaraties met de regel !important specifieker dan niet-gelaagde stijlen.

In dat geval keren de !important stijlen hun specificiteit om. Het diagram hierboven laat dit ter referentie zien: auteur @lagen hebben minder prioriteit dan auteur normaal, die minder prioriteit hebben dan auteur !belangrijk en die minder prioriteit hebben dan auteur @laag !belangrijk.

Als je meerdere lagen hebt, krijgt de eerste laag met !important de prioriteit !important en is deze de meest specifieke stijl.

Regel 4: Begrijp injectiepunten

Omdat de laagvolgorde wordt bepaald wanneer elke laagnaam voor het eerst in uw code verschijnt, kunt u deze negeren als u een @layer -declaratie plaatst na het importeren en instellen layer() 's, of na een andere @layer -instructie. Anders dan in CSS, waar de stijlregel het verst naar beneden op de pagina wordt toegepast voor cascadelagen, wordt de volgorde in eerste instantie bepaald.

Dit kan in een lijst, in een laagblok of in een import zijn. Als je @layer na een importlijst met layer() plaatst, zal er niets gebeuren. Als u het bovenaan het bestand plaatst, wordt de laagvolgorde ingesteld en kunt u de lagen binnen de architectuur duidelijk zien.

Regel #5: let op uw specificiteit

Met cascadelagen zal een minder specifieke selector (zoals a ) een meer specifieke selector (zoals .link ) overschrijven als die minder specifieke selector zich op een specifiekere laag bevindt. Overweeg het volgende:

a in layer(components) zou .pink in layer(utilities) overschrijven als: @layer utilities, components waren opgegeven. Hoewel dit een opzettelijk onderdeel van de API is, kan dit verwarrend en frustrerend zijn als je het niet verwacht.

Dus als u hulpprogrammaklassen schrijft, neem deze dan altijd op als een laag van hogere orde dan de componenten waarmee u ze wilt overschrijven. Je zou kunnen denken: "Ik heb zojuist deze .pink -klasse toegevoegd om de kleur te veranderen, maar deze wordt niet toegepast".

Meer informatie over cascadelagen

U kunt ook deze bronnen raadplegen voor meer informatie over cascadelagen: