La Herencia en CSS
Tags: css, spanish
Published: 2021-07-24 00:13:36

¡Hola gente bonita!👋

Hay una última manera en la que un elemento puede recibir estilos: la herencia. La cascada se confunde frecuentemente con el concepto de herencia. Aunque los dos temas están relacionados, debes entender cada uno por separado. Si quieres conocer sobre la cascada te invito a leer mi articulo de este tema:

{% link https://dev.to/lupitacode/la-cascada-en-css-que-es-y-como-funciona-31cd %}

##👨‍👦 ¿Qué es la herencia?

Vamos a comenzar por una analogía que me gusta usar mucho.

Muchas veces los niños y niñas heredan rasgos de sus padres: el color de los ojos, el color del cabello, la estatura, etc. A veces heredamos rasgos de antepasados más lejanos, como abuelos o bisabuelos. La metáfora de las relaciones familiares también forma parte de la estructura del HTML. Y al igual que las personas, las etiquetas HTML pueden heredar propiedades CSS de sus antepasados.

Los descendientes (piense en hijos y nietos) heredan propiedades de los ancestros (piense en padres y abuelos).

> La herencia es el proceso por el cual algunas propiedades CSS aplicadas a una etiqueta se pasan a las etiquetas anidadas, es decir, los elementos HTML heredan los estilos de sus padres o ancestros.

Si un elemento no tiene un valor en cascada para una determinada propiedad, puede heredar uno de un elemento antecesor. Es común aplicar la propiedad `font-family` al elemento `<body>`. Todas las etiquetas descendientes de la etiqueta `<body>`, es decir, las que están dentro de la etiqueta `<body>` heredarán esta fuente y no es necesario aplicarla explícitamente a cada elemento de la página.

NOTA: Cualquier etiqueta dentro de otra etiqueta es descendiente de esa etiqueta. por ejemplo, una etiqueta `<p>` dentro de la etiqueta `<body>` es descendiente de `<body>`, mientras que la etiqueta `<body>` es un ancestro de la etiqueta `<p>`. 

La herencia también funciona a través de múltiples generaciones. Si una etiqueta como `<em>` o `<strong>` aparece dentro de una etiqueta `<p>`, entonces las etiquetas `<em>` y `<strong>` también 
heredan las propiedades de cualquier estilo aplicado a la etiqueta `<body>`.

La siguiente imagen muestra cómo la herencia fluye hacia abajo en el árbol del DOM. Las propiedades heredadas se transfieren por el árbol DOM desde los nodos padres a sus descendientes.

![árbol del DOM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xptrm0otvatj9idia7o6.jpg)

> Como puedes notar en la estructura del árbol cada elemento solo tiene un padre directo.

## Propiedades heredadas y propiedades no heredadas

Hay algunas propiedades en CSS que se heredan y otras que no. Esta diferencia crea dos tipos de grupos de propiedades CSS:

1. Propiedades heredadas (Inherited properties)
2. Propiedades no heredadas (Non-inherited properties)

Para saber cuales son las propiedades heredadas y no heredadas puede consultar la documentación de la MDN, en cada propiedad se le proporciona una tabla donde se le explica si es heredada o no, por ejemplo:

![Propiedades heredadas y no heredadas](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0x5pt3dws0xwqd7x8bgi.jpeg)

## Propiedades heredadas

Las propiedades heredadas son las que pertenecen principalmente al texto:

`color`, `font`, `font-family`, `font-size`, `font-weight`, 
`font-variant`, `font-style`, `line-height`, 
`letter-spacing`, `text-align`, `text-indent`, 
`text-transform`,`white-space`, y `word-spacing`.

También se heredan algunas otras, como las propiedades de la lista:

`list-style`, `list-style-type`, 
`list-style-position`, y `list-style-image`.

Las propiedades del borde de la tabla, `border-collapse` y `border-spacing`, también se heredan. Tenga en cuenta que éstas controlan el comportamiento de los bordes de las tablas, NO las propiedades para especificar los bordes de los elementos que no son tablas. No queremos que un `<div>` pasara su borde a todos los elementos descendientes ¿Verdad?.

## Propiedades no heredadas

La herencia no siempre se aplica, y eso NO es necesariamente algo malo. Para algunas propiedades, la herencia tendría un efecto negativo en la apariencia de una página. Los márgenes, el padding y los bordes (entre otras propiedades) no son heredados por las etiquetas y no es deseable que lo hagan. ¿Por que?

Mira el siguiente ejemplo:

```
 <p> Lorem ipsum <em> dolor </em> sit amet. </p>
```
```
p {
 padding-left: 20px;
 border-left: solid red;
}
```
Observa que la etiqueta `<p>` tienen un borde a la izquierda. Sin embargo, la etiqueta `<em>` dentro de `<p>` no tienen ningún borde adicional. Este comportamiento tiene sentido: se vería raro o extraño si hubiera un borde adicional y 20px de espacio a la izquierda de cada etiqueta `<em>` dentro de un párrafo. Por este motivo es que la propiedad `border` no se hereda.

##🤔 ¿Por que es importante la herencia?

Aunque esto pueda parecer confuso, la herencia es un gran ahorro de tiempo. Imagina que no se pasan las propiedades CSS a las etiquetas anidadas y que tienes un párrafo `<p>` que contiene otras etiquetas como una etiqueta `<strong>`, una etiqueta `<em>` para enfatizar el texto y una etiqueta `<a>` para añadir un enlace. 

Si creas un estilo que haga que el texto del párrafo sea blanco y de 32px, sería raro y extraño que todo el texto dentro de las etiquetas `<em>`, `<strong>` y `<a>` tuvieran su estilo normal, tal y como se muestra en la siguiente imagen de muestra:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4rqh4rd5o5o3kf0gfzew.jpg)

