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

Sesión 1

Cómo se aplica CSS y quién gana

Tres horas. Media hora para entender cómo se enlaza una hoja, cómo se elige un selector y qué decide un conflicto entre dos reglas, y dos horas y media dando estilo a tu sitio y diagnosticando quién gana.

Hoy · Hoja de ruta

  1. 1. Aprende: Cómo se enlaza una hoja de estilos, de qué partes se compone una regla, qué familias de selectores existen y qué decide cuál de dos reglas en conflicto se aplica.
  2. 2. Haz: Crea tu hoja, dale el primer estilo al sitio, elige el selector correcto para cinco requisitos y resuelve un conflicto sin !important.
  3. 3. Comprueba: Sabes leer en DevTools qué regla ha ganado y por qué, y no queda un solo !important en tu hoja.

Antes de empezar · 5 minutos, sin apuntes

  1. ¿Qué información pertenece a HTML y cuál esperas que pertenezca a CSS?
  2. ¿Qué ventaja tiene conservar el mismo HTML cuando cambia el diseño?
  3. Señala qué cambiarías para presentar un título en azul sin alterar su significado.

Se explica

25 minutos · conceptos y demostración

Hoy entra el lenguaje entero en su forma mínima: una hoja, una regla, un selector y un criterio para decidir quién gana cuando dos reglas se contradicen. El catálogo de selectores queda como material de consulta dentro del paso que lo usa.

El navegador ya estaba aplicando CSS

Cuando escribiste esto en la UD1:

<h1>PixelStore</h1>

el título se veía grande y en negrita. Eso no es «lo natural»: es una hoja de estilos que trae el navegador de fábrica, la hoja de usuario-agente. Nunca has trabajado sin CSS. Lo que vamos a hacer es tomar el control.

Las tres formas, y por qué usamos una

Forma Cómo se escribe Cuándo
Hoja externa Un archivo .css enlazado con link Siempre, en esta unidad y en la práctica profesional
Hoja interna Un bloque style en el head Casos muy puntuales, como un correo electrónico
En línea Un atributo style en el elemento Prácticamente nunca a mano

La hoja externa gana por tres razones concretas: una sola definición sirve para las cuatro páginas, el navegador se la guarda en caché y no vuelve a descargarla, y el estilo queda separado del contenido, que es la idea entera de estas dos unidades.

<link rel="stylesheet" href="css/styles.css">

Fíjate en que es una ruta relativa, como las de la UD1. Si una página estuviera dentro de una carpeta, sería ../css/styles.css.

Cómo funciona una regla

h1 {
    color: navy;
}
h1       selector      a qué elementos afecta
color    propiedad     qué característica cambio
navy     valor         qué valor le doy

La regla se lee así: «selecciona todos los h1 y cambia su propiedad color». Al conjunto de propiedad y valor se le llama declaración, y van separadas por punto y coma:

body {
    font-family: system-ui, sans-serif;
    line-height: 1.6;
    color: #222;
}
Vista previaLa estructura recibe una presentación propia

PixelStore

Componentes pensados para trabajar y crear.

El contenido HTML no cambia: CSS modifica tipografía, color y ritmo de lectura.

Regla

Un selector más el bloque de declaraciones que se le aplican. Una hoja de estilos es una lista de reglas.

Los comentarios se escriben solo de una forma. // no funciona, aunque el editor a veces lo coloree como si lo hiciera:

/* Sistema tipográfico base */
body {
    font-family: system-ui, sans-serif;
}

Los selectores, en tres familias

Un selector responde a «¿a qué te refieres?», y hay tres maneras de responder.

Por lo que el elemento es. p, a, h1. Afecta a todos los del sitio: útil para las bases, peligroso para algo específico.

Por el papel que le das. Una clase, que se repite en tantos elementos como quieras y describe una función:

<article class="card producto destacado">
.destacado { font-weight: 700; }

