Flexbox: el maquetador de una dimensión
Flexbox (display: flex) organiza los hijos de un contenedor
en una sola dirección: fila o columna. Es la herramienta perfecta para
barras de navegación, filas de tarjetas, pies de página… cualquier componente lineal.
.menu {
display: flex; /* activa el modo flex */
gap: 16px; /* espacio entre ítems */
}
1.1 · Los dos ejes
Todo flexbox tiene dos ejes y conviene nombrarlos bien:
- Eje principal: la dirección en la que fluyen los ítems. Por defecto es la fila (
flex-direction: row). - Eje cruzado: perpendicular al principal.
| Propiedad | Controla | Valores típicos |
|---|---|---|
justify-content | Alineación en el eje principal | center, space-between, space-evenly, flex-end |
align-items | Alineación en el eje cruzado | stretch (por defecto), center, flex-start, baseline |
flex-direction | Dirección del eje principal | row, column |
flex-wrap | Saltar de línea si no caben | nowrap, wrap |
gap | Espacio entre ítems | cualquier longitud: 12px, 1rem… |
1.2 · Recetas infalibles
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
.modal {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
1.3 · Propiedades de los ítems
.card { flex: 1; } /* crece por igual hasta llenar la fila */
.lateral { flex: 0 0 220px; } /* no crece, no encoge, ancho fijo */
.especial { align-self: flex-end; } /* excepción puntual */
flex: 1 1 240px significa «base de 240px, permite encoger y
crecer». Con flex-wrap: wrap en el padre consigues tarjetas que saltan de línea
solas cuando no caben: responsive sin media queries.CSS Grid: plantillas bidimensionales
Mientras Flexbox piensa en líneas, CSS Grid (display: grid)
piensa en cuadrículas completas: filas Y columnas a la vez. Es ideal para galerías,
dashboards y el esqueleto global de una página.
.galeria {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 columnas iguales */
gap: 16px;
}
2.1 · La unidad mágica: fr
1fr es una fracción del espacio libre. Con
200px 1fr 1fr reservas 200px para el lateral y repartes el resto en dos mitades:
algo imposible de calcular cómodamente con porcentajes.
2.2 · Ocupar varias casillas
.destacada {
grid-column: span 2; /* ocupa 2 columnas */
grid-row: span 2; /* ocupa 2 filas */
}
2.3 · El patrón profesional: auto-fit + minmax
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}
/* «columnas de mínimo 220px que se estiran por igual;
crea o retira pistas automáticamente según el ancho» */
2.4 · Plantillas con áreas
.page {
display: grid;
grid-template-areas:
"cabecera cabecera"
"menu contenido"
"pie pie";
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
<header> { grid-area: cabecera }
<nav> { grid-area: menu }
<main> { grid-area: contenido }
<footer> { grid-area: pie }
Posicionamiento: relative, absolute, fixed y sticky
| Valor | Comportamiento | Uso típico |
|---|---|---|
static | El normal; ignora top/right/bottom/left | Es el valor por defecto |
relative | Se desplaza desde su sitio original conservando su hueco en el flujo | Ajustes finos; contenedor de absolutos |
absolute | Sale del flujo y se ancla al ancestro posicionado más cercano | Insignias, iconos decorativos |
fixed | Anclado a la ventana del navegador; ni rota con el scroll | Banners flotantes, botón «subir» |
sticky | relative hasta cruzar un umbral (top: 0) y después fixed | Cabeceras que se quedan pegadas |
3.1 · La pareja relative + absolute
Un hijo absoluto busca al pariente más cercano con position distinto de
static. Si nadie lo tiene, se ancla al documento entero — el clásico susto de
principiante. La receta estándar: padre relative, hijo absolute:
.tarjeta { position: relative; }
.badge {
position: absolute;
top: -10px;
right: -10px;
}
3.2 · Sticky, el favorito de las navbars
header {
position: sticky;
top: 0; /* imprescindible: define el umbral */
z-index: 100; /* por encima del contenido */
}
z-index solo surte efecto entre elementos posicionados.
Si tu capa flotante queda debajo de otra, revisa que ambas tengan position
y compara sus z-index.Responsive mobile-first y media queries
4.1 · La base: la meta viewport
Sin esta línea en el <head>, los móviles simulan un escritorio de 980px
y hacen zoom: todo tu responsive se pierde.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
4.2 · Media queries: CSS condicional
@media (min-width: 768px) {
/* estas reglas SOLO se aplican a partir de 768px */
.features { grid-template-columns: repeat(3, 1fr); }
}
4.3 · Mobile-first: el orden profesional
Escribe primero los estilos del móvil (lo pequeño) y amplía con
min-width. El código base sirve al 70 % de las visitas y las reglas grandes
solo cargan donde aportan.
.features { display: grid;
grid-template-columns: repeat(3, 1fr); }
@media (max-width: 600px) {
.features { grid-template-columns: 1fr; }
}
.features { display: grid;
grid-template-columns: 1fr; }
@media (min-width: 600px) {
.features { grid-template-columns: repeat(3, 1fr); }
}
- Puntos de ruptura por contenido, no por dispositivos: cuando el diseño «pide» un cambio (~480, ~768, ~1024px).
- Imágenes fluidas siempre:
img { max-width: 100% }. - Anchos fluidos:
%,vw/vho contenedores conmax-widthen rem — nunca anchos gigantes fijos.
✍️ Los 12 ejercicios del bloque
Sigue trabajando en tu carpeta css-b1/ (o crea css-b2/).
Cada ejercicio construye una pieza del proyecto final del bloque.
1 Barra de navegación flexible
Convierte el <header> en flexbox: logo a la izquierda, menú a la
derecha, verticalmente centrados y con 24px de separación entre enlaces.
Ver solución
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
}
.menu {
display: flex;
gap: 24px;
}
2 Centrado perfecto
Crea una sección .aviso de 60vh cuyo contenido quede exactamente en el
centro horizontal y vertical.
Ver solución
.aviso {
display: flex;
justify-content: center;
align-items: center;
min-height: 60vh;
}
3 Fila de tarjetas que salta de línea
Con Flexbox, logra tarjetas de base 240px que se reparten el espacio y pasan a la siguiente línea cuando no caben.
Ver solución
.cards {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.cards > .card {
flex: 1 1 240px;
}
4 Galería a tres columnas
Rehaz la galería con Grid: tres columnas iguales, separación de 16px, sin márgenes negativos ni trucos.
Ver solución
.galeria {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
5 Esqueleto de página con áreas
Monta un layout completo con áreas: cabecera arriba, menú lateral izquierdo, contenido a su derecha, y pie a lo ancho. Ocupa el alto completo de la ventana.
Ver solución
body {
display: grid;
grid-template-areas:
"cabecera cabecera"
"menu contenido"
"pie pie";
grid-template-columns: 220px 1fr;
grid-template-rows: auto 1fr auto;
min-height: 100vh;
}
> header { grid-area: cabecera; }
> nav { grid-area: menu; }
> main { grid-area: contenido; }
> footer { grid-area: pie; }
6 Galería autorresponsive
Consigue la misma galería pero que funcione en CUALQUIER ancho sin media queries: mínimo 220px por tarjeta, máximo una por columna disponible.
Ver solución
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
}
7 Insignia en la esquina
Añade a cada tarjeta una insignia «Nuevo» clavada en su esquina superior derecha, medio asomando fuera (-10px).
Ver solución
.card { position: relative; }
.nuevo {
position: absolute;
top: -10px;
right: -10px;
}
8 Cabecera pegajosa
Haz que la barra de navegación se quede fija arriba mientras haces scroll, siempre por encima del contenido.
Ver solución
.navbar {
position: sticky;
top: 0;
z-index: 100;
}
9 Botón «volver arriba»
Crea un botón flotante anclado a 20px de las esquinas inferior derecha, visible siempre aunque hagas scroll.
Ver solución
#toTop {
position: fixed;
right: 20px;
bottom: 20px;
}
10 Apilar en pantallas pequeñas
Partiendo de la galería de 3 columnas, haz que en pantallas de 600px o menos las tarjetas se apilen en una única columna.
Ver solución
@media (max-width: 600px) {
.galeria { grid-template-columns: 1fr; }
}
11 Refactor mobile-first
Rewrite el ejercicio 10 al revés: estilos base pensados para móvil (una columna) y
ampliación a tres columnas a partir de 600px con min-width.
Ver solución
.galeria {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
@media (min-width: 600px) {
.galeria { grid-template-columns: repeat(3, 1fr); }
}
12 🏆 Proyecto integrador: «landing-responsive.html»
Une todo el bloque en una landing completa. Requisitos:
- Meta viewport presente
- Cabecera flexible (logo ⇆ navegación) que además sea
sticky - Tarjetas de características con Grid y patrón
repeat(auto-fit, minmax()) - Enfoque mobile-first con al menos una media query
min-width - Anchos fluidos (% o unidades de ventana), sin píxeles grandes fijos
Este ejercicio es el reto del laboratorio del examen: la validación automática comprobará estos criterios por ti.
📝 Examen del Bloque 2
Dos partes: un test teórico autoevaluable (necesitas un mínimo de 70 % para superar el bloque) y un reto práctico de autocorrección con checklist.
Parte B · Reto práctico final
Construye el ejercicio 12 («landing-responsive.html») sin mirar soluciones y valida tú mismo/a estos criterios. Mínimo para aprobar: 7 de 8 casillas.
Cumplidos: 0 / 8