Herencia

Digamos que acaba de escribir algo de CSS para que los elementos parezcan 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 agrega un elemento de enlace a un artículo de contenido, con un valor .my-button para class. Sin embargo, hay un problema, el texto no tiene el color que esperaba. ¿Cómo pasó esto?

Algunas propiedades CSS se heredan si no especifica 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á por qué sucede eso y cómo la herencia es una característica poderosa para ayudarlo a escribir menos CSS.

Flujo de la herencia

Echemos un vistazo a cómo funciona la herencia, mediante 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. Agregue algo de CSS en el elemento HTML y comenzará a heredarse en cascada por el documento.

html {
  color: lightslategray;
}

La propiedad color es heredada por otros elementos. El elemento html tiene un valor color: lightslategray, por lo tanto, todos los elementos que pueden heredar el color ahora tendrán un color lightslategray.

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

Solo el elemento <p> tendrá texto en cursiva porque es el elemento anidado más profundo. La herencia solo fluye hacia abajo, no hacia los elementos principales.

¿Qué propiedades son heredables?

No todas las propiedades CSS son heredables, pero hay muchas que sí lo son. Como referencia, esta es la lista completa de propiedades heredables, tomada de la referencia W3 de todas las propiedades CSS:

Cómo funciona la herencia

Cada elemento HTML tiene todas las propiedades CSS definidas por defecto con un valor inicial. Un valor inicial es una propiedad que no se hereda y aparece como predeterminada si la cascada no calcula un valor para ese elemento.

Las propiedades que se pueden heredar descienden en cascada y los elementos secundarios obtendrán un valor calculado que representa el valor de sus primarios. Esto significa que si un primario tiene el elemento font-weight establecido en bold, todos los elementos secundarios estarán en negrita, a menos que su elemento font-weight se establezca en un valor diferente, o la hoja de estilo del agente de usuario tenga un valor font-weight para ese elemento.

Cómo heredar y controlar explícitamente la herencia

La herencia puede afectar los elementos de formas inesperadas, por lo que CSS tiene herramientas para ayudar con eso.

La palabra clave inherit

Puede hacer que cualquier propiedad herede el valor calculado de su elemento primario 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 bold predeterminado, que sería el equivalente a font-weight: 700.

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

En su lugar, la clase .my-component establece el valor font-weight en 500. Para hacer que los elementos <strong> dentro de .my-component también tengan font-weight: 500 agregue:

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

Ahora, los elementos <strong> dentro de .my-component tendrán un font-weight igual a 500.

Puede establecer explícitamente este valor, pero si usa inherit y el CSS de .my-component cambia en el futuro, puede garantizar que su <strong> se mantendrá actualizado automáticamente con eso.

La palabra clave initial

La herencia puede causar problemas con sus elementos y la palabra clave initial proporciona una poderosa opción de reinicio.

Aprendió anteriormente que cada propiedad tiene un valor predeterminado en CSS. La palabra clave initial establece una propiedad de nuevo a ese valor predeterminado inicial.

aside strong {
  font-weight: initial;
}

Este fragmento eliminará el peso 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 es heredable o no. Si una propiedad es heredable, la palabra clave unset se comportará lo mismo que inherit. Si la propiedad no es heredable, la palabra clave unset se comporta igual que initial.

Recordar qué propiedades CSS son heredables puede ser difícil, pero unset puede ser útil en ese contexto. Por ejemplo, color es heredable, pero margin no lo es, por lo que puede escribir esto:

/* Estilos de color globales para párrafos en CSS creado */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* La p debe restablecerse en asides, para que pueda usar unset */
aside p {
  margin: unset;
  color: unset;
}

Ahora, el margin se elimina y el color vuelve a ser el valor calculado heredado.

También puede utilizar el valor unset con la propiedad all. De regreso al ejemplo anterior, ¿qué sucede si los estilos p globales obtienen algunas propiedades adicionales? Solo se aplicará la regla que se estableció para los parámetros margin y color.

/* Estilos de color globales para párrafos en CSS creado */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* No todas las propiedades se tienen más en cuenta */
aside p {
    margin: unset;
    color: unset;
}

Si en vez de ello, cambia la regla aside p a all: unset, no importa qué estilos globales se apliquen a p en el futuro, siempre estarán desactivados.

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

Check your understanding

Test your knowledge of inheritance

Which of the following properties are inheritable?

animation
Animations do not pass down to children.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

Which value behaves like inherit unless there is nothing to inherit and then behaves like initial?

reset
not a valid value, try again!
unset
🎉
superset
not a valid value, try again!

Recursos