Es el selector que más vas a usar. El id también funciona, pero es único en la página y pesa demasiado en los conflictos. Regla práctica: los id son para enlazar y para los label; las clases son para dar estilo.

Por lo que el documento ya declara. Su posición, su estado o sus atributos:

nav a          { }   /* cualquier enlace dentro de nav */
input:required { }   /* el campo es obligatorio */
li:first-child { }   /* es el primer hijo de su padre */
a[href^="http"]{ }   /* enlaces externos */

Pseudo-clase

Un selector que depende del estado o de la posición del elemento, no de su marcado. Se escribe con dos puntos y no existe en el HTML: la calcula el navegador.

Aquí se comprueba el efecto de lo que hiciste en la UD1: si escribiste type="email" en lugar de type="text", ahora tienes un selector. El HTML bien marcado te devuelve selectores, y esa es la razón de que inventar una clase para algo que el documento ya dice sea duplicar la información en dos sitios.

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>

Se ve rojo. La pregunta relevante es por qué.

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 anterior: si das estilo con id, cualquier ajuste posterior con clases no podrá corregirlo.

Cuando hay empate de especificidad decide el orden, y gana la última escrita:

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

Gana el verde. Por eso el orden de tu hoja importa, y por eso conviene escribir de lo general a lo particular.

Herencia

Algunas propiedades pasan de un elemento a sus descendientes, de modo que basta declararlas una vez en body:

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 y cómo se lee un conflicto

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é?».

Esa pregunta se responde en DevTools. Selecciona un elemento y ve a la pestaña Styles: verás las reglas que le afectan ordenadas de la que gana a la que pierde, con las declaraciones derrotadas tachadas y, a la derecha, el archivo y la línea donde se escribió cada una. La pestaña Computed da el valor final de cada propiedad, ya resuelto el conflicto.

Se trabaja

150 minutos · práctica sobre tu propio proyecto

Los dos primeros pasos ponen en marcha la hoja y eligen selectores; los cuatro últimos entran en los conflictos, que es donde se pierde el tiempo cuando no se sabe diagnosticar.

Paso 1 · Tu primer estilo · 25 min

Sobre tu proyecto de la UD1:

  1. Crea la carpeta css/ y dentro styles.css.
  2. Enlázalo en las cuatro páginas.
  3. Cambia la tipografía general del sitio desde body.
  4. Da un color distinto a los encabezados.
  5. Cambia el aspecto de los enlaces.
  6. Comprueba que el estilo se aplica en las cuatro.

Si una página no cambia, no escribas más CSS

Es el error que más tiempo consume la primera semana, y la reacción instintiva es escribir más reglas por si acaso. No sirve de nada: si la hoja no carga, ninguna regla va a funcionar.

Comprueba en este orden: ¿la ruta del link es correcta desde esa página?, ¿el archivo se llama exactamente así, con sus mayúsculas?, ¿lo has guardado? Y la comprobación definitiva: abre DevTools, pestaña Network, recarga, y busca styles.css. Si aparece en rojo con un 404, ya sabes que el problema es la ruta y no el CSS.

Antes de continuar: las cuatro páginas cargan la hoja, comprobado en Network y no por su apariencia, y el HTML no se ha tocado salvo para añadir el link.

Paso 2 · El selector correcto · 35 min

Para cada requisito, escribe el selector que le corresponde. No vale cualquiera que funcione: vale el que expresa lo que pide el enunciado.

2.1 · Ejemplo resuelto

Requisito: los enlaces del pie no deben subrayarse, pero los del contenido sí.

¿Qué me piden seleccionar?
Enlaces, pero solo los de una zona concreta del documento.
¿Cómo está marcada esa zona?
En la UD1 el pie es un footer. Ya tengo por dónde acotar.
¿Descendiente o hijo directo?
Descendiente: los enlaces pueden estar dentro de párrafos o de listas, no necesariamente colgando del footer.
Selector
footer a { text-decoration: none; }

