← CSS: diseño, maquetación y responsive

Sesión 3 · Semana 1

Cascada, herencia y especificidad

Hoy · Hoja de ruta

  1. 1. Aprende: Qué decide cuál de dos reglas en conflicto se aplica, qué se hereda y qué no, y por qué !important es una rendición.
  2. 2. Haz: Diagnostica una hoja con reglas contradictorias y resuélvela sin !important.
  3. 3. Comprueba: Sabes leer en DevTools qué regla ha ganado y por qué.

Antes de empezar · 5 minutos, sin apuntes

  1. ¿Cuándo conviene un selector de elemento y cuándo una clase?
  2. ¿Qué selecciona nav a que no selecciona nav > a?
  3. Escribe el selector de todos los campos obligatorios sin inventar una clase.

La palabra «cascading» no es decorativa

CSS significa Cascading Style Sheets. Hojas de estilo en cascada. Esa palabra describe el mecanismo central del lenguaje: varias reglas pueden querer cambiar la misma propiedad del mismo elemento, y hace falta un criterio para decidir.

p          { color: blue; }
.destacado { color: red; }
<p class="destacado">Hola</p>

¿De qué color se ve? Rojo. La pregunta relevante es por qué.

Lo que decide, en orden

Cómo se resuelve un conflicto, de arriba abajo
  1. Importancia · una declaración con !important gana a una normal
  2. Especificidad · gana el selector más específico
  3. Orden · a igual especificidad, gana la última escrita

Especificidad

Una medida de cuán concreto es un selector. Funciona como un orden de prioridad que basta con conocer, sin necesidad de calcularlo manualmente.

De menos a más específico Ejemplo
Elemento y pseudo-elemento p, a
Clase, atributo y pseudo-clase .destacado, [type="email"], :hover
id #productos

Una regla práctica evita la aritmética: una clase gana a cualquier cantidad de elementos, y un id gana a cualquier cantidad de clases. Por eso #productos p gana a body main section article p, aunque el segundo parezca más trabajado.

De ahí sale el consejo de ayer: si das estilo con id, cualquier ajuste posterior con clases no podrá corregirlo, y acabarás escalando la pelea.

El orden, cuando hay empate

.boton { background: blue; }
.boton { background: green; }

Gana el verde: misma especificidad, y la última escrita manda. Esto explica por qué el orden de tu hoja importa, y por qué conviene escribir de lo general a lo particular.

Herencia

Algunas propiedades pasan de un elemento a sus descendientes:

body {
    font-family: system-ui, sans-serif;
    color: #222;
    line-height: 1.6;
}

Con eso, todo el documento hereda la tipografía. No hace falta repetirla en cada elemento.

Se heredan No se heredan
color, font-family, font-size, line-height, text-align margin, padding, border, background, width, display

La lógica es razonable: lo que se hereda tiene que ver con el texto, y lo que no, con la caja. Que un padding se heredara sería un desastre.

!important

color: red !important;

Existe, gana casi siempre, y no es el botón de arreglar CSS.

Por qué evitarlo

Un !important no resuelve el conflicto: lo esconde. La regla que perdía sigue ahí, y el problema real —que tu selector no era el adecuado, o que el orden estaba mal— sigue sin diagnosticarse.

Además escala. Cuando dentro de un mes necesites sobrescribir esa propiedad, la única forma será otro !important más específico. Ese es el punto en el que una hoja de estilos deja de poder mantenerse.

Si te encuentras escribiéndolo, la pregunta correcta no es «¿cómo hago que esto gane?» sino «¿qué está ganando ahora y por qué?».

DevTools · leer quién gana

Selecciona un elemento e id a la pestaña Styles. Verás las reglas que le afectan, ordenadas de la que gana a la que pierde, y las declaraciones derrotadas aparecen tachadas. A la derecha de cada bloque está el archivo y la línea donde se escribió.

Eso responde simultáneamente a las tres preguntas: qué se está aplicando, qué se ha descartado y dónde está escrito. La pestaña Computed da el siguiente paso: el valor final de cada propiedad, ya resuelto el conflicto.

Tarea 3 · ¿Quién está ganando?

