Ya tienes el HTML: sabes qué es un elemento, cómo se anida y qué va en el <head>. Ahora le
toca al aspecto. HTML describe la estructura de la página; CSS describe cómo se ve. Son dos
lenguajes con dos trabajos distintos, y esa separación no es un capricho de diseño: es lo que
hace posible mantener un proyecto sin que cada cambio de color rompa la estructura.
Seguimos con el Overwatch Team Builder. La ficha de Tracer ya existe como HTML; en este capítulo le damos su primera capa de estilo.
Qué es CSS#
CSS son las siglas de Cascading Style Sheets (hojas de estilo en cascada). Es el lenguaje
que le dice al navegador cómo pintar cada elemento: colores, tamaños, tipografía, espaciado. Sin
CSS, el navegador usa sus propios estilos por defecto (el <h1> grande, los enlaces azules y
subrayados), que son funcionales pero no diseñados.
La idea central es esta: el HTML dice qué es cada cosa; el CSS dice cómo se ve. Una
ficha de héroe tiene un título (<h1>), un rol (<p class="hero-rol">) y una lista de
estadísticas (<ul>). Eso es HTML. Que el título sea verde azulado, que el rol aparezca en
mayúsculas pequeñas y que la lista tenga fondo gris es CSS.
Las tres formas de aplicar CSS (y cuál usar)#
Hay tres sitios donde puede vivir el CSS. Los tres funcionan; no todos son igual de mantenibles.
1. Inline: el atributo style#
Puedes escribir CSS directamente en el atributo style de cualquier elemento:
<h1 style="color: teal; border-bottom: 2px solid teal;">Tracer</h1>Funciona. El problema es la escala: si tienes veinte páginas y decides cambiar el color del
título, tienes que abrir veinte ficheros HTML y cambiar el atributo en cada <h1>. Y si el
mismo elemento tiene reglas en el style y en una hoja externa, las del style siempre ganan,
lo que convierte el CSS en difícil de depurar.
2. El elemento <style> en el <head>#
Puedes agrupar todas las reglas en un bloque <style> dentro del <head> de la página:
<head>
<style>
/* selector de tipo: color del texto del <h1> */
h1 { color: teal; }
/* selector de clase: tamaño de letra para los elementos con esa clase */
.hero-rol { font-size: 0.85rem; }
</style>
</head>Mejor que el inline: las reglas están en un solo sitio dentro de ese fichero. Pero siguen viviendo en el HTML. Si añades una segunda página, tienes que copiar el bloque entero —y mantenerlo sincronizado con el primero.
3. Hoja de estilos externa (la forma correcta)#
Un fichero .css independiente, enlazado desde el <head> con <link>:
<head>
<link rel="stylesheet" href="styles.css" />
</head>Esta es la forma que se usa en producción. Tres razones:
- Se reutiliza: todas las páginas del sitio enlazan el mismo
styles.css. Cambias el color del título en un solo sitio y se propaga a todas. - Separa responsabilidades: el HTML describe la estructura; el CSS, el aspecto. Puedes leer y editar cada uno sin tocar el otro.
- Se cachea: el navegador descarga
styles.cssla primera vez que el visitante carga una página, y en las siguientes páginas del mismo sitio lo sirve desde caché sin volver a descargarlo.
A partir de aquí, siempre hoja externa.
Anatomía de una regla CSS#
Una regla CSS tiene esta forma:
selector {
propiedad: valor;
otra-propiedad: otro-valor;
}Pieza a pieza:
- Selector: a qué elementos del HTML afecta esta regla. Puede ser el nombre de una etiqueta
(
h1,p), una clase (.hero-rol) o un id (#cabecera). Lo verás en profundidad en el capítulo siguiente; aquí usamos solo los dos primeros. - Bloque de declaraciones: lo que va entre las llaves
{ }. - Declaración: cada
propiedad: valor;. Termina siempre con punto y coma.
Un ejemplo real para la ficha de Tracer:
/* selector de tipo: afecta a todos los <h1> de la página */
h1 {
/* color del texto en verde azulado */
color: teal;
/* línea de 2 píxeles bajo el título, del mismo color */
border-bottom: 2px solid teal;
/* separación interior entre el texto y esa línea */
padding-bottom: 0.5rem;
}Esta regla dice: “todos los <h1> de la página tendrán el texto en verde azulado, un borde
inferior de dos píxeles y separación interior abajo”. Si añades un segundo <h1> mañana,
recibe el mismo estilo sin tocar el CSS.
Los colores como
tealo las unidades comoremypxlos verás a fondo en el capítulo Color, unidades y tipografía. Aquí los usamos sin profundizar; y las propiedades de caja comomargin,paddingoborder, que dan espacio y separación a los elementos, las verás en Box model y Flexbox.
Selectores de tipo y de clase#
Con lo que sabes de HTML ya puedes usar los dos selectores más habituales:
Selector de tipo: el nombre de la etiqueta. Afecta a todos los elementos de ese tipo en la página.
/* selector de tipo: afecta a todos los <p> de la página */
p {
/* altura de línea: espacio entre líneas de texto (1.6 = cómodo de leer) */
line-height: 1.6;
/* color del texto en gris oscuro */
color: #333;
}Eso aplica line-height y color a todos los párrafos de la página.
Selector de clase: un punto seguido del nombre de la clase. Afecta solo a los elementos que
tengan ese atributo class.
/* selector de clase: solo los elementos con class="hero-rol" */
.hero-rol {
/* tamaño de letra más pequeño que el párrafo normal */
font-size: 0.8rem;
/* convierte el texto a mayúsculas sin cambiarlo en el HTML */
text-transform: uppercase;
/* espacio extra entre letras, da aspecto de etiqueta */
letter-spacing: 0.08em;
}Y en el HTML:
<!-- class="hero-rol" enlaza este párrafo con la regla de arriba -->
<p class="hero-rol">Daño</p>El selector de clase es más preciso: si tienes tres párrafos y solo quieres que uno tenga ese estilo, le pones la clase y ya.
class e id: los ganchos del HTML#
Para que el CSS pueda apuntar a elementos concretos, el HTML les pone etiquetas identificativas.
class es reutilizable: puedes poner la misma clase en varios elementos y la regla CSS los
afecta a todos. Es lo más habitual.
<p class="hero-rol">Daño</p>
<!-- misma clase, mismo estilo -->
<p class="hero-rol">Apoyo</p>id debe ser único en la página: solo un elemento puede tener ese id. En CSS se apunta con
#nombre-del-id. Se usa menos para estilos (las clases son más flexibles) y más para anclas de
navegación en la misma página (<a href="#estadisticas">).
<!-- id="estadisticas": identificador único en la página -->
<h2 id="estadisticas">Estadísticas</h2>/* selector de id: solo el elemento con id="estadisticas" */
#estadisticas {
/* línea de color a la izquierda, como un marcador lateral */
border-left: 3px solid teal;
/* separación entre esa línea y el texto del encabezado */
padding-left: 0.75rem;
}La norma práctica: usa clases para estilos, usa ids para anclas. Cuando empieces a trabajar con JavaScript también lo agradecerás: los ids son fáciles de localizar en el árbol del documento.
La cascada: qué pasa cuando dos reglas chocan#
El nombre completo de CSS es Cascading Style Sheets. La cascada es la regla que decide qué estilo gana cuando dos declaraciones se contradicen.
La especificidad: un selector de clase gana a uno de tipo.
/* selector de tipo: afecta a todos los <p> */
p { color: gray; }
/* selector de clase: más específico, gana al de tipo */
.destacado { color: teal; }Un <p class="destacado"> tendrá el texto en verde azulado: la clase es más específica.
Si no hubiera clase, sería gris.
El orden cuando la especificidad es igual: si dos reglas tienen el mismo peso, gana la que aparece más tarde en el fichero.
/* misma especificidad que la regla de abajo */
h1 { color: gray; }
/* gana esta: aparece después en el fichero */
h1 { color: teal; }La herencia: algunas propiedades se heredan de padre a hijos automáticamente. color y
font-family son las más comunes: si las declaras en body, todos los elementos de la página
las reciben salvo que tengan su propia regla.
body {
/* todos los descendientes heredarán esta tipografía */
font-family: system-ui, sans-serif;
/* todos los descendientes heredarán este color de texto */
color: #1c1b22;
}Con esto, todos los párrafos, encabezados y listas heredan la fuente y el color del texto sin necesidad de declararlo en cada uno. Cuando un elemento sí tiene su propia regla de color, su regla gana sobre la heredada.
No todas las propiedades se heredan: border, padding o margin no se propagan. Lo
aprenderás por la práctica; por ahora, quédate con que color y font-family sí lo hacen.
La cascada y la herencia son dos mecanismos distintos aunque trabajan juntos. La cascada
es el algoritmo que resuelve conflictos cuando varias reglas apuntan al mismo elemento: gana
la más específica (inline > id > clase > tipo) y, a igual especificidad, la que aparece más
tarde en el fichero. La herencia es otra cosa: ciertas propiedades como color o
font-family pasan automáticamente de un elemento padre a sus descendientes. Cuando el nombre
CSS dice Cascading, se refiere al primer mecanismo, no al segundo.
Pruébalo#
Esta es la ficha de Tracer con su primera hoja de estilos. Abre la pestaña /styles.css y
cambia los valores que se mencionan en los comentarios del HTML: modifica el color del h1,
ajusta el tamaño de .hero-rol y observa cómo los selectores de tipo y de clase afectan a
distintos elementos. Los cambios son inmediatos en el preview.
Comprueba lo que sabes#
Pregunta 1 de 5
¿Cuál es la diferencia principal entre CSS inline, en un `<style>` y en una hoja externa?
Ahora, en local#
El HTML de la ficha ya está hecho. Tu tarea es escribir la primera hoja de estilos y enlazarla.
Ejercicio · hazlo en local
La primera hoja de estilos de Tracer
El HTML de la ficha ya está hecho. Tu tarea es darle estilo: crea el fichero styles.css, enlázalo con <link> en el <head> y escribe unas reglas con selectores de tipo y de clase para que la página se vea limpia. No hay Flexbox ni Grid todavía: solo estructura y aspecto básico.
Paso 1: Que se vea con estilo
- La página tiene color y tipografía aplicados.
- Vale con estilos inline (style="...") o con un <style> en el <head>.
- No hace falta hoja externa todavía.
Paso 2: Hoja externa correcta
- El CSS está en un fichero styles.css enlazado con <link rel="stylesheet">.
- El HTML no tiene ningún atributo style ni etiqueta <style>.
- Hay reglas con selectores de tipo (h1, h2, p) que afectan a varios elementos a la vez.
- La clase .rol usa un selector de clase y solo afecta al elemento de rol.
Paso 3: Clases con sentido y cascada aprovechada
- Los nombres de clase describen qué es el elemento, no cómo se ve (.hero-rol, no .texto-pequeño).
- Las reglas de tipo dan la base; las clases sobreescriben solo lo necesario.
- Un comentario explica por qué la clase gana a la regla de tipo (especificidad).
- El HTML está completamente limpio de estilos: solo estructura.
Cómo hacerlo en local
Clona el repositorio del curso, entra en la carpeta del ejercicio y abre el
index.html en tu navegador. Toda tu solución va en
solucion.js.
git clone <repo>
cd exercises/nivel-1/que-es-css
# abre index.html en el navegador y edita solucion.js Soluciones comentadas#
La de nivel OK es un fichero HTML (mezcla estructura y estilos). Las de “mejor” y “excelente”
son el fichero styles.css por separado. Lee los comentarios de cada nivel para entender qué
cambia y por qué importa.
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<title>Tracer — Overwatch Team Builder</title>
<style>
h1 {
color: teal;
font-size: 2rem;
}
p {
font-size: 1rem;
color: #333;
}
ul {
background: #f5f5f5;
padding: 12px 24px;
}
</style>
</head>
<body>
<h1 style="border-bottom: 2px solid teal;">Tracer</h1>
<p class="rol" style="font-weight: bold; text-transform: uppercase; font-size: 0.85rem;">Daño</p>
<h2>Estadísticas</h2>
<ul>
<li>Partidas: <strong>120</strong></li>
<li>Victorias: <strong>78</strong></li>
<li>Winrate: <strong>65 %</strong></li>
</ul>
<h2>Descripción</h2>
<p>
Tracer es la heroína de daño más ágil del plantel. Su parpadeo la mueve
al instante; su retroceso deshace los últimos segundos de su posición.
Su trabajo es presionar la retaguardia rival y desaparecer antes de que
le respondan.
</p>
</body>
</html> Por qué este nivel
- Hay estilo aplicado y la página se ve bien: ese es el objetivo mínimo, y lo cumple.
- Pero los estilos están repartidos en dos sitios a la vez: un `<style>` en el `<head>` y atributos `style` directamente en algunos elementos. Si mañana hay diez páginas y quieres cambiar el color del título, tienes que editar diez ficheros HTML.
- El atributo `style` en el `<h1>` tiene la máxima especificidad posible: nada de lo que pongas en un fichero externo puede sobreescribirlo a no ser que uses `!important`, lo que convierte el CSS en un juego de lucha de pesos. Es exactamente lo que queremos evitar.
- La separación entre estructura (HTML) y aspecto (CSS) existe por este motivo: cuando los dos están mezclados, mantener uno obliga a tocar el otro.
body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 2rem auto;
padding: 0 1rem;
color: #1c1b22;
}
h1 {
font-size: 2rem;
color: teal;
border-bottom: 2px solid teal;
padding-bottom: 0.5rem;
}
h2 {
font-size: 1.2rem;
color: #333;
margin-top: 1.5rem;
}
.rol {
font-weight: bold;
text-transform: uppercase;
font-size: 0.85rem;
color: #666;
letter-spacing: 0.05em;
}
ul {
background: #f5f5f5;
padding: 0.75rem 1.5rem;
border-radius: 6px;
}
p {
line-height: 1.6;
} Por qué es mejor que el anterior
- El CSS está en su propio fichero (`styles.css`) enlazado con `<link rel="stylesheet" href="styles.css">` en el `<head>`. El HTML no tiene ni un `style=""` ni un `<style>`: la separación es completa.
- Los selectores de tipo (`h1`, `h2`, `p`, `ul`) aplican la base a todos esos elementos de la página de un golpe. Si añades un segundo `<h2>` mañana, hereda los estilos sin tocar el CSS.
- La clase `.rol` apunta solo al párrafo del rol: más específica que `p`, así que sobreescribe el color y el tamaño de ese elemento concreto sin afectar a los demás párrafos.
- Este nivel y el excelente se ven casi igual en pantalla. La diferencia está en la escalabilidad: cuánto trabajo cuesta añadir un segundo héroe.
/* Las reglas de tipo (h1, h2, p, ul) dan la base.
Las clases (.hero-rol, .hero-stats, .hero-descripcion) añaden
o sobreescriben solo lo que diferencia a este elemento concreto.
Gana la clase: más específica que el selector de tipo. */
body {
font-family: system-ui, sans-serif;
max-width: 40rem;
margin: 2rem auto;
padding: 0 1rem;
color: #1c1b22;
line-height: 1.5;
}
h1 {
font-size: 2rem;
color: teal;
border-bottom: 2px solid teal;
padding-bottom: 0.5rem;
margin-bottom: 0.25rem;
}
h2 {
font-size: 1.1rem;
color: #333;
margin-top: 1.75rem;
}
p {
line-height: 1.6;
margin: 0.25rem 0 0;
}
/* Clase .hero-rol: sobreescribe el color y el tamaño por defecto de <p> */
.hero-rol {
font-weight: 700;
text-transform: uppercase;
font-size: 0.8rem;
color: teal;
letter-spacing: 0.08em;
}
/* Clase .hero-stats: da fondo y relleno solo a esta lista concreta,
no a todas las <ul> de la página.
Si mañana añadimos una segunda lista (habilidades), no se verá afectada. */
.hero-stats {
background: #f0fafa;
border-left: 3px solid teal;
padding: 0.75rem 1.5rem;
border-radius: 0 6px 6px 0;
list-style: none;
margin: 0;
}
.hero-descripcion {
color: #444;
} Por qué es mejor que el anterior
- Los nombres de clase describen qué es el elemento, no cómo se ve: `.hero-rol`, `.hero-stats`, `.hero-descripcion`. Si dentro de un mes cambias el color del rol de teal a naranja, el nombre sigue teniendo sentido. Una clase `.texto-pequeño-teal` quedaría mentirosa en cuanto cambias cualquiera de sus dos características.
- Las reglas de tipo (`h1`, `h2`, `p`) dan la base general. Las clases sobreescriben solo lo que diferencia a ese elemento concreto. Esta es la cascada en acción: la clase gana al tipo por especificidad, así que puedes leer el CSS de arriba a abajo como una jerarquía.
- El comentario en `.hero-stats` explica por qué esa clase solo afecta a esa lista y no a futuras listas que se añadan. Un comentario que explica la intención —no lo que ya se ve en el código— vale su peso en oro cuando lo lees seis meses después.
- El HTML del excelente está completamente limpio: solo estructura semántica. Todo el aspecto vive en `styles.css`. Puedes intercambiar la hoja de estilos y la página tiene otro aspecto sin tocar el HTML.