No ha hecho falta inventar ninguna clase. Si el HTML ya distingue esa zona, el selector sale solo.

2.2 · Ahora tú

  1. Todos los enlaces de la navegación principal deben cambiar de aspecto.
  2. El primer producto del catálogo debe destacarse.
  3. Los campos obligatorios del formulario deben distinguirse.
  4. Los enlaces externos deben poder marcarse de forma distinta a los internos.
  5. Solo los párrafos que están dentro de una ficha de producto, no todos los del sitio.
Consultar · las familias de selectores al completo

Por elemento. Afecta a todos los del sitio.

p { line-height: 1.6; }

Por clase. Una clase puede repetirse en muchos elementos, y un elemento puede tener varias.

.destacado { font-weight: 700; }

Por id. Funciona, pero es único y pesa demasiado en los conflictos.

#productos { padding-block: 3rem; }

Descendiente y directo.

nav a {          /* cualquier enlace dentro de nav, a la profundidad que sea */
    text-decoration: none;
}

nav > ul {       /* solo las listas que son hijas directas de nav */
    display: flex;
}

Por atributo.

input[type="email"] {
    border-color: #999;
}

a[href^="http"] {     /* enlaces cuyo href empieza por http: los externos */
    ...
}

Pseudo-clases. Seleccionan por estado o por posición.

a:hover        { }   /* el cursor está encima */
a:focus-visible{ }   /* tiene el foco de teclado */
li:first-child { }   /* es el primer hijo de su padre */
li:last-child  { }   /* es el último */
input:required { }   /* el campo es obligatorio */
input:invalid  { }   /* su valor no cumple la validación */

Agrupar. La coma es «o».

h1, h2, h3 {
    line-height: 1.15;
}

Un fallo típico es olvidarla: h1 h2 significa «un h2 dentro de un h1», que casi nunca existe, y entonces la regla no hace nada.

Estoy atascado · ¿clase o selector estructural?

Pregúntate si la condición ya está escrita en el HTML. Si es «los obligatorios», el HTML ya lo dice con required: usa :required. Si es «el primero», el HTML ya lo dice por su posición: usa :first-child. Si es «los de oferta», eso no está en ninguna parte del marcado y sí necesita una clase.

Inventar una clase para algo que el documento ya declara es duplicar la información en dos sitios, y tarde o temprano dejan de coincidir.

Ver soluciones

1 · nav a, o si tienes varias navegaciones, acota por su etiqueta: nav[aria-label="Navegación principal"] a.

2 · .catalogo article:first-child, con la clase que uses para el contenedor.

3 · input:required, que además cubre los campos que añadas después sin tocar el CSS.

4 · a[href^="http"], porque los internos de tu proyecto son rutas relativas y no empiezan por http.

5 · article p, o mejor .producto p si el catálogo comparte marcado con otras zonas.

Paso 3 · ¿Quién está ganando? · 35 min

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; }

3.1 · Ejemplo resuelto

¿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.

3.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.

Paso 4 · La regla que no hace nada · 15 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

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.

Paso 5 · Cinco selectores reales en tu sitio · 25 min

Lleva al proyecto lo del paso 2. Escribe cinco reglas que usen, cada una, una familia distinta de selector, y anota en un comentario por qué ese y no otro:

  1. Una que acote por una zona semántica de la UD1 (nav, main, footer…).
  2. Una que use una clase que describa un papel, no una apariencia.
  3. Una que se apoye en un atributo que ya está en tu HTML.
  4. Una que use una pseudo-clase de estado o de posición.
  5. Una que agrupe varios selectores con la coma.

Si alguna te obliga a añadir una clase al HTML, pregúntate antes si el documento ya lo decía de otra forma. Si te obliga a inventar un id, es que no era el camino.

Paso 6 · Auditoría de tu propia hoja · 15 min

Recorre styles.css de arriba abajo y responde:

