Curso de CSS

1. ¿Qué es CSS?

CSS son las siglas de Cascading Style Sheets, «hojas de estilo en cascada». Es el lenguaje que define cómo se ve el contenido escrito en HTML.

Si HTML es el esqueleto de la página (qué hay y en qué orden), CSS es su aspecto: los colores, las tipografías, los espacios, los bordes y la colocación de cada elemento en la pantalla.

¿Qué se puede controlar con CSS?

  • Colores de texto y de fondo.
  • Tipografías, tamaños y espaciado del texto.
  • Márgenes, rellenos y bordes.
  • La maquetación: colocar los elementos en columnas, rejillas, etc.
  • Diseño adaptable a móvil (responsive).
  • Transiciones y animaciones.

¿Por qué «en cascada»?

Porque los estilos se van aplicando en cadena y unos pueden sobrescribir a otros. Cuando varias reglas afectan al mismo elemento, el navegador decide cuál gana según su especificidad y el orden en que están escritas. Lo veremos al hablar de selectores.

Separar el contenido (HTML) del aspecto (CSS) es una gran ventaja: puedes cambiar por completo el diseño de un sitio entero tocando un solo archivo.

2. La regla CSS

Todo en CSS se escribe con la misma estructura, llamada regla. Una regla tiene un selector (a quién afecta) y un bloque de declaraciones (qué le hacemos), entre llaves:

selector {
  propiedad: valor;
}

Un ejemplo real:

p {
  color: blue;
  font-size: 16px;
}

Se lee así: «a todos los párrafos (p), ponles el color azul y un tamaño de letra de 16 píxeles». Fíjate en los detalles:

  • El selector va antes de la llave: p.
  • Cada declaración es una pareja propiedad: valor.
  • Los dos puntos (:) separan la propiedad de su valor.
  • Cada declaración termina en punto y coma (;). Olvidarlo es el error más típico.
Resultado en el navegador

Este párrafo es azul y mide 16px.

Comentarios

Para dejar notas en el código (que el navegador ignora) se usa /* ... */:

/* Estilos de la cabecera */
header {
  background-color: orangered;
}

3. Cómo aplicar CSS

Hay tres formas de añadir CSS a un documento HTML. Conviene conocer las tres, aunque en la práctica se usa casi siempre la última.

1) En línea (inline)

Con el atributo style directamente en la etiqueta. Solo afecta a ese elemento:

<p style="color: red;">Párrafo rojo</p>

Se desaconseja: mezcla contenido y diseño, y no se puede reutilizar.

2) Interno

Con la etiqueta <style> dentro del <head>. Afecta solo a esa página:

<head>
  <style>
    p { color: red; }
  </style>
</head>

3) Externo (el recomendado)

En un archivo aparte con extensión .css, que se enlaza desde el <head> con la etiqueta <link>:

<head>
  <link rel="stylesheet" href="css/estilos.css">
</head>

Es la mejor opción porque un mismo archivo sirve para todas las páginas del sitio: cambias un color ahí y se actualiza en toda la web.

4. Selectores básicos

El selector indica a qué elementos se aplica la regla. Estos son los fundamentales:

Selector de etiqueta

Afecta a todas las etiquetas de ese tipo:

h1 { color: navy; }

Selector de clase

Empieza por punto y afecta a los elementos con ese class. Es el más usado, porque una clase se puede repetir tantas veces como quieras:

.destacado { background-color: yellow; }
<p class="destacado">Texto destacado</p>

Selector de id

Empieza por almohadilla y afecta al elemento con ese id. El id debe ser único en la página:

#cabecera { height: 100px; }

Otros selectores útiles

  • * → el universal, afecta a todos los elementos.
  • h1, h2, pagrupación: aplica lo mismo a varios selectores separados por comas.
  • nav adescendiente: los enlaces que estén dentro de un nav.
  • a:hoverpseudoclase: cuando el ratón pasa por encima.
Resultado en el navegador

Texto con la clase .destacado

