Ereditarietà

The CSS Podcast - 005: Inheritance

Supponiamo di aver appena scritto del codice CSS per far sembrare gli elementi un pulsante.

<a href="http://example.com" class="my-button">I am a button link</a>
.my-button {
  display: inline-block;
  padding: 1rem 2rem;
  text-decoration: none;
  background: pink;
  font: inherit;
  text-align: center;
}

Aggiungi quindi un elemento di collegamento a un articolo di contenuti, con un valore class di .my-button. Tuttavia, c'è un problema: il testo non è del colore che ti aspettavi. Come è accaduto?

Alcune proprietà CSS vengono ereditate se non specifichi un valore. Nel caso di questo pulsante, ha ereditato il color da questo CSS:

article a {
  color: maroon;
}

In questa lezione imparerai perché ciò accade e come l'ereditarietà sia una funzionalità potente che ti aiuta a scrivere meno CSS.

Flusso di ereditarietà

Dai un'occhiata a come funziona l'ereditarietà, utilizzando questo snippet di HTML:

<html>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet.</p>
    </article>
  </body>
</html>

L'elemento radice (<html>) non erediterà nulla perché è il primo elemento del documento. Aggiungi alcuni CSS all'elemento HTML e inizia a scorrere verso il basso del documento.

html {
  color: lightslategray;
}

La proprietà color viene ereditata per impostazione predefinita da altri elementi. L'elemento html ha color: lightslategray, pertanto tutti gli elementi che possono ereditare il colore ora avranno il colore lightslategray.

body {
  font-size: 1.2em;
}
p {
  font-style: italic;
}

Solo l'attributo <p> avrà il testo in corsivo perché è l'elemento nidificato più profondo. L'ereditarietà avviene solo verso il basso, non verso gli elementi principali.

Quali proprietà vengono ereditate per impostazione predefinita?

Non tutte le proprietà CSS vengono ereditate per impostazione predefinita, ma molte sì. Come riferimento, ecco l'elenco completo delle proprietà ereditate per impostazione predefinita, tratto dal riferimento W3 di tutte le proprietà CSS:

Come funziona l'ereditarietà

Per impostazione predefinita, ogni elemento HTML ha ogni proprietà CSS definita con un valore iniziale. Un valore iniziale è una proprietà non ereditata e visualizzata come valore predefinito se la cascata non riesce a calcolare un valore per l'elemento.

Le proprietà che possono essere ereditate vengono trasmesse a cascata verso il basso e gli elementi secondari ottengono un valore calcolato che rappresenta il valore del relativo elemento principale. Ciò significa che se un elemento principale ha font-weight impostato su bold, tutti gli elementi secondari saranno in grassetto, a meno che il relativo font-weight non sia impostato su un valore diverso o che il foglio di stile dell'user agent abbia un valore per font-weight per quell'elemento.

Come ereditare e controllare esplicitamente l'ereditarietà

L'ereditarietà può influire sugli elementi in modi inaspettati, pertanto CSS dispone di strumenti per aiutarti.

La parola chiave inherit

Puoi fare in modo che qualsiasi proprietà erediti il valore calcolato della proprietà principale con la parola chiave inherit. Un modo utile per utilizzare questa parola chiave è creare eccezioni.

strong {
  font-weight: 900;
}

Questo snippet CSS imposta tutti gli elementi <strong> in modo che abbiano un font-weight di 900, anziché il valore predefinito bold, che sarebbe l'equivalente di font-weight: 700.

.my-component {
  font-weight: 500;
}

La classe .my-component imposta font-weight su 500. Per fare in modo che anche gli elementi <strong> all'interno di .my-component siano font-weight: 500, aggiungi:

.my-component strong {
  font-weight: inherit;
}

Ora, gli elementi <strong> all'interno di .my-component avranno un font-weight di 500.

Puoi impostare questo valore in modo esplicito, ma se utilizzi inherit e il CSS di .my-component cambia in futuro, puoi garantire che il tuo <strong> rimarrà automaticamente aggiornato.