Comprobación Cuántos Qué haces
!important en la hoja
Selectores que empiezan por #
Reglas que no seleccionan nada (comprobado en DevTools)
Clases cuyo nombre describe la apariencia y no el papel

Corrige los cuatro grupos. Los nombres del tipo .azul o .texto-grande se renombran por lo que significan: el día que el azul pase a verde, la clase .azul miente.

Ampliación si has completado el trabajo

Primero termina y comprueba los seis pasos. Los dos retos trabajan con hojas que no has escrito tú, que es como llegan los proyectos reales.

Reto 1 · La hoja heredada

Recibes esta hoja de un proyecto anterior. Funciona, y es un desastre.

#main .content p.text { color: #444 !important; }
#main .content p { color: #888; }
.text { color: #222; }
p { color: #000; }

#nav ul li a { text-decoration: none !important; }
#nav ul li a:hover { text-decoration: underline; }

.boton-azul { background: #1a5fb4; color: white; }
.boton-azul-grande { background: #1a5fb4; color: white; padding: 1rem 2rem; }
#formulario input { border: 1px solid #ccc !important; }

Reescríbela entera con una condición: ningún !important y ningún id como selector de estilo, manteniendo exactamente el mismo resultado visual.

  1. Antes de tocar nada, escribe qué color acaba teniendo un <p class="text"> dentro de #main .content, y por qué. Compruébalo después.
  2. El !important de la navegación tiene un efecto que quizá no era el buscado: averigua qué le ocurre al subrayado del :hover y explícalo.
  3. Las dos clases de botón repiten dos declaraciones. Resuélvelo sin duplicar, y di qué has hecho con el nombre de las clases.
  4. Anota cuántas líneas tiene tu versión frente a la original.

Reto 2 · Seis conflictos, predichos antes de mirar

Para cada pareja, predice por escrito qué regla gana y por qué, antes de probar nada. Después móntalo y comprueba.

# Regla A Regla B Gana Motivo
1 .card p article p
2 p.aviso .aviso
3 #main p .a .b .c .d p
4 a:hover nav a
5 ul li escrito arriba ul li escrito abajo
6 p { color: red !important } #main p { color: blue }

La fila 4 no se decide igual que las demás: piénsala dos veces antes de escribir el motivo.

Objetivo mínimoHoja externa cargada en las cuatro páginas, los cinco selectores del paso 2 resueltos y el conflicto del paso 3 diagnosticado.
Si lo tienesLas cinco reglas reales en tu sitio justificadas y la auditoría de tu hoja con sus cuatro grupos corregidos.
RetoLa hoja heredada reescrita sin !important ni id, y las seis predicciones escritas antes de comprobarlas.

Cierre

5 minutos · comprobación y recuerdo

Lista de verificación de la sesión

  • Existe css/styles.css y está enlazado en las cuatro páginas.
  • Sabes nombrar las tres partes de una regla y comprobar en Network si la hoja se ha cargado.
  • Sabes ordenar elemento, clase e id por especificidad.
  • 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 ni ningún id de estilo en tu hoja.

Antes de cerrar · 3 minutos, sin mirar

  1. ¿Por qué usamos una hoja externa y no un atributo style?
  2. Nombra las tres partes de una regla CSS.
  3. ¿Qué diferencia hay entre nav a y nav > a?
  4. ¿Qué gana: tres clases o un id?
  5. ¿Cuándo decide el orden en que están escritas las reglas?
  6. En DevTools, ¿qué significa que una declaración aparezca tachada, y qué que no aparezca?
Ver respuestas

1 · Una definición sirve para todas las páginas, el navegador la cachea, y el estilo queda separado del contenido.

2 · Selector, propiedad y valor. La propiedad con su valor forman una declaración.

3 · El primero selecciona cualquier enlace dentro del nav, a la profundidad que sea; el segundo, solo los que cuelgan directamente de él.

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

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

6 · 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.