Per introdurre i livelli della cascata nel CSS esistente, decidi innanzitutto a quale livello appartengono le vecchie regole. Le regole normali non inserite in un livello prevalgono su tutti i livelli con nome; quindi, i nuovi override inseriti nei livelli funzioneranno solo dopo aver spostato le regole legacy in conflitto in un livello con priorità inferiore.

Questa guida è pensata per chi modifica una pagina web di cui ha scritto il codice su un Mac e la controlla in un browser desktop. L’obiettivo concreto è collocare un foglio di stile esistente al di sotto dei nuovi stili dei componenti, mantenendo un percorso di migrazione comprensibile. Gli esempi usano file locali, etichette fittizie e una struttura CSS semplice.

Perché i nuovi stili inseriti nei livelli perdono contro le regole esistenti?

Quando dichiarazioni normali in fogli di stile dell’autore entrano in conflitto, il CSS non inserito in un livello ha la precedenza sul CSS contenuto in qualsiasi livello esplicito. Un selettore più specifico o una posizione successiva all’interno di un livello non può superare questo limite. La specifica CSS illustra questo comportamento con una regola non inserita in un livello che prevale su una regola inserita in un livello e più specifica. CSS Cascading and Inheritance Level 5.

Considera questo frammento CSS, che seleziona un elemento con la classe tile:

.tile {
  background-color: #b8bdc5;
}

@layer components {
  .tile {
    background-color: #246a73;
  }
}

Lo sfondo resta grigio. Assegnare al livello il nome overrides, spostare il suo blocco più avanti nel file o aumentare la specificità del suo selettore non cambia la precedenza della regola normale non inserita in un livello. I nomi dei livelli non hanno un significato predefinito: il loro ordine di dichiarazione stabilisce la relazione tra loro. MDN: livelli della cascata.

La tabella decisionale seguente presuppone dichiarazioni concorrenti nei fogli di stile dello stesso contesto e della stessa origine autore, senza stili inline, animazioni o transizioni che influiscano sulla proprietà. Leggi ogni riga dal livello di precedenza più basso a quello più alto.

Tipo di dichiarazione Precedenza dal livello più basso → al più alto
Normale Primo livello dichiarato → livelli dichiarati successivamente → regole non inserite in un livello
!important Regole non inserite in un livello → livelli dichiarati successivamente → primo livello dichiarato

La precedenza dei livelli viene risolta prima della specificità dei selettori. All’interno del livello vincente, la specificità continua a contare; l’ordine nel sorgente può risolvere dichiarazioni altrimenti alla pari. L’inversione per le dichiarazioni importanti implica che la migrazione debba considerare separatamente le regole normali e quelle importanti. MDN: livelli della cascata.

Quale confine di migrazione dovresti scegliere?

Inizia con un elemento e una proprietà che il nuovo CSS deve controllare. Esamina la dichiarazione attualmente vincente, individua il foglio di stile a cui appartiene e decidi se puoi modificare quel file o il modo in cui la pagina lo carica. In questo modo stabilisci il confine di migrazione minimo utile.

La tua situazione Prossimo passo pratico Conseguenza
Il CSS esistente deve mantenere la precedenza Lascialo non inserito in un livello e aggiungi valori predefiniti con priorità inferiore nei livelli I nuovi livelli forniscono valori quando non entrano in conflitto con regole più forti
Puoi modificare il CSS esistente Inserisci le regole legacy idonee in @layer legacy I livelli successivi possono sovrascrivere le dichiarazioni normali legacy
Puoi modificare il punto di ingresso del foglio di stile Importa il file esistente con layer(legacy) Il foglio di stile importato entra in quel livello senza riscriverne i selettori
Non puoi modificare il CSS legacy in conflitto né il modo in cui viene caricato Mantieni temporaneamente non inserito in un livello l’override necessario Dovrai comunque risolvere la specificità e gli altri fattori della cascata

Queste opzioni corrispondono ai tre meccanismi dei livelli documentati da CSS: una dichiarazione stabilisce i nomi dei livelli, un blocco assegna le regole a un livello e un import con livello assegna un foglio di stile importato a un livello. Una dichiarazione, da sola, non sposta le regole esistenti. CSS Cascading and Inheritance Level 5: dichiarazione dei livelli della cascata.