Este HTML y este CSS conviven:

<main id="contenido">
  <section class="bloque">
    <p class="aviso destacado">Envío gratuito a partir de 50 €.</p>
  </section>
</main>
p                      { color: #333; }
.aviso                 { color: green; }
.destacado             { color: orange; }
#contenido p           { color: navy; }
section .aviso         { color: purple; }
main section p.aviso   { color: teal; }

Paso 1 · Te enseño uno

¿Cuántos id hay en juego?
Solo uno: #contenido p. Como el id gana a cualquier cantidad de clases, ese es el candidato inmediato.
¿Le puede ganar alguna otra?
No. main section p.aviso tiene una clase y tres elementos, y sigue por debajo de un id.
¿Importa el orden?
Aquí no, porque no hay empate en especificidad. El orden solo decide entre iguales.
Resultado
navy. Al eliminar la regla del id, prevalecería main section p.aviso, que es teal.

Paso 2 · Ahora tú

  1. Comprueba en el navegador que el color es el que dice el razonamiento.
  2. Borra la regla del id y predice el nuevo color antes de recargar. Después comprueba.
  3. Ahora consigue que el párrafo se vea naranja sin usar !important y sin tocar el HTML. Hay más de una solución válida: explica la que elijas.
  4. Abre DevTools y localiza cuántas declaraciones de color aparecen tachadas.
Estoy atascado · ¿cómo gano sin !important?

Tienes tres caminos legítimos, y conviene que sepas cuál es cuál:

  1. Subir la especificidad del selector que quieres que gane, hasta pasar al que gana ahora.
  2. Bajar la del que gana, que casi siempre es lo correcto: quitar el id del selector y usar una clase.
  3. Mover la regla más abajo en el archivo, si hay empate de especificidad.

El segundo es el que deja la hoja mejor que antes. Los otros dos la dejan igual de enredada, solo que a tu favor.

Reto 1 · La regla que no hace nada (10 min)

.card .titulo {
    color: crimson;
}
<article class="card">
    <h3 class="titulo">Portátil Nova 14</h3>
</article>

El título no se ve rojo, y DevTools no muestra la regla ni siquiera tachada. ¿Qué está pasando?

Ver respuesta del Reto 1

Que no aparezca ni tachada es la pista entera. Una regla tachada es una regla que sí seleccionó el elemento y perdió el conflicto. Si no aparece en absoluto, es que no ha seleccionado nada.

Las causas posibles son de fontanería, no de cascada: la hoja no se está cargando, hay una errata en el nombre de la clase, falta el punto y coma o la llave de la regla anterior —lo que invalida esta—, o el elemento no está donde crees.

La lección es el método: tachado significa problema de cascada; ausente significa problema de selector o de sintaxis. Son dos diagnósticos distintos y se buscan en sitios distintos.

Checkpoint · fin de la sesión 3 y de la semana 1

  • Sabes ordenar elemento, clase e id por especificidad.
  • Sabes que el orden solo decide cuando hay empate.
  • Distingues una propiedad que se hereda de una que no.
  • Sabes leer en Styles qué regla gana y cuáles están tachadas.
  • No hay ningún !important en tu hoja.

Antes de cerrar · 2 minutos, sin mirar

  1. ¿Qué gana: tres clases o un id?
  2. ¿Cuándo decide el orden en que están escritas las reglas?
  3. En DevTools, ¿qué significa que una declaración aparezca tachada, y qué que no aparezca?
Ver respuestas

1 · El id. Gana a cualquier cantidad de clases.

2 · Solo cuando dos reglas tienen la misma especificidad; entonces se aplica la última escrita.

3 · Tachada quiere decir que seleccionó el elemento pero perdió el conflicto: es un problema de cascada. Que no aparezca quiere decir que no seleccionó nada: es un problema de selector, de sintaxis o de carga.

Microprueba semanal 1 · 5–10 minutos

Individual, sin IA y sin apuntes.

  1. Escribe un selector de clase, uno descendiente y uno por atributo.
  2. Ordena por especificidad: p, .aviso p y #principal p.
  3. Una regla aparece tachada en DevTools: explica qué significa y qué revisarías.