La parola chiave initial

L'ereditarietà può causare problemi con gli elementi e initial ti offre una potente opzione di ripristino.

In precedenza hai appreso che ogni proprietà ha un valore predefinito in CSS. La parola chiave initial reimposta una proprietà sul valore predefinito iniziale.

aside strong {
  font-weight: initial;
}

Questo snippet rimuoverà il grassetto da tutti gli elementi <strong> all'interno di un elemento <aside> e li renderà normali, che è il valore iniziale.

La parola chiave unset

La proprietà unset si comporta in modo diverso a seconda che una proprietà venga ereditata per impostazione predefinita o meno. Se una proprietà viene ereditata per impostazione predefinita, la parola chiave unset sarà uguale a inherit. Se la proprietà non viene ereditata per impostazione predefinita, la parola chiave unset è uguale a initial.

Ricordare quali proprietà CSS vengono ereditate per impostazione predefinita può essere difficile, unset può essere utile in questo contesto. Ad esempio, color viene ereditato per impostazione predefinita, ma margin no, quindi puoi scrivere:

/* Global color styles for paragraph in authored CSS */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* The p needs to be reset in asides, so you can use unset */
aside p {
  margin: unset;
  color: unset;
}

Ora, margin viene rimosso e color torna a essere il valore calcolato ereditato.

Puoi utilizzare il valore unset anche con la proprietà all. Tornando all'esempio precedente, cosa succede se gli stili p globali acquisiscono altre proprietà? Verrà applicata solo la regola impostata per margin e color.

/* Global color styles for paragraph in authored CSS */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* Not all properties are accounted for anymore */
aside p {
    margin: unset;
    color: unset;
}

Se modifichi la regola aside p in all: unset, non importa quali stili globali verranno applicati a p in futuro, verranno sempre annullati.

aside p {
    margin: unset;
    color: unset;
    all: unset;
}

La parola chiave revert

Come hai appreso nella lezione sulla cascata, gli stili hanno origini diverse: stili di base dello user agent, stili delle preferenze dell'utente e stili creati da te. La parola chiave revert annulla gli stili impostati nella stessa origine in cui viene utilizzata la parola chiave revert.

Questa opzione è utile quando hai impostato uno stile, ma non vuoi che venga applicato in alcuni casi. Mentre inherit, initial e unset specificano come calcolare il valore di uno stile, revert specifica solo che gli altri stili che hai scritto non vengono applicati.

p {
  padding: 2em;
}

aside p {
  padding: revert;
}

Questo snippet assegna un padding agli elementi <p>, ma quando l'elemento <p> si trova all'interno di un elemento <aside>, non specifica affatto un padding. Viene invece ripristinato uno stile di preferenza utente (se impostato) o gli stili di base dello user agent.

La parola chiave revert-layer

I livelli a cascata offrono un modo utile per organizzare gli stili e assegnare loro la priorità all'interno dell'origine autore della cascata. La parola chiave revert-layer è simile a revert, ma anziché specificare che non deve essere applicato nessuno degli stili dell'autore per una proprietà, annulla solo gli stili nel livello corrente.

Se utilizzi una libreria UI di terze parti, un pattern utile è importarla in un livello e aggiungere eventuali override in un livello con priorità più alta. Dopodiché, puoi rimuovere un override utilizzando revert-layer e verranno utilizzati i valori predefiniti della libreria UI.

Se nessun altro livello specifica un valore per la proprietà, si comporterà come revert e utilizzerà un valore di un'origine precedente.

Verifica la tua comprensione

Metti alla prova le tue conoscenze sull'ereditarietà

Quali delle seguenti proprietà vengono ereditate per impostazione predefinita?

animation
Le animazioni non vengono trasmesse ai figli.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

Quale valore si comporta come inherit a meno che non ci sia nulla da ereditare e poi si comporta come initial?

reset
non è un valore valido, riprova.
unset
🎉
superset
non è un valore valido, riprova.

Risorse