Per un foglio di stile piccolo, può essere comodo racchiudere le regole ordinarie in un blocco. Per un file esterno esistente, un import con livello crea un confine chiaro. Non inserire le regole @import esistenti all’interno di un blocco @layer: gli import sono regole di primo livello con vincoli di posizionamento. MDN: @import.

La migrazione consigliata di seguito importa il file legacy in un livello con nome. Questo ne modifica la precedenza rispetto agli altri fogli di stile, quindi controlla gli altri CSS caricati prima di applicare la stessa modifica al di fuori della pagina di esempio.

Come creare un esempio locale completo su Mac?

Crea una cartella contenente i tre file di testo semplice seguenti. Usa un editor di codice e mantieni le estensioni .html e .css. I file non richiedono pacchetti, script, font o risorse scaricate. I loro nomi identificano risorse di esempio locali.

Salva questo documento completo come sample.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Layer sample</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main id="sample">
    <h1>Shape sample</h1>
    <p>Tile A</p>
    <div class="tile" aria-label="Sample shape"></div>
  </main>
</body>
</html>

Il documento contiene un collegamento solo a styles.css. L’HTML usa rel="stylesheet" e href per associare il foglio di stile esterno alla pagina. Lo standard HTML attuale non definisce un attributo layer per l’elemento link; assegna la risorsa a un livello tramite CSS. HTML Standard: l’elemento link.

Salva questo foglio di stile completo come legacy.css. Rappresenta regole esistenti i cui selettori restano invariati:

body {
  margin: 2rem;
  font-family: system-ui, sans-serif;
  color: #26313a;
  background-color: #f4f5f7;
}

#sample .tile {
  width: 6rem;
  height: 6rem;
  background-color: #b8bdc5;
  border-radius: 0;
}

Salva questo foglio di stile di ingresso completo come styles.css:

@layer legacy, components;
@import url("legacy.css") layer(legacy);

@layer components {
  .tile {
    background-color: #246a73;
    border-radius: 50%;
  }
}

Apri sample.html in una versione attuale di Safari o Firefox per desktop. Il risultato atteso è un cerchio color petrolio sotto l’etichetta Tile A. Il livello legacy fornisce le dimensioni, mentre il livello components, dichiarato successivamente, fornisce lo sfondo e la forma arrotondata. Il suo selettore di una sola classe prevale sul selettore ID legacy perché le dichiarazioni competono tra livelli. MDN: @layer.

Il file di ingresso stabilisce prima l’ordine dei livelli, mantiene l’import prima del blocco e poi aggiunge le regole dei componenti. Questo rispetta la sintassi e i vincoli di posizionamento documentati per gli import. Una dichiarazione di livello può precedere gli import; un blocco di livello no. MDN: @import.

Cosa dovresti modificare in una pagina esistente?

Quando adotti questa struttura, sostituisci il riferimento diretto al foglio di stile della pagina con il nuovo foglio di stile di ingresso. Se la pagina carica ancora direttamente legacy.css oltre a importarlo in un livello, il caricamento diretto fornisce dichiarazioni non inserite in un livello che possono vanificare la migrazione.

Usa l’esempio per prevedere il problema: aggiungi un collegamento separato e diretto al foglio di stile legacy.css; le sue dichiarazioni normali possono ripristinare il quadrato grigio. Rimuovendo il caricamento diretto, le regole legacy restano nel livello previsto. Questa previsione segue l’ordine definito dalla specifica per la precedenza normale, in cui le regole non inserite in un livello seguono i livelli espliciti. CSS Cascading and Inheritance Module Level 5: ordine dei livelli.

Per questo esempio, tieni insieme tutti e tre i file. Quando adatti l’approccio, conserva le condizioni esistenti delle risorse, come le restrizioni per i media, e verifica che ogni foglio di stile referenziato venga caricato prima di diagnosticare un conflitto nella cascata.

Come verificare la migrazione in Firefox su macOS?

Apri gli strumenti per sviluppatori di Firefox con Command–Option–I e seleziona Inspector. Seleziona la forma di esempio nell’albero del documento, poi esamina la vista Rules. Mozilla documenta la scorciatoia degli strumenti per Mac e i comandi di ispezione CSS di Inspector. Tutte le scorciatoie da tastiera, Esaminare e modificare il CSS.

