Imposta i valori predefiniti del testo della pagina su body, lascia che le proprietà ereditate si propaghino ai componenti e definisci deliberatamente le regole di layout. Questa guida mostra come creare e verificare una pagina HTML locale su un Mac senza costringere ogni elemento ad annullare una regola universale.
Perché una regola universale interferisce con i valori predefiniti dei componenti?
Il selettore universale * corrisponde a ogni elemento. Una dichiarazione all'interno di quella regola si applica quindi direttamente a ciascun elemento corrispondente; non fornisce semplicemente un valore che i discendenti possono ereditare. Inoltre, non corrisponde direttamente agli pseudo-elementi, per i quali servono selettori come *::before. Selettori universali.
Considera questo frammento CSS per un componente che contiene un paragrafo e uno span di testo annidato:
/* Illustrative fragment: assumes a .tile with text descendants. */
* {
color: #303840;
}
.tile {
color: #245d75;
}
La tessera riceve il colore del testo blu. Il paragrafo e lo span ricevono direttamente il colore scuro della regola universale. Il colore del componente non può propagarsi attraverso queste dichiarazioni tramite la normale ereditarietà. In base alle regole CSS per i valori predefiniti, le proprietà ereditate assumono il valore calcolato del genitore quando la cascata non fornisce alcun valore per quella proprietà sull'elemento. CSS Cascading and Inheritance Level 4, valori predefiniti.
Questo può creare confusione perché * ha specificità zero. La specificità confronta le dichiarazioni in conflitto sullo stesso elemento, all'interno dell'origine e del livello della cascata applicabili. Una dichiarazione su un genitore non è un selettore corrispondente al suo elemento figlio. Rendere più specifico il selettore del genitore, quindi, non risolve questo problema di ereditarietà. Specificità.
La modifica utile consiste nel rimuovere la dichiarazione universale sul testo e impostare il valore predefinito su body. I discendenti potranno così ereditarlo finché un componente o un elemento non specifica un altro valore. MDN identifica color come proprietà ereditata e spiega che l'ereditarietà segue il valore calcolato del genitore. Ereditarietà.
Quali valori predefiniti appartengono alla pagina, a un componente o a ogni elemento?
Prima di scrivere un selettore ampio, decidi se la proprietà deve propagarsi lungo una gerarchia di testo, descrivere un singolo riquadro o stabilire una regola intenzionale per tutti i riquadri. La seguente guida decisionale applica questa distinzione a una piccola pagina creata da zero.
| Risultato desiderato | Posizione consigliata | Motivo |
|---|---|---|
| Il testo normale della pagina condivide colore e tipografia di base | body |
Fornisce al testo una base comune tramite l'ereditarietà |
| Una tessera e il suo testo normale condividono un colore diverso | .tile |
Stabilisce un nuovo valore ereditabile all'interno del componente |
| Una singola didascalia ha un colore diverso | .caption |
Applica l'eccezione all'elemento che ne ha bisogno |
| Un pannello ha padding, un bordo o uno sfondo | La classe del pannello | Mantiene la decorazione del riquadro associata al suo elemento |
| I riquadri usano un modello di dimensionamento coerente | Una regola box-sizing deliberata |
Stabilisce una convenzione di dimensionamento esplicita |
| I margini delle intestazioni hanno un valore predefinito facile da sostituire | Un selettore specifico per le intestazioni, eventualmente racchiuso in :where() |
Limita il valore predefinito agli elementi previsti |
L'ereditarietà dipende dalla proprietà. Consulta la voce Inherited nel riferimento della proprietà, invece di presumere che ogni dichiarazione su body raggiunga i discendenti. Per esempio, i bordi non vengono ereditati per impostazione predefinita. Ereditarietà.
Una regola universale per il dimensionamento può comunque essere appropriata. Con border-box, la larghezza dichiarata di un elemento include il padding e il bordo; i margini restano al di fuori di tale larghezza. È una scelta specifica relativa al modello di riquadro, non un motivo per applicare universalmente tutti i valori predefiniti della pagina. box-sizing.
Crea una dimostrazione locale completa sul tuo Mac
Usa TextEdit in modalità testo semplice o un editor di codice già installato. In TextEdit, scegli File > New, poi Format > Make Plain Text. Incolla il documento completo qui sotto, scegli File > Save e chiamalo page-defaults.html. Se ti viene chiesto, scegli Use .html. Apple documenta questa procedura nella sua guida HTML di TextEdit.
Questo esempio usa etichette fittizie e forme disegnate con CSS. È un documento completo con un foglio di stile incorporato, quindi non occorre preparare altri file. Il codice è stato esaminato qui; il suo rendering non è stato eseguito in un browser su Mac.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Page defaults demonstration</title>
<style>
*, *::before, *::after {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
font-size: 1rem;
line-height: 1.5;
color: #303840;
background-color: #f4f5f6;
}
main {
max-width: 44rem;
margin: 0 auto;
padding: 2rem 1rem;
}
h1 {
line-height: 1.2;
}
.tile {
margin: 1.5rem 0;
padding: 1.25rem;
border: 2px solid currentColor;
border-radius: 0.75rem;
color: #245d75;
background-color: #ffffff;
}
.tile h2 {
margin-top: 0;
}
.shape {
width: 4rem;
height: 4rem;
background-color: currentColor;
}
.shape--round {
border-radius: 50%;
}
.caption {
color: #66523c;
}
</style>
</head>
<body>
<main>
<h1>Shape notes</h1>
<p>Page sample: <span>Label A</span>.</p>
<section class="tile">
<h2>Tile B</h2>
<div class="shape shape--round" aria-hidden="true"></div>
<p>Component sample: <span>Label C</span>.</p>
<p class="caption">Caption D has its own text color.</p>
</section>
<p>Page sample: <span>Label E</span>.</p>
</main>
</body>
</html>
Apri page-defaults.html nel browser. Quando riapri il sorgente in TextEdit, scegli TextEdit > Settings > Open and Save e attiva Display HTML files as HTML code instead of formatted text se vuoi che TextEdit mostri il markup in modo coerente. Lavorare con documenti HTML in TextEdit sul Mac.
Verifica il confine dell'ereditarietà con tre modifiche
Queste verifiche trasformano il documento in un piccolo esercizio diagnostico. Salva il sorgente e ricarica la pagina nel browser dopo ogni modifica. Conserva una copia del documento originale o annulla ogni modifica prima di provare la successiva.
- Modifica soltanto il colore
body. Impostalo su#4b465f. Il testo intorno a Label A e Label E dovrebbe cambiare. La tessera conserva il proprio colore. - Ripristina il colore della pagina, poi modifica soltanto
.tileimpostandolo sucolor: #526637. Il normale testo dell'intestazione e del paragrafo dovrebbe seguire questa modifica, compresa Label C. Caption D conserva il proprio colore esplicito. - Ripristina il colore della tessera, poi aggiungi temporaneamente
* { color: #303840; }all'inizio del foglio di stile. Il paragrafo che contiene Label C riceve ora quella dichiarazione diretta. Rimuovi la regola temporanea al termine.
Le verifiche illustrano la differenza tra un componente che stabilisce un valore ereditabile e un discendente che riceve una propria dichiarazione. Il comportamento previsto del testo segue le regole di ereditarietà e assegnazione dei valori predefiniti della specifica.
Qual è il rapporto tra la pagina HTML e il suo foglio di stile?
Tieni separati il caricamento delle risorse e il comportamento dei selettori. L'esempio incorpora il CSS in un elemento style. Se preferisci un foglio di stile separato, sposta solo il contenuto di quell'elemento in un file di testo semplice chiamato page-defaults.css, salvato nella stessa cartella del file HTML. Sostituisci l'intero elemento style con la seguente riga all'interno di head. È un frammento sostitutivo, non un altro documento completo.
<link rel="stylesheet" href="page-defaults.css">
Il tipo di collegamento stylesheet identifica una risorsa CSS esterna usata per presentare il documento. Il nome del file in href deve corrispondere al file che hai effettivamente salvato; la dichiarazione non crea quel file. Lo standard HTML definisce questa relazione in Tipo di collegamento: stylesheet.
Per questo esempio, il rapporto è semplice: l'HTML fornisce gli elementi e le classi, mentre il CSS ne definisce la presentazione. Se rinomini .tile nel foglio di stile, devi aggiornare la classe corrispondente nell'HTML. Se sposti il file CSS, devi aggiornare il riferimento alla risorsa. Nessuna delle due modifiche richiede un selettore più specifico.
Se la versione esterna appare senza stili, verifica prima che il file CSS esista con il nome previsto e che contenga CSS, non il documento HTML che lo circonda. Torna alla versione incorporata per isolare gli errori di caricamento delle risorse prima di modificare la cascata.
Quando dovresti usare :where() o i livelli della cascata?
Usa queste funzionalità quando risolvono un problema aggiuntivo. L'esempio completo qui sopra non dipende da nessuna delle due.
Usa :where() per valori predefiniti mirati con specificità zero
Supponiamo che la pagina includa più livelli di intestazione. Questo frammento di foglio di stile facoltativo stabilisce spaziature condivise e permette ai normali selettori delle intestazioni di sostituirle facilmente:
/* Optional fragment: add to the example stylesheet. */
:where(h1, h2, h3) {
margin-bottom: 0.75rem;
}
h2 {
margin-bottom: 1rem;
}
Il selettore completo :where() ha specificità zero, compresi i suoi argomenti. Ma sostituire * con :where(*) non risolve il precedente problema del colore: continua a corrispondere a ogni elemento e a fornirgli una dichiarazione diretta. Per risolvere quel problema, usa l'ereditarietà. MDN documenta :where() come ampiamente disponibile nei browser da gennaio 2021; consulta la tabella di compatibilità per il supporto dei browser meno recenti. La pseudo-classe :where().
Se un browser non supporta :where(), usa per queste impostazioni di spaziatura un normale elenco di selettori, come h1, h2, h3, poi inserisci le eccezioni con specificità uguale più avanti nello stesso foglio di stile e livello. In questo modo i valori predefiniti restano mirati, anche se la loro specificità non è più zero. Specificità.
Usa i livelli quando i gruppi di regole necessitano di un ordine esplicito
Per un foglio di stile più ampio, questo frammento facoltativo mostra un ordine di livelli dichiarato. È separato dall'esempio completo e non ne sostituisce l'intero CSS.
/* Optional fragment for browsers supporting cascade layers. */
@layer defaults, components;
@layer defaults {
p {
margin-bottom: 1rem;
}
}
@layer components {
.tile p {
margin-bottom: 0.5rem;
}
}
Per le dichiarazioni normali dell'autore, i livelli successivi hanno la precedenza su quelli precedenti; le dichiarazioni normali non appartenenti a un livello prevalgono su quelle nei livelli. Le dichiarazioni importanti invertono l'ordine dei livelli, quindi aggiungere !important cambia tale disposizione. I livelli organizzano le regole in conflitto; non fanno sì che un figlio con uno stile diretto erediti il valore del genitore. La regola at @layer.
MDN indica che @layer è disponibile nei principali browser da marzo 2022. Se il browser di destinazione è più vecchio e non lo supporta, lascia gli stili essenziali fuori dai blocchi dei livelli e usa l'approccio senza livelli mostrato nell'esempio completo. Non inserire l'unica copia degli stili necessari in una funzionalità non supportata. Supporto dei livelli della cascata.
Come puoi correggere un foglio di stile esistente senza aggiungere altri override?
Procedi una proprietà alla volta. Per un problema con il colore del testo, individua la regola ampia che assegna direttamente il colore ai discendenti. Rimuovi quella dichiarazione dalla regola universale, imposta il valore della pagina su body e mantieni i colori dei componenti sui relativi elementi radice. Conserva le dichiarazioni a livello di elemento solo dove il design richiede un'eccezione.
Poi ripeti le tre modifiche della dimostrazione. Se il normale testo di un componente continua a non seguire il genitore, cerca una dichiarazione che seleziona quel discendente. Se modificare il bordo di un componente non cambia i bordi dei suoi discendenti, è il comportamento previsto: l'ereditarietà del bordo è diversa da quella del colore del testo. Ereditarietà.
Un valore predefinito facile da mantenere ha un responsabile chiaro. Imposta la tipografia della pagina al confine della pagina, la presentazione dei componenti al confine dei componenti e le eccezioni deliberate sugli elementi interessati. Riserva le dichiarazioni universali alle scelte che vuoi applicare a ogni elemento corrispondente, poi verifica questi confini con una piccola pagina locale.
Fonti
- CSS Cascading and Inheritance Level 4 — W3C.
- Selettori universali — MDN Web Docs.
- Specificità — MDN Web Docs.
- Ereditarietà — MDN Web Docs.
- box-sizing — MDN Web Docs.
- Lavorare con documenti HTML in TextEdit sul Mac — Apple Support.
- Standard HTML: tipo di collegamento stylesheet — WHATWG.
- Pseudo-classe CSS :where() — MDN Web Docs.
- Regola at CSS @layer — MDN Web Docs.