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.
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, p→ agrupación: aplica lo mismo a varios selectores separados por comas.nav a→ descendiente: los enlaces que estén dentro de unnav.a:hover→ pseudoclase: cuando el ratón pasa por encima.
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%); }
#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).2emes el doble.rem→ relativo al tamaño de letra de la raíz (<html>, normalmente 16px). Así1rem= 16px y2rem= 32px.vwyvh→ porcentaje del ancho y del alto de la ventana.100vhes todo el alto de la pantalla.
Texto de 1rem (16px)
Texto de 1.5rem (24px)
¿Cuál uso?
rempara tipografías y espaciados: escala bien y es accesible.%para anchos de contenedores.pxpara 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.
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%; }
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:
- Contenido → el texto o la imagen.
- Padding → el relleno interior.
- Border → el borde.
- Margin → la separación exterior.
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; }
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: center + gap
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);
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
destacadodeben 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-boxa 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.