En CSS, tan importante es saber qué pasa cuando se declara más de un valor para una propiedad (cascada), como saber qué pasa cuando no se declara ninguno (valores por defecto). Tener claro cómo funciona la herencia en CSS es fundamental para no volverte majara depurando errores “inexplicables”.
¿Qué es la herencia?
Muchas propiedades CSS (por ejemplo, color
o font-size
) son heredadas. Esto significa que si no se les asigna ningún valor específico, lo heredarán del que tenga el elemento padre en la jerarquía HTML (el cual, a su vez, podría heredarlo de su padre, y así hasta el elemento raíz).
Lo vemos en el siguiente ejemplo:
<p style="color: red">
Lorem ipsum <strong>dolor</strong> sit amet,
consectetuer adipiscing <em>elit</em>. Aenean commodo
ligula eget dolor. Aenean massa. Cum sociis natoque
penatibus et magnis dis parturient montes,
nascetur ridiculus mus.
</p>
Si no se especifica lo contrario, los elementos <strong>dolor</strong>
y <em>elit</em>
serán también de color rojo.
En el elemento raíz (<html>
) el valor heredado es siempre el valor inicial de la propiedad en cuestión (ver más adelante).
¿Qué propiedades son heredadas?
Las propiedades que el estándar CSS define como heredadas son bastante de sentido común, si te fijas:
font-*
color
line-height
list-style-*
text-align
text-indent
text-justify
text-transform
word-break
word-wrap
word-spacing
letter-spacing
hanging-punctuation
hyphens
line-break
overflow-wrap
white-space
tab-size
text-emphasis
quotes
orphans
widows
direction
text-combine-upright
text-orientation
writing-mode
border-collapse
border-spacing
empty-cells
caption-side
image-orientation
image-resolution
clip-rule
caret-color
cursor
visibility
--*
(variables)
En cambio no tendría mucho sentido que fueran heredadas propiedades como margin
, display
o width
.
A una propiedad no heredada se le puede forzar a heredar su valor del elemento padre asignándole el valor inherit
:
Valores computados
Es importante tener en cuenta que lo que se hereda no es el valor declarado, sino el valor computado. Me explico:
En el siguiente ejemplo, los elementos <code>Rocinante</code>
y <code>Sancho</code>
a la izquierda heredan el font-size
de sus padres, pero no heredan el valor 1.25em
sino el valor computado 20px
(16px multiplicado por 1,25). Si heredase 1.25em (simulado a la derecha), entonces el tamaño sería un 25% mayor que el de su padre:
El estándar CSS especifica cómo se calculan los valores computados de cada propiedad.
Herencia de los pseudoelementos
En el caso de selectores como ::before
o ::first-letter
, estos generan pseudoelementos HTML, que heredan del elemento (o pseudoelemento) al que se añaden. Por ejemplo:
Valores por defecto (initial
)
Todas las propiedades, incluso las heredadas, tienen un valor por defecto, especificado en el estándar CSS como initial value. Ejemplos de estos valores son:
Propiedad | Valor inicial |
display | inline |
width | auto |
margin-top | 0 |
background-color | transparent |
color | depende del navegador |
font-family | depende del navegador |
font-weight | normal |
Es el navegador, en su propia hoja de estilos, quien se encarga de asignar estilos más adecuados para cada tipo de elemento (font-weight: bolder
para los <strong>
, display: block
para los <p>
o los <div>
, etc.).
Podemos asignar explícitamente su valor inicial a cualquier propiedad mediante la palabra clave initial
:
.decolorante {
color: initial; /* Color por defecto del navegador */
}
El valor initial
puede ser útil para eliminar todos los estilos que pudiera tener asignado un determinado elemento, incluyendo los estilos heredados, o los del navegador, usando la declaración all: initial
.
Propiedades abreviadas (shorthand)
Las propiedades abreviadas (shorthand properties) son aquellas que «abarcan» a otras propiedades más específicas, de manera que se pueden usar para asignar varios valores en una sola declaración.
Un ejemplo sería la propiedad border
, que engloba border-left-width
, border-top-color
, etc.
¿Y qué tienen que ver estas propiedades con los valores iniciales? ¡Pues mucho!
Cuando asignas un conjunto de valores a una propiedad abreviada, las propiedades específicas a las que no asignes un valor explícitamente asumen implícitamente el valor inicial, incluso si son propiedades heredadas.
Esto puede tener inquietantes implicaciones.
Veámoslo. El siguiente código:
.shorthand {
font: 1.2em serif;
}
es entonces una forma resumida de escribir lo siguiente:
.shorthand {
font-size: 1.2em;
font-family: serif;
font-style: initial; /* → normal */
font-weight: initial; /* → normal */
font-stretch: initial; /* → normal */
line-height: initial; /* → normal */
/* etc. */
}
El siguiente Pen muestra una de las posibles consecuencias:
Reiniciando propiedades: unset
La palabra clave unset
es equivalente a inherit
en propiedades heredadas y a initial
en no heredadas. Así, por ejemplo:
.restablecido {
color: unset;
display: unset;
}
es equivalente a:
.restablecido {
color: inherit;
display: initial;
}
Es decir, unset
tiene el efecto de eliminar todas las anteriores declaraciones de la cascada CSS que afectan a esa propiedad (incluyendo las de la hoja de estilos del navegador, ojo).
Por lo tanto, all: unset
aplicaría a todas las propiedades del elemento el valor inherit
o initial
, dependiendo de si son heredadas o no heredadas, respectivamente.
Por si te lo estabas preguntando, no, nuestro amigo Internet Explorer no es compatible con los valores unset
e initial
.
Conclusión
En definitiva, el funcionamiento de la herencia en CSS es fundamental para todo desarrollador web que se precie. Si lo tienes bien asimilado e interiorizado, te permitirá crear hojas de estilos de una manera mucho más eficiente. Si no, dar estilos a tu web será algo parecido a magia negra: unas veces funcionará, otras no, y nunca sabrás muy bien por qué.