Inheritance

El podcast de CSS 005: Herencia

Supongamos que acabas de escribir algunas CSS para que los elementos se vean como un botón.

<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, agregas 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 es 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, descubrirás por qué sucede esto y cómo la herencia es una función eficaz para ayudarte a escribir menos CSS.

Flujo de herencia

Veamos 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 CSS al elemento HTML, y el documento comienza en cascada.

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 <p> tendrá texto en cursiva porque es el elemento anidado más profundo. La herencia solo fluye hacia abajo, no hacia arriba a los elementos superiores.

¿Qué propiedades se heredan de forma predeterminada?

No todas las propiedades de CSS se heredan de forma predeterminada, pero hay muchas de ellas. A modo de referencia, a continuación, se muestra la lista completa de propiedades que se heredan de forma predeterminada, tomada de la referencia W3 de todas las propiedades de CSS:

Cómo funciona la herencia

Cada elemento HTML tiene todas las propiedades de CSS definidas de forma predeterminada con un valor inicial. Un valor inicial es una propiedad que no se heredó y se muestra como predeterminada si la cascada no puede calcular un valor para ese elemento.

Las propiedades que pueden heredarse en cascada y los elementos secundarios obtendrán un valor calculado que representa el valor de su elemento superior. Esto significa que si un elemento superior tiene font-weight establecido en bold, todos los elementos secundarios aparecerán en negrita, a menos que su font-weight esté configurado en un valor diferente o que la hoja de estilo del usuario-agente tenga un valor de font-weight para ese elemento.

Cómo heredar y controlar de forma explícita la herencia

La herencia puede afectar los elementos de formas inesperadas, por lo que CSS tiene herramientas para ayudarte 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 manera útil de usar esta palabra clave es crear excepciones.

strong {
  font-weight: 900;
}

Este fragmento de CSS configura todos los elementos <strong> para que 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;
}

En cambio, la clase .my-component configura font-weight como 500. Para hacer que los elementos <strong> dentro de .my-component también 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 mantenga actualizado con él automáticamente.

La palabra clave initial

La herencia puede causar problemas con tus elementos, y initial te proporciona una potente opción de restablecimiento.

Anteriormente, aprendiste que cada propiedad tiene un valor predeterminado en CSS. La palabra clave initial vuelve a configurar una propiedad en ese valor predeterminado inicial.

aside strong {
  font-weight: initial;
}

Este fragmento quitará el grosor en negrita de todos los elementos <strong> dentro de un elemento <aside> y, en su lugar, los convertirá en un 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 será igual a initial.

Recordar qué propiedades de CSS se heredan de forma predeterminada puede ser difícil, 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 diseños p globales obtienen algunas propiedades adicionales? Solo se aplicará la regla que se configuró 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é diseños globales se apliquen a p en el futuro, siempre no se establecerán.

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

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre herencia

¿Cuáles de las siguientes propiedades son heredables?

animation
Las animaciones no se transfieren a los elementos secundarios.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

¿Qué valor se comporta como inherit, a menos que no haya nada que heredar y, luego, se comporte como initial?

reset
no es un valor válido. Vuelve a intentarlo.
unset
🎉
superset
no es un valor válido. Vuelve a intentarlo.

Recursos