Tilbage til Fundamentals

3. semester / Tema 13C: Frontend Design

Cascade Layers i praksis

Forstå hvordan @layer giver mere forudsigelig CSS.

Se undervisningsslides

Relevante links

TL;DR

  1. @layer lader dig styre prioritet med en bevidst lag-rækkefølge.
  2. For normale deklarationer afgøres lagets prioritet før specificity.
  3. Deklarer helst lag-ordenen tidligt (up-front) i filen.
  4. Normale regler uden for layers vinder over normale regler i layers.
  5. Brug faste lag-navne på tværs af projektet, fx reset, global, components, utilities.

Hvorfor cascade layers?

I større CSS-kodebaser opstår der ofte “specificity wars”, hvor udviklere skriver mere og mere specifikke selectors for at få deres regler til at vinde.

I følgende eksempel kan du se, hvordan forskellige regler kæmper om at style det samme element:

/* Lav specificity, 0.0.1 */
input {
border: 1px solid gray;
}
/* Høj specificity, 0.1.1 */
input[type="text"] {
border: 2px solid red;
}
/* Endnu højere specificity, 0.2.2 */
form .input-wrapper input[type="text"] {
border: 3px solid green;
}

Du kan udregne effekten af en selector her: Specificity calculator

Med layers flytter du fokus fra selector-styrke til bevidst prioritering. Det giver færre “specificity wars” og mere forudsigelig styling.

Fra cascade til layer-tænkning

I stedet for at skrive tungere selectors for at “vinde”, kan du lægge regler i forskellige lag:

@layer reset, components;
@layer reset {
input[type="text"] {
border: 1px solid gray;
}
}
@layer components {
.my-input {
border: 4px solid blue;
}
}

Her kan en simpel klasse i components stadig vinde over en mere kompleks selector i reset, fordi lag-ordenen er deklareret.

Deklarer layer-order oppefra

Et godt mønster er at deklarere den samlede lag-rækkefølge først:

@layer reset, global, components, utilities;

For normale deklarationer har senere lag højere prioritet. Rækkefølgen fastlægges, når lagene først oprettes; at flytte en senere blok for et allerede oprettet lag ændrer ikke lagets prioritet. Det er især nyttigt, når flere filer og flere personer bidrager til samme CSS.

Et projekt-stack af layers

Vælg navne efter ansvar i projektet, og brug dem konsekvent. Et muligt udgangspunkt er:

@layer reset, global, components, utilities;

Layers i praksis

Du kan kombinere tildelingen af lag med imports af forskellige CSS-filer:

@layer reset, global, components, utilities;
@import "./reset.css" layer(reset);
@import "./utils.css" layer(utilities);

Det gør det let at holde struktur, selv når styles kommer fra flere filer.

Layers i Astro

Undersøg, hvordan komponentens scoped styles spiller sammen med de globale lag. Scope bestemmer, hvilke elementer reglen rammer; det fritager ikke deklarationen fra kaskaden.

Find en konkurrerende global regel og en komponentregel. Forklar, hvilket lag hver regel ligger i, før du ændrer dem.

En svag selector kan vinde

Gæt først, om en simpel a-selector kan vinde over den lange selector med flere id’er. Prøv derefter at placere reglerne i forskellige lag. Flyt kodeblokkene, mens den deklarerede lagrækkefølge bliver stående. Forklar, hvorfor resultatet er uændret.

Reset og spacing

I denne demo kan du se, hvordan en reset-regel i et lavere lag kan blive overtrumfet af en simpel klasse i et højere lag, uden at skulle skrive en mere specifik selector, hvilket gør styling mere forudsigeligt og nemmere at vedligeholde.

Åbn spacing-øvelsen uden steps. Find den regel, som forhindrer den ønskede afstand. Løs konflikten med lagenes ansvar frem for en længere selector eller !important.

Når regler ligger uden for layers

En normal deklaration uden for layers har højere prioritet end normale deklarationer i navngivne lag. Hvis et eksisterende projekt kun delvist bruger layers, er det derfor ikke nok at lægge en ny override i det sidste lag.

Prøv at flytte en af farvereglerne ud af laget i demoen. Gæt først, hvad det gør ved resultatet, og kontrollér i DevTools.

Med !important vendes rækkefølgen mellem lagene: vigtige deklarationer i tidligere lag prioriteres højere, og vigtige deklarationer i lag vinder over vigtige deklarationer uden for lag. Hold i første omgang øvelserne fri for !important, så du kan forklare den normale rækkefølge.

Specificity sammenlignes først efter blandt andet origin, importance og lagprioritet. “Den mest specifikke selector vinder” er derfor ikke en fuldstændig beskrivelse af kaskaden. Se MDN om layers.