¿Cómo funciona la herencia en CSS?

CSS es algo a primera vista muy fácil. Al fin y al cabo solo es cuestión de poner un selector y escribir los estilos que quieran esos elementos.

Si sigues las buenas prácticas es aún más fácil. Porque en ese caso estarás asignandole clases a tu HTML, tal vez con la metodología OOCSSS, BEM, etc.

Esta facilidad es la que evita que muchos desarrolladores nos tomemos el tiempo de realmente aprender acerca de sus particularidades:

Las reglas de ordenamiento de la cascada o el CSSOM son algunas de ellas.

Pero la que nos atañe hoy es otra de esas tantas particularidades: La herencia en CSS.

Las propiedades heredadas

El concepto de herencia es un concepto común en programación orientada a objetos. Cuando hablamos de este paradigma, normalmente nos referimos a la habilidad de un objeto de pasarle sus propiedades (valores y funciones) a otro objeto.

En CSS evidentemente no estamos utilizando objetos, pero el concepto es similar. Se pasan propiedades de un elemento a otro.

La cuestión en CSS es que no se puede pasar cualquier propiedad. No todas las propiedades se heredan entre todos los elementos. De hecho sólo una pequeña parte de todas las propiedades son las que cuentan con esta característica.

Aqui algunas de ellas:

* {
    color: #000;
    cursor: default;
    font: inherit;
    font-family: sans-serif;
    font-size: 16px;
    font-style: normal;
    font-weight: normal;
    letter-spacing: normal;
    line-height: 1.5;
    text-align: left;
    text-indent: 0;
    text-justify: auto;
    text-shadow: none;
    text-transform: none;
    visibility: visible;
    word-spacing: normal;
}

*Cabe mencionar que si quieres ver la lista completa puedes revisarlas en la documentación del World Wibe Web Consortium W3C, quienes se encargán de establecer la estandarización de CSS entre otras cosas.

Si te fijas, muchas de estas reglas tienen que ver con el texto y con darle estilos personalizados al mismo (lo cual es algo casi obligatorio en cualquier proyecto). Por lo tanto aún si no te has dado cuenta lo mas probable es que le hayas estado sacando provecho a la funcionalidad de herencia de CSS.

La herencia en acción

Para poder entenderlo es mejor verlo.

Abajo tenemos un documento de HTML junto con su respectivo CSS estructurado para que podamos observar como se comporta la herencia:

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="styles.css">
        <title>Herencia en CSS</title>
    </head>
    <body>
        <header>
            <h1>Lorem Ipsum</h1>
            <h2>Dolor sit amet</h2>
        </header>
        <section>
            <p>Ut malesuada dapibus eros, sollicitudin varius nibh fermentum nec. Nullam purus risus, dictum ac dapibus et, egestas eu lectus. Vestibulum vitae tristique augue. Aenean blandit lorem non ipsum interdum egestas. Integer ligula nibh, lobortis suscipit pellentesque ac, molestie ac arcu. Mauris euismod felis sit amet neque mollis blandit quis sit amet tortor. Cras lacus odio, ultricies in orci et, placerat placerat lorem. Etiam semper ultrices augue, eget ornare mi hendrerit in. <span>Praesent dui massa, fermentum ut metus id, posuere ullamcorper urna.</span> In ullamcorper lacus vitae nulla vestibulum, a dictum augue laoreet. Ut volutpat metus sed luctus ultricies. Nulla molestie pulvinar urna. Donec eu scelerisque diam. Aenean nec arcu risus. Nam sapien neque, egestas eget tortor vel, luctus gravida nulla.</p>
            <p>Sed nec fermentum orci, vel commodo nibh. Nulla laoreet interdum sodales. Integer ultrices enim in feugiat accumsan. Praesent quis ante ac massa congue sodales ut a nisi. Quisque condimentum leo ipsum, ut dictum diam feugiat et. Duis euismod, turpis ut sodales maximus, sem ante consectetur neque, ut sollicitudin ex dolor sed ex. Donec dui ligula, varius nec sagittis accumsan, efficitur pretium massa. Mauris ac enim est. <span>Praesent <em>vitae rhoncus erat,</em></span> eu auctor sem. Nullam facilisis finibus ipsum vel consectetur. Fusce ornare venenatis cursus. Nam pharetra tempus purus, ac consectetur magna interdum in. Nullam vitae finibus libero. Etiam eros orci, pulvinar hendrerit leo ut, pretium volutpat leo. Donec vel risus ante.</p>
            <p>Nam varius lectus ac leo ultrices pretium. Cras id pellentesque eros, at rhoncus erat. Duis ultricies suscipit turpis in sagittis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam rhoncus arcu velit, ut consectetur dui faucibus non. <span>Phasellus ut eros at tortor <i>egestas bibendum semper id</i> sapien.</span> Quisque fringilla, nibh et eleifend scelerisque, elit velit pulvinar ante, eu fringilla elit metus a mi. Aenean sollicitudin mi dui, non mattis dolor dictum sit amet. Etiam imperdiet consectetur consequat. <span>Cras suscipit nunc sed urna dictum facilisis. Sed blandit luctus sem in mollis.</span> Integer aliquam lacinia urna quis malesuada. In dapibus sapien id orci sagittis, non porttitor neque maximus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc tempus est ac lorem finibus scelerisque.</p>

            <article>
                <a href="https://www.youtube.com/">Link a Youtube</a>

                <ul>
                    <li>Item 1</li>
                    <li>Item 2</li>
                    <li>Item 3</li>
                    <li>Item 4</li>
                    <li>Item 5</li>
                </ul>
            </article>
        </section>
    </body>