Controlla l’esempio una proprietà alla volta:

  1. Individua background-color. La dichiarazione del componente dovrebbe prevalere sul valore grigio legacy.
  2. Individua border-radius. Il valore del componente dovrebbe creare il cerchio.
  3. Controlla width e height. I relativi valori dovrebbero provenire ancora dal file legacy.
  4. Disattiva temporaneamente la dichiarazione dello sfondo del componente. Il grigio legacy dovrebbe diventare visibile mentre la forma resta arrotondata.

Firefox barra le dichiarazioni sovrascritte e offre caselle di controllo per disattivarle temporaneamente. Inoltre, collega le regole ai file sorgente. Usa questi controlli per individuare la dichiarazione in conflitto, invece di attribuire ogni risultato imprevisto a un problema di selettore. Mozilla: Esaminare e modificare il CSS.

Per una pagina reale, ripeti il controllo per gli stati che hai modificato: finestre più strette, condizioni media pertinenti e varianti dei componenti. Salva le modifiche definitive nei file sorgente e ricarica la pagina; le modifiche temporanee nell’inspector sono utili per la diagnosi.

Cosa può cambiare in modo imprevisto durante la migrazione?

Le dichiarazioni importanti invertono l’ordine previsto

Con @layer legacy, components, una dichiarazione importante in legacy prevale su una dichiarazione importante concorrente in components. Spostare le regole legacy importanti in un livello iniziale può quindi renderle più difficili da sovrascrivere. Tutte le dichiarazioni importanti dei fogli di stile inserite nei livelli prevalgono anche sulle dichiarazioni importanti concorrenti dei fogli di stile non inserite in un livello nella stessa origine autore e nello stesso contesto. MDN: @layer.

Prima di spostare un file, cercavi !important e controlla ogni conflitto pertinente. Se controlli entrambe le dichiarazioni, stabilisci se l’importanza è ancora necessaria dopo aver introdotto i livelli. Non aggiungere l’importanza a ogni nuova regola dei componenti: così cambieresti il sistema di precedenza utilizzato.

Gli stili inline richiedono un’attenzione specifica. Gli stili inline normali prevalgono sulle normali regole dei fogli di stile dell’autore e gli stili inline importanti prevalgono sulle altre dichiarazioni importanti dell’autore. Spostare un foglio di stile in un livello non sposta l’attributo di stile di un elemento. MDN: introduzione alla cascata CSS.

Una dichiarazione successiva non può riordinare i livelli esistenti

L’ordine dei livelli dipende dalla loro prima dichiarazione. Riaprire un livello con nome aggiunge regole senza spostarlo. Stabilisci l’ordine previsto prima che la pagina crei per la prima volta quei livelli, anche tramite fogli di stile importati. CSS Cascading and Inheritance Module Level 5.

Per una migrazione graduale, mantieni breve ed esplicito l’ordine iniziale. Sposta un gruppo coerente di regole, controlla le dichiarazioni vincenti e poi prosegui. Spostare una regola lasciando in giro una copia concorrente non inserita in un livello di solito mantiene proprio il confine di precedenza che volevi eliminare.

Quali limiti del supporto dei browser contano su Mac?

MDN indica che @layer è ampiamente disponibile nei browser da marzo 2022. WebKit documenta il supporto dei livelli della cascata in Safari 15.4. Queste date descrivono la disponibilità della funzionalità; non garantiscono che ogni Mac abbia installato un browser compatibile. Controlla le versioni effettivamente richieste dalla tua pagina. MDN: @layer, WebKit: nuove funzionalità di WebKit in Safari 15.4.

Un browser che non riconosce un blocco di livello non applica gli stili contenuti come normali regole non inserite in un livello. La sintassi non supportata viene scartata secondo le regole di parsing CSS. Di conseguenza, racchiudere tutto il CSS essenziale nei livelli non è una soluzione alternativa per i browser meno recenti. MDN: gestione degli errori CSS.

Se quei browser restano tra i requisiti, mantieni un foglio di stile deliberatamente non inserito in un livello per il percorso supportato e risolvi i conflitti con i selettori e l’ordine nel sorgente. Evita di caricare una copia non inserita in un livello insieme alla versione con livelli nei browser compatibili: cambierebbe la cascata appena progettata.

Inizia con la migrazione più piccola che consente al nuovo componente di controllare le proprietà previste. Stabilisci l’ordine dei livelli, assegna a un livello le regole legacy in conflitto, rimuovi i caricamenti duplicati non inseriti in un livello e controlla quali dichiarazioni vincono. Questa sequenza rende visibile ogni cambiamento di precedenza prima di migrare altro CSS.

Fonti