Texto afectado por el selector de etiqueta

La especificidad

Si dos reglas afectan al mismo elemento, gana la más específica. El orden de fuerza, de menor a mayor, es: etiqueta < clase < id. Y si dos reglas tienen la misma especificidad, gana la que esté escrita después.

5. Colores

Los colores se indican con las propiedades color (color del texto) y background-color (color de fondo). Hay varias formas de escribir un color:

Por nombre

CSS reconoce unos 140 nombres en inglés: red, blue, orangered, navy

h1 { color: orangered; }

Hexadecimal

El más usado. Empieza por # y lleva 6 cifras: dos para el rojo, dos para el verde y dos para el azul.

h1 { color: #ff4500; }

Si las cifras se repiten por parejas se puede abreviar a 3: #ffcc00 equivale a #fc0.

RGB y RGBA

Se indican las cantidades de rojo, verde y azul (de 0 a 255). La versión RGBA añade un cuarto valor, la transparencia (de 0 a 1):

h1 { color: rgb(255, 69, 0); }
.caja { background-color: rgba(255, 69, 0, 0.3); }

HSL

Define el color por tono, saturación y luminosidad. Es muy cómodo para crear variaciones de un mismo color:

h1 { color: hsl(16, 100%, 50%); }
Resultado en el navegador

#ff4500 rgba 0.3 navy

Texto con color: #ff4500;

6. Medidas y unidades

Casi todas las propiedades de CSS necesitan una medida: un tamaño de letra, un ancho, un margen… Las unidades se dividen en absolutas y relativas.

Unidades absolutas

Tienen un tamaño fijo. La única que se usa de verdad en pantalla es el píxel:

p { font-size: 16px; }
.caja { width: 300px; }

Es precisa y predecible, pero no se adapta si el usuario cambia el tamaño de letra de su navegador.

Unidades relativas

Su valor depende de otra cosa, y por eso son las mejores para diseño adaptable:

  • % → porcentaje respecto al elemento padre. width: 50% es la mitad del contenedor.
  • em → relativo al tamaño de letra del propio elemento (o del padre). 2em es el doble.
  • rem → relativo al tamaño de letra de la raíz (<html>, normalmente 16px). Así 1rem = 16px y 2rem = 32px.
  • vw y vh → porcentaje del ancho y del alto de la ventana. 100vh es todo el alto de la pantalla.
Resultado en el navegador

Texto de 1rem (16px)

Texto de 1.5rem (24px)

Caja con width: 50%

¿Cuál uso?

  • rem para tipografías y espaciados: escala bien y es accesible.
  • % para anchos de contenedores.
  • px para detalles finos que no deben cambiar (bordes de 1px, por ejemplo).

7. Margen y relleno

Son las dos propiedades que crean espacio, y confundirlas es uno de los errores más habituales al empezar:

  • margin → el espacio por fuera del elemento, lo separa de sus vecinos.
  • padding → el espacio por dentro, entre el borde y el contenido.
Resultado en el navegador
Contenido. El gris de fuera es el margin; el hueco entre el borde rojo y este texto es el padding.

Formas de escribirlos

Ambas admiten de uno a cuatro valores:

margin: 10px;              /* los 4 lados */
margin: 10px 20px;         /* arriba-abajo | izquierda-derecha */
margin: 10px 20px 30px;    /* arriba | lados | abajo */
margin: 10px 20px 30px 40px; /* arriba | derecha | abajo | izquierda */

El orden de los cuatro valores va en el sentido de las agujas del reloj: arriba, derecha, abajo, izquierda.

También se pueden usar por separado: margin-top, padding-left, etc.

Truco: centrar un bloque

Un elemento de bloque con ancho definido se centra poniendo los márgenes laterales en auto:

.contenedor {
  width: 800px;
  margin: 0 auto;
}

8. Bordes

La propiedad border dibuja una línea alrededor del elemento. Se escribe con tres valores: grosor, estilo y color:

.caja {
  border: 2px solid #333;
}

Estilos disponibles

Los más usados son solid (continuo), dashed (a rayas), dotted (a puntos) y none (sin borde).

Esquinas redondeadas

Con border-radius. Si se pone un valor muy alto (o el 50%), se consigue un círculo:

.caja { border-radius: 8px; }
.avatar { border-radius: 50%; }
Resultado en el navegador
solid
dashed
dotted
radius 10px
50%

Un solo lado

Se puede aplicar a un lado concreto, muy útil para subrayados o separadores:

h2 { border-bottom: 3px solid orangered; }

9. El modelo de caja

En CSS todo elemento es una caja rectangular, formada por cuatro capas, de dentro hacia fuera:

  1. Contenido → el texto o la imagen.
  2. Padding → el relleno interior.
  3. Border → el borde.
  4. Margin → la separación exterior.
Las capas de la caja
margin
border
padding
contenido

El problema del ancho

Por defecto, cuando pones width: 300px, esos 300px son solo del contenido: el padding y el borde se suman por fuera. Así, esta caja ocupa en realidad 350px:

.caja {
  width: 300px;
  padding: 20px;   /* +20 a cada lado */
  border: 5px solid;  /* +5 a cada lado */
}
/* Ancho real = 300 + 40 + 10 = 350px */

La solución: box-sizing

Con box-sizing: border-box le decimos al navegador que el width incluya el padding y el borde. Ahora la caja mide exactamente 300px:

* {
  box-sizing: border-box;
}

Esta regla, aplicada a todos los elementos con el selector universal, se pone al principio de casi todas las hojas de estilo modernas. Te ahorrará muchísimos quebraderos de cabeza.

10. Posicionamiento

La propiedad position determina cómo se coloca un elemento en la página. Junto a ella se usan top, right, bottom y left para desplazarlo.

static (por defecto)

Todos los elementos son static si no dices lo contrario: se colocan en el flujo normal del documento, uno detrás de otro. top, left, etc. no tienen efecto.

relative

El elemento se desplaza respecto a su propia posición original, pero sigue ocupando su hueco en el flujo:

.caja { position: relative; top: 20px; left: 20px; }

absolute

El elemento sale del flujo (deja de ocupar espacio) y se sitúa respecto al antepasado posicionado más cercano; si no hay ninguno, respecto a la página.

De ahí el truco más usado en CSS: se pone position: relative al padre para que el hijo absolute se coloque dentro de él.

.padre { position: relative; }
.hijo  { position: absolute; top: 10px; right: 10px; }
Resultado en el navegador
absolute arriba-izquierda absolute abajo-derecha centrado

fixed

Como absolute, pero se posiciona respecto a la ventana del navegador y no se mueve al hacer scroll. Es lo que se usa para menús o botones que quedan siempre visibles:

.boton-arriba {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

sticky

Un híbrido: el elemento se comporta con normalidad hasta que llega a la posición indicada, y entonces se queda pegado mientras haces scroll. El índice lateral de este curso funciona así:

.indice {
  position: sticky;
  top: 1rem;
}

z-index

Cuando varios elementos posicionados se superponen, z-index decide cuál va delante: a mayor número, más arriba en la pila.

.modal { position: fixed; z-index: 100; }

11. Flexbox

Flexbox es un sistema de maquetación pensado para distribuir elementos en una dirección: una fila o una columna. Es la forma moderna de alinear y repartir espacio.

Para empezar, se convierte el contenedor en flexible. Sus hijos pasan a ser elementos flex y se colocan automáticamente en fila:

.contenedor { display: flex; }

Los dos ejes

  • Eje principal → la dirección en la que se colocan (horizontal por defecto). Se controla con justify-content.
  • Eje secundario → el perpendicular (vertical por defecto). Se controla con align-items.

Propiedades del contenedor

.contenedor {
  display: flex;
  flex-direction: row;        /* row | column */
  justify-content: center;    /* flex-start | center | space-between | space-around */
  align-items: center;        /* flex-start | center | stretch */
  gap: 1rem;                  /* separación entre elementos */
  flex-wrap: wrap;            /* permite saltar de línea */
}
justify-content: space-between
1 2 3

justify-content: center + gap

1 2 3

El centrado perfecto

Combinando las dos propiedades se centra cualquier cosa, horizontal y verticalmente:

.contenedor {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

Lo tienes explicado paso a paso en el blog: Cómo centrar cualquier elemento con Flexbox.

12. Grid

Si Flexbox trabaja en una dirección, Grid lo hace en dos a la vez: filas y columnas. Es la herramienta ideal para maquetar la estructura completa de una página.

.contenedor {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 1rem;
}

Ese ejemplo crea dos columnas: una fija de 200px y otra que ocupa el resto.

La unidad fr

fr significa «fracción del espacio disponible» y es exclusiva de Grid. Con 1fr 1fr 1fr tienes tres columnas iguales.

La función repeat()

Evita repetir valores. Estas dos líneas son idénticas:

grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr)
1
2
3
4
5
6

Rejillas que se adaptan solas

Esta es una de las líneas más útiles de CSS moderno. Crea tantas columnas como quepan, con un ancho mínimo, y salta de línea automáticamente sin necesidad de media queries:

.contenedor {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1rem;
}

Es exactamente lo que usa la rejilla de cursos de esta web.

¿Grid o Flexbox?

  • Flexbox → para una fila o una columna: menús, barras de botones, alinear elementos.
  • Grid → para estructuras de dos dimensiones: la maquetación general, galerías, rejillas de tarjetas.

No compiten: en la práctica se usan juntos, Grid para el esqueleto y Flexbox para los detalles.

13. Ejercicios

Practica lo aprendido. Crea un archivo .html con su .css enlazado, y ve comprobando el resultado en el navegador. Intenta resolverlos por tu cuenta antes de abrir la solución.

Ejercicio 1. Tu primera hoja de estilos Básico

Crea un archivo estilos.css, enlázalo desde tu HTML y consigue que:

  • Todos los párrafos sean de color gris oscuro y de 18px.
  • Los <h1> sean de color naranja y estén centrados.
Ver solución
<!-- En el HTML, dentro del head -->
<link rel="stylesheet" href="estilos.css">
/* estilos.css */
p {
  color: #333;
  font-size: 18px;
}

h1 {
  color: orangered;
  text-align: center;
}

Ejercicio 2. Clases e id Básico

Partiendo de este HTML, escribe el CSS necesario:

<h1 id="titulo">Mi web</h1>
<p class="destacado">Párrafo importante</p>
<p>Párrafo normal</p>
<p class="destacado">Otro importante</p>
  • El título debe tener fondo negro y letra blanca.
  • Los párrafos con clase destacado deben ir en negrita y con fondo amarillo.
  • El párrafo normal no debe cambiar.
Ver solución
#titulo {
  background-color: black;
  color: white;
}

.destacado {
  font-weight: bold;
  background-color: yellow;
}

Ejercicio 3. Colores Básico

Crea tres cajas (tres <div>) con el mismo color de fondo rojo anaranjado, pero escrito de tres formas distintas: por nombre, en hexadecimal y en RGB. Añade una cuarta caja con ese mismo color al 30% de opacidad usando RGBA.

Ver solución
.caja1 { background-color: orangered; }
.caja2 { background-color: #ff4500; }
.caja3 { background-color: rgb(255, 69, 0); }
.caja4 { background-color: rgba(255, 69, 0, 0.3); }

Ejercicio 4. Margen y relleno Básico

Crea una caja con borde que tenga:

  • 20px de relleno por dentro.
  • 40px de separación por arriba y por abajo, y 0 por los lados.
  • Un ancho de 600px y que quede centrada en la página.
Ver solución
.caja {
  width: 600px;
  padding: 20px;
  margin: 40px auto;   /* 40 arriba-abajo, auto a los lados = centrado */
  border: 1px solid #333;
}

Ejercicio 5. Una tarjeta Medio

Diseña una tarjeta con: fondo blanco, borde gris fino, esquinas redondeadas de 10px, relleno interior de 1.5rem y un ancho de 300px. Dentro, un título y un párrafo. Añade además un avatar circular usando border-radius.

Ver solución
.tarjeta {
  width: 300px;
  background-color: white;
  border: 1px solid #ddd;
  border-radius: 10px;
  padding: 1.5rem;
}

.avatar {
  width: 80px;
  height: 80px;
  border-radius: 50%;
}

Ejercicio 6. El modelo de caja Medio

Tienes esta regla:

.caja {
  width: 400px;
  padding: 30px;
  border: 10px solid black;
}

Responde y corrige:

  • ¿Cuántos píxeles ocupa realmente la caja a lo ancho?
  • Añade lo necesario para que ocupe exactamente 400px sin quitar el padding ni el borde.
Ver solución

Ocupa 480px: 400 de contenido + 60 de padding (30 a cada lado) + 20 de borde (10 a cada lado).

.caja {
  width: 400px;
  padding: 30px;
  border: 10px solid black;
  box-sizing: border-box;  /* ahora sí mide 400px en total */
}

Ejercicio 7. Posicionamiento Medio

Practica con position:

  • Crea una caja con una etiqueta «Nuevo» pegada a su esquina superior derecha (la etiqueta debe posicionarse dentro de la caja, no de la página).
  • Añade un botón «Subir» que se quede fijo en la esquina inferior derecha de la pantalla al hacer scroll.
Ver solución
.producto {
  position: relative;   /* la clave: el padre se posiciona */
}

.etiqueta {
  position: absolute;
  top: 10px;
  right: 10px;
}

.boton-subir {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

Ejercicio 8. Menú con Flexbox Medio

Maqueta una cabecera con Flexbox en la que el logotipo quede a la izquierda y el menú de navegación a la derecha, ambos alineados verticalmente al centro. Separa los enlaces del menú 1.5rem entre sí.

<header class="cabecera">
  <img class="logo" src="logo.png" alt="Logo">
  <nav class="menu">
    <a href="#">Inicio</a>
    <a href="#">Cursos</a>
    <a href="#">Contacto</a>
  </nav>
</header>
Ver solución
.cabecera {
  display: flex;
  justify-content: space-between;  /* separa logo y menú */
  align-items: center;
  padding: 1rem 2rem;
}

.menu {
  display: flex;
  gap: 1.5rem;
}

Ejercicio 9. Proyecto final: galería adaptable Avanzado

Crea una galería de 6 tarjetas que reúna todo lo aprendido:

  • Usa Grid para la rejilla, con tarjetas de 250px mínimo que se reorganicen solas al cambiar el ancho de la ventana (sin media queries).
  • Separación de 1.5rem entre tarjetas.
  • Cada tarjeta: fondo blanco, borde redondeado, relleno y una imagen arriba.
  • Dentro de cada tarjeta, usa Flexbox en columna para que el botón quede siempre abajo, aunque los textos tengan distinta longitud.
  • Aplica box-sizing: border-box a todo el documento.
Ver solución
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.galeria {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1.5rem;
  width: 90%;
  max-width: 1100px;
  margin: 2rem auto;
}

.tarjeta {
  display: flex;
  flex-direction: column;   /* apila en columna */
  background-color: white;
  border: 1px solid #ddd;
  border-radius: 10px;
  padding: 1rem;
}

.tarjeta img {
  width: 100%;
  border-radius: 6px;
}

.tarjeta p {
  flex-grow: 1;   /* el texto se estira y empuja el botón abajo */
  margin: 1rem 0;
}

.tarjeta .boton {
  background-color: orangered;
  color: white;
  text-align: center;
  padding: .7rem;
  border-radius: 6px;
  text-decoration: none;
}

14. Proyectos y recursos

Proyectos de ejemplo

Enlaces útiles

Cuentas de Instagram

  • creativewebelements → gradientes, botones, sombras, etc.