The CSS Podcast - 005: Inheritance (Podcast de CSS, episodio 5: Herencia)
Supongamos que acabas de escribir código CSS para que los elementos parezcan botones.
<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;
}
Luego, agrega un elemento de vínculo a un artículo de contenido con un valor class
de .my-button
. Sin embargo, hay un problema: el texto no tiene el color que esperabas. ¿Cómo ocurrió esto?
Algunas propiedades de CSS se heredan si no especificas un valor para ellas.
En el caso de este botón, heredó el color
de este CSS:
article a {
color: maroon;
}
En esta lección, aprenderás por qué sucede eso y cómo la herencia es una función potente que te ayuda a escribir menos CSS.
Flujo de herencia
Echa un vistazo a cómo funciona la herencia con este fragmento de HTML:
<html>
<body>
<article>
<p>Lorem ipsum dolor sit amet.</p>
</article>
</body>
</html>
El elemento raíz (<html>
) no heredará nada porque es el primer elemento del documento.
Agrega algo de CSS al elemento HTML y comenzará a aplicarse en cascada por el documento.
html {
color: lightslategray;
}
Otros elementos heredan la propiedad color
de forma predeterminada.
El elemento html
tiene color: lightslategray
, por lo que todos los elementos que pueden heredar color ahora tendrán un color de lightslategray
.
body {
font-size: 1.2em;
}
p {
font-style: italic;
}
Solo el <p>
tendrá texto en cursiva porque es el elemento anidado más profundo.
La herencia solo fluye hacia abajo, no hacia los elementos superiores.
¿Qué propiedades se heredan de forma predeterminada?
No todas las propiedades de CSS se heredan de forma predeterminada, pero hay muchas que sí lo hacen. Como referencia, aquí se incluye la lista completa de propiedades que se heredan de forma predeterminada, extraída de la referencia de W3 de todas las propiedades de CSS:
- azimuth
- border-collapse
- border-spacing
- caption-side
- color
- cursor
- direction
- empty-cells
- font-family
- font-size
- font-style
- font-variant
- font-weight
- fuente
- letter-spacing
- line-height
- list-style-image
- list-style-position
- list-style-type
- list-style
- huérfanos
- precios
- text-align
- text-indent
- text-transform
- visibilidad
- white-space
- viudas
- word-spacing
Cómo funciona la herencia
De forma predeterminada, cada elemento HTML tiene definida cada propiedad CSS con un valor inicial. Un valor inicial es una propiedad que no se hereda y aparece como predeterminada si la cascada no puede calcular un valor para ese elemento.
Las propiedades que se pueden heredar se propagan hacia abajo, y los elementos secundarios obtendrán un valor calculado que representa el valor de su elemento principal.
Esto significa que, si un elemento principal tiene font-weight
establecido en bold
, todos los elementos secundarios estarán en negrita, a menos que su font-weight
esté establecido en un valor diferente o que la hoja de estilo del agente de usuario tenga un valor para font-weight
para ese elemento.
Cómo heredar y controlar la herencia de forma explícita
La herencia puede afectar los elementos de formas inesperadas, por lo que CSS tiene herramientas para ayudar con eso.
La palabra clave inherit
Puedes hacer que cualquier propiedad herede el valor calculado de su elemento superior con la palabra clave inherit
.
Una forma útil de usar esta palabra clave es crear excepciones.
strong {
font-weight: 900;
}
Este fragmento de CSS establece que todos los elementos <strong>
tengan un font-weight
de 900
, en lugar del valor predeterminado bold
, que sería equivalente a font-weight: 700
.
.my-component {
font-weight: 500;
}
La clase .my-component
establece font-weight
en 500
en su lugar.
Para que los elementos <strong>
dentro de .my-component
también sean font-weight: 500
, agrega lo siguiente:
.my-component strong {
font-weight: inherit;
}
Ahora, los elementos <strong>
dentro de .my-component
tendrán un font-weight
de 500
.
Puedes establecer este valor de forma explícita, pero si usas inherit
y el CSS de .my-component
cambia en el futuro, puedes garantizar que tu <strong>
se mantendrá actualizado automáticamente.
La palabra clave initial
La herencia puede causar problemas con tus elementos, y initial
te proporciona una potente opción de restablecimiento.
Ya aprendiste que cada propiedad tiene un valor predeterminado en CSS.
La palabra clave initial
restablece una propiedad a ese valor predeterminado inicial.
aside strong {
font-weight: initial;
}
Este fragmento quitará el peso en negrita de todos los elementos <strong>
dentro de un elemento <aside>
y, en su lugar, los hará de peso normal, que es el valor inicial.
La palabra clave unset
La propiedad unset
se comporta de manera diferente si una propiedad se hereda de forma predeterminada o no.
Si una propiedad se hereda de forma predeterminada, la palabra clave unset
será la misma que inherit
.
Si la propiedad no se hereda de forma predeterminada, la palabra clave unset
es igual a initial
.
Recordar qué propiedades de CSS se heredan de forma predeterminada puede ser difícil, por lo que unset
puede ser útil en ese contexto.
Por ejemplo, color
se hereda de forma predeterminada, pero margin
no, por lo que puedes escribir lo siguiente:
/* 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;
}
Ahora, se quita margin
y color
vuelve a ser el valor calculado heredado.
También puedes usar el valor unset
con la propiedad all
.
Volviendo al ejemplo anterior, ¿qué sucede si los estilos p
globales obtienen algunas propiedades adicionales?
Solo se aplicará la regla que se estableció para margin
y 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;
}
Si cambias la regla aside p
a all: unset
, no importa qué estilos globales se apliquen a p
en el futuro, siempre se anularán.
aside p {
margin: unset;
color: unset;
all: unset;
}
La palabra clave revert
Como aprendiste en la lección sobre la cascada, los estilos provienen de diferentes orígenes: los estilos base del usuario-agente, los estilos de preferencia del usuario y los estilos que creaste. La palabra clave revert
deshace los estilos que se establecen en el mismo origen en el que se usa la palabra clave revert
.
Esto es útil cuando estableciste un estilo, pero no quieres que se aplique en algunos casos. Mientras que inherit
, initial
y unset
especifican cómo calcular el valor de un estilo, revert
solo especifica que no se aplican otros estilos que escribiste.
p {
padding: 2em;
}
aside p {
padding: revert;
}
Este fragmento les da a los elementos <p>
un relleno, pero, cuando el elemento <p>
está dentro de un <aside>
, no especifica ningún padding
. En cambio, se revierte a un estilo de preferencia del usuario (si se configuró uno) o a los estilos base del usuario-agente.
La palabra clave revert-layer
Las capas en cascada proporcionan una forma útil de organizar tus estilos y priorizarlos dentro del origen del autor de la cascada. La palabra clave revert-layer
es similar a revert
, pero, en lugar de especificar que no se debe aplicar ninguno de los diseños del autor para una propiedad, solo deshace los diseños en la capa actual.
Si usas una biblioteca de IU de terceros, un patrón útil es importarla en una capa y agregar cualquier anulación en una capa de mayor prioridad. Luego, puedes quitar una anulación con revert-layer
, y se usarán los valores predeterminados de la biblioteca de IU.
Si ninguna otra capa especifica un valor para la propiedad, se comportará como revert
y usará un valor de un origen anterior.
Verifica tus conocimientos
Pon a prueba tus conocimientos sobre la herencia
¿Cuáles de las siguientes propiedades se heredan de forma predeterminada?
line-height
animation
font-size
text-align
color
¿Qué valor se comporta como inherit
, a menos que no haya nada que heredar y, luego, se comporta como initial
?
unset
reset
superset