</html>

styles.css

body {
    font-family: Georgia, serif;
}

header {
    color: brown;
    font-style: italic;
    letter-spacing: 2px;
}

section {
    color: darkgray;
    text-align: justify;
}

section span {
    color: darkblue;
    font-weight: bolder;
    text-shadow: 2px 2px 2px lightblue;
}

article {
    font-style: italic;
}

a:visited {
    color: darkgreen;
}

Con estos archivos nuestro documento se ve algo similar a la siguiente imágen:

¿Cómo se propagaron las reglas de herencia para obtener este resultado?

  1. El elemento body hereda a sus 2 hijos, header y section la propiedad de font-family.
  2. El elemento header hereda color, font-style y letter-spacing a h1 y h2.
  3. El elemento section hereda color y text-align a sus hijos, article y los 3 elementos p.
  4. Los elementos p no tienen estilos definidos explícitamente pero heredan a sus hijos las propiedades que ellos a su vez heredaron. En estes caso los elementos span son sus únicos hijos.
  5. Los elementos span que se encuentra dentro de elementos section (que en este ejemplo son todos los span), cuentan con estilos definidos para color, font-weight y text-shadow. La propiedad de color ya venía heredada del elemento p y section sucesivamente con el valor darkgray. Sin embargo se le da prioridad al valor definido en el selector de span: darkblue.
  6. Los elementos i y em que se encuentran dentro de un par de span (si, buscalos, ahí estan) heredan las propiedades de span. Aunque no hay estilos definidos explícitamente para estos elementos, el User-Agent (el navegador) define font-style: italic; como propiedad por defecto para los mismos.
  7. El elemento article heredó las propiedades de section y agrega un valor a font-style. Esto a su vez lo pasa a sus hijos ul y a.
  8. El elemento a define un color para el estado visitado con una pseudo-clase. Los demás valores los heredó de article.
  9. El elemento ul no define propiedades propias, así que solo hereda a cada elemento li las propiedades que obtuvo de article.
  10. Los elementos li tampoco cuentan con propiedades por sí mismos por lo que terminan aplicando los mismos estilos que tienen ul y article.

El árbol que se construye para el CSSOM resultante nos puede ayudar a visualizar mejor la jerarquía de los objetos:

*El CSSOM y el DOM pueden parecer muy similares y en ocasiones quedar prácticamente idénticos.