En ese caso, tendrías que crear otro estilo para dar formato a la etiqueta `<em>`, `<strong>` y `<a>` para que coincida con la apariencia de la etiqueta `<p>`. Qué tedioso. ¡Por eso esta la herencia y por eso es importante!

## La palabra clave `inherit`

CSS tiene "Global Keywords" o palabras clave por defecto, pero en este articulo solo hablare de la palabra clave `inherit` (heredar) porque tiene relación con la herencia.

La palabra clave `inherit` hace que el valor de una propiedad en un elemento sea el mismo que el valor de su elemento padre. En otras palabras, `inherit` obliga a que la herencia se produzca incluso en situaciones en las que normalmente no funcionaría. 

El proceso ocurre de la siguiente manera:

1. La palabra clave `inherit` le dice al navegador que busque el valor del elemento padre más cercano y que el elemento actual herede ese valor. 

2. Si el padre más cercano también tiene el valor `inherit`, el navegador continuará subiendo por el DOM hasta encontrar algún valor. 

3. Si no hay ningún valor, el navegador utilizará su estilo de agente de usuario, y si no hay ningún estilo de agente de usuario, utilizará el estilo base inicial o el valor inicial.

Vamos a ver el siguiente ejemplo:

```
<nav class="toolbar">
  <a href="#">One</a>
  <a href="#">Two</a>
  <a href="#">Three</a>
</nav>
```
```
.toolbar {
  background-color: blue;
  color: white;
}
```
El `nav` tendrá un fondo azul, pero los enlaces tendrán otro estilo acorde con la configuración de preferencias del navegador. 

Puede escribir una regla que establezca explícitamente que los enlaces sean de color blanco pero puede hacer que las cosas sean un poco más robustas usando `inherit`. Sólo tiene que añadir la siguiente regla a la hoja de estilos:

```
.toolbar {
  background-color: blue;
  color: white;
}
.toolbar a{
  color: inherit;
}
```
Esto hará que los enlaces utilicen el valor heredado del color en lugar de los estilos por defecto del agente de usuario.

Como dije al principio podemos hacer que la herencia se produzca incluso en situaciones en las que normalmente no funcionaría, por ejemplo la propiedad `padding` por defecto, no se puede heredar pero podemos hacer que si se herede, seguiremos con el ejemplo anterior:

```
.toolbar {
  padding: 20px;
}
.toolbar a{
  padding: inherit;
}
```
En este ejemplo todos los enlaces heredaran el valor de la propiedad `padding` del elemento padre, a pesar de que dicha propiedad no se herede por defecto.

En muchos casos, no es necesario especificar la herencia, ya que muchas propiedades se heredan de forma natural. Sin embargo, heredar puede ser muy útil.

## Heredar las fuentes para los controles de formularios: `font: inherit;`

Es probable que en varios resets de CSS encuentres la siguiente regla de estilo:

```css

/* Inherit fonts for inputs and buttons */
input, button, textarea, select {
  font: inherit;
}
```
Por defecto, los botones y los input no heredan los estilos tipográficos de sus padres. En su lugar, tienen sus propios estilos.

Por ejemplo, `<textarea>` utilizará la fuente monospace predeterminada del sistema. Los input utilizarán la fuente sans serif predeterminada del sistema. Y ambos elegirán un tamaño de fuente muy pequeño (13,333px en Chrome).

Como podrás imaginar, es muy difícil leer un texto de 13px en un dispositivo móvil. Cuando enfoquemos un input con un tamaño de fuente pequeño, el navegador hará zoom automáticamente para que el texto sea más fácil de leer. Por lo que no es una buena experiencia de usuario.

[font](https://developer.mozilla.org/en-US/docs/Web/CSS/font#syntax) es un shorthand poco utilizado que engloba varias propiedades relacionadas con la fuente, como `font-family`, `font-size`, `font-stretch`, `font-style`, `font-variant`, `font-weight` y `line-height`. Al establecer la propiedad `font` como `inherit`, ordenamos a estos elementos que coincidan con la tipografía de su entorno.

`font: inherit` afectará sobre todo a los elementos `<textarea>`, pero no hay nada malo en aplicarlo también a los otros elementos de formulario porque ahorra algo de CSS más adelante en un proyecto.


####📚 Libros de CSS consultados para este tema:

1. CSS in Depth
2. CSS The Missing Manual
3. CSS The Definitive Guide

Gracias por leer🦸🏻‍♀️
Mis redes sociales donde comparto notas de código:

[▶️Youtube](https://www.youtube.com/lupitacode)
[📷Instagram](https://instagram.com/lupitacode)
[🐦Twitter](https://twitter.com/lupitacode)
[🔲Codepen](https://codepen.io/lupitacode/)
[✍️Medium](https://lupitacode.medium.com/)
[🎵Tik Tok](https://www.tiktok.com/@lupitacode)
[🔵Facebook](https://facebook.com/lupitacode)