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:
- azimuth
- border-collapse
- border-spacing
- caption-side
- colore
- cursor
- direzione
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- carattere
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- orphans
- quotes
- text-align
- text-indent
- text-transform
- visibilità
- white-space
- widows
- word-spacing
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
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
unset
superset