Contenido principal — display: grid para las cards
Layouts modernos con Flexbox (1D) y CSS Grid (2D)
Antes de aprender cada sistema por separado, es importante entender cuándo usar cada uno. No son alternativas excluyentes: se usan juntos en casi todo proyecto profesional.
/*
Ideal para:
- Barras de navegación
- Listas horizontales o verticales
- Alinear elementos dentro de un componente
- Centrar cosas (vertical + horizontal)
- Componentes pequeños
Piensa en Flexbox como
una línea de elementos.
*/
.nav {
display: flex;
justify-content: space-between;
align-items: center;
}
/*
Ideal para:
- Layout de página completo
- Galerías de imágenes
- Dashboards con múltiples áreas
- Cuando necesitas controlar
filas Y columnas al mismo tiempo
Piensa en Grid como
una tabla o cuadrícula.
*/
.pagina {
display: grid;
grid-template-areas:
"header"
"main"
"footer";
}
Regla práctica: ¿Necesitas controlar solo una dirección (horizontal o vertical)? → Flexbox. ¿Necesitas controlar ambas a la vez? → CSS Grid. ¿No estás seguro? En la práctica, Grid para el layout exterior y Flexbox para los componentes interiores.
Flexbox se activa con display: flex en el elemento contenedor.
A partir de ese momento, sus hijos directos se convierten en ítems flex
y pueden alinearse, distribuirse y redimensionarse de manera flexible.
flex-direction — dirección del eje principalDefine si los ítems se colocan en fila o en columna.
/* flex-direction controla el eje principal */
.contenedor {
display: flex;
flex-direction: row; /* → izquierda a derecha (default) */
/* flex-direction: row-reverse; → derecha a izquierda */
/* flex-direction: column; → arriba a abajo */
/* flex-direction: column-reverse;→ abajo a arriba */
}
justify-content — alineación en el eje principalControla cómo se distribuye el espacio a lo largo del eje principal (en row: horizontal).
/*
justify-content distribuye el espacio en el eje principal.
(Eje horizontal cuando flex-direction: row)
*/
.contenedor {
display: flex;
justify-content: flex-start; /* elementos al inicio */
/* justify-content: flex-end; elementos al final */
/* justify-content: center; centrados */
/* justify-content: space-between; espacio entre elementos */
/* justify-content: space-around; espacio alrededor */
/* justify-content: space-evenly; espacio exactamente igual */
}
align-items — alineación en el eje cruzadoControla la alineación perpendicular al eje principal (en row: vertical).
/*
align-items controla el eje cruzado (vertical cuando flex-direction: row).
stretch es el valor por defecto: los ítems se estiran para llenar el contenedor.
*/
.contenedor {
display: flex;
align-items: stretch; /* estira los ítems (default) */
/* align-items: flex-start; al inicio del eje cruzado */
/* align-items: flex-end; al final del eje cruzado */
/* align-items: center; centrados en el eje cruzado */
/* align-items: baseline; alineados por la línea base del texto */
}
flex-wrap — envolver ítemsPor defecto los ítems intentan caber en una sola línea. flex-wrap: wrap permite que salten a la siguiente fila.
/* flex-wrap controla si los ítems se quedan en una línea o saltan */
.contenedor {
display: flex;
flex-wrap: nowrap; /* todos en una línea (default) */
/* flex-wrap: wrap; saltan a la siguiente fila */
/* flex-wrap: wrap-reverse; saltan hacia arriba */
}
flex — grow, shrink y basis
La propiedad flex es el shorthand de tres propiedades que controlan
cómo cada ítem crece, encoge y cuál es su tamaño base.
/*
flex: grow shrink basis
├── flex-grow: cuánto puede CRECER (0 = no crece)
├── flex-shrink: cuánto puede ENCOGER (0 = no encoge)
└── flex-basis: tamaño BASE antes de distribuir espacio libre
Valores comunes:
*/
.item-igual { flex: 1; } /* todos iguales → flex: 1 1 0% */
.item-doble { flex: 2; } /* el doble de espacio */
.item-fijo { flex: 0 0 200px; } /* siempre 200px, no cambia */
.item-auto { flex: 1 1 auto; } /* crece y encoge desde su tamaño natural */
align-self y order — propiedades del ítem/* Propiedades que van en los ÍTEMS, no en el contenedor */
/* align-self sobrescribe align-items solo para ese ítem */
.item-especial {
align-self: center; /* flex-start | flex-end | center | stretch | baseline */
}
/* order cambia el orden visual (default: 0 para todos) */
/* valores negativos van primero, positivos van al final */
.primero-visual { order: -1; }
.ultimo-visual { order: 10; }
/* Importante: no afecta el orden del DOM ni la accesibilidad */
CSS Grid se activa con display: grid. A diferencia de Flexbox,
permite definir una cuadrícula de filas y columnas y colocar
los elementos en posiciones exactas dentro de ella.
grid-template-columns — definir columnas/*
Formas de definir columnas:
*/
.grid {
display: grid;
/* Tres columnas fijas de 200px */
grid-template-columns: 200px 200px 200px;
/* Tres columnas iguales que ocupan el espacio disponible */
grid-template-columns: repeat(3, 1fr);
/* Columnas de distinto tamaño */
grid-template-columns: 200px 1fr 2fr;
/* Columnas automáticas RESPONSIVE sin media queries */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/*
auto-fill → crea tantas columnas como quepan
minmax(200px, 1fr) → mínimo 200px, máximo 1 fracción
Esto crea un grid que se adapta solo al viewport.
*/
}
grid-template-rows — definir filas/*
grid-template-rows funciona igual que columns,
pero para las filas.
*/
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 60px 100px 40px; /* fila 1, 2 y 3 */
/* grid-auto-rows: 80px; → todas las filas generadas automáticamente miden 80px */
}
grid-column y grid-row — spanning
Un ítem puede ocupar más de una celda usando span o especificando
las líneas de inicio y fin.
/*
Los ítems pueden ocupar múltiples celdas con span.
Las líneas del grid se numeran desde 1.
Una grilla de 4 columnas tiene 5 líneas verticales (1, 2, 3, 4, 5).
*/
.item-ancho { grid-column: span 2; } /* ocupa 2 columnas */
.item-alto { grid-row: span 2; } /* ocupa 2 filas */
/* Especificando líneas exactas: inicio / fin */
.item-preciso { grid-column: 1 / 4; } /* de la línea 1 a la 4 (3 columnas) */
.item-exacto { grid-column: 2 / span 3; } /* empieza en 2, ocupa 3 columnas */
.item-final { grid-column: 3 / -1; } /* de columna 3 hasta el final (-1) */
grid-template-areas — nombrar zonasEsta es la forma más visual y legible de crear layouts. Cada cadena de texto representa una fila, y los nombres definen las áreas.
/* ── CONTENEDOR: define las áreas y el tamaño de columnas/filas ── */
.layout {
display: grid;
grid-template-areas:
"header header header" /* fila 1: header ocupa toda la fila */
"sidebar main main" /* fila 2: sidebar + main (2 columnas) */
"footer footer footer"; /* fila 3: footer ocupa toda la fila */
grid-template-columns: 200px 1fr 1fr; /* ancho de cada columna */
grid-template-rows: 60px auto 50px; /* alto de cada fila */
gap: 1rem; /* espacio entre áreas */
}
/* ── ÍTEMS: cada hijo se asigna a su área por nombre ── */
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
/*
Para hacer el layout responsive, solo hay que cambiar
grid-template-areas en el media query:
*/
@media (max-width: 600px) {
.layout {
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
grid-template-columns: 1fr;
}
}
En un proyecto real, Grid define la estructura general de la página y Flexbox organiza los componentes internos. El siguiente ejemplo muestra cómo conviven.
Contenido principal — display: grid para las cards
/*
ESTRUCTURA DE UN LAYOUT REAL
Grid para la página → Flexbox para los componentes
*/
/* 1. Grid en el body principal */
.pagina {
display: grid;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
grid-template-columns: 200px 1fr;
grid-template-rows: 60px 1fr 50px;
min-height: 100vh;
}
/* 2. Flexbox en el header */
.header {
grid-area: header;
display: flex; /* ← Flexbox aquí */
justify-content: space-between;
align-items: center;
}
/* 3. Grid en las cards internas */
.cards {
display: grid; /* ← Grid aquí */
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 1rem;
}
/* 4. Flexbox dentro de cada card */
.card {
display: flex; /* ← Flexbox aquí */
flex-direction: column;
gap: 0.5rem;
}
El patrón más común: logo a la izquierda, links centrados o a la derecha, botón al extremo.
/* Navbar clásica con Flexbox */
.navbar {
display: flex;
justify-content: space-between; /* logo | links | botón */
align-items: center; /* centrado vertical */
padding: 1rem 2rem;
}
.nav-links {
display: flex; /* links en fila */
gap: 1.5rem;
list-style: none;
}
La técnica más sencilla para centrar un elemento horizontal y verticalmente.
/* La técnica de centrado más limpia en CSS moderno */
.contenedor {
display: flex;
justify-content: center; /* centrado horizontal */
align-items: center; /* centrado vertical */
height: 100vh; /* necesita altura definida */
}
/* Alternativa con place-items (shorthand) */
.contenedor-v2 {
display: grid;
place-items: center; /* centra en las dos dimensiones */
height: 100vh;
}
El truco clave: flex: 1 en la descripción hace que el botón
siempre quede al fondo, sin importar el largo del texto.
/* Tarjeta con botón siempre al fondo */
.card {
display: flex;
flex-direction: column; /* apilado vertical */
}
.card-info {
flex: 1; /* ocupa el espacio libre → empuja el botón abajo */
display: flex;
flex-direction: column;
}
.card-descripcion {
flex: 1; /* hace que el precio quede al final de la info */
}
.card-btn {
/* Este botón siempre queda al fondo de la tarjeta */
margin-top: auto;
}
Grid permite que ciertos elementos ocupen más de una celda, creando layouts asimétricos interesantes.
/* Galería con elemento destacado */
.galeria {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px; /* todas las filas miden 100px por defecto */
gap: 0.5rem;
}
/* El elemento destacado ocupa 2 columnas y 2 filas */
.destacado {
grid-column: span 2;
grid-row: span 2;
}
El clásico layout de tres columnas (header, sidebar izquierdo, contenido central, aside derecho, footer) que era muy difícil antes de Grid.
headerleft sidebarmain contentright aside/* Holy Grail Layout — el layout clásico de 3 columnas */
.pagina {
display: grid;
grid-template-areas:
"header header header"
"left content right"
"footer footer footer";
grid-template-columns: 160px 1fr 120px;
grid-template-rows: 60px 1fr 50px;
min-height: 100vh;
}
.header { grid-area: header; }
.left { grid-area: left; }
.content { grid-area: content; }
.right { grid-area: right; }
.footer { grid-area: footer; }
/* En móvil, todo en una columna: */
@media (max-width: 600px) {
.pagina {
grid-template-areas:
"header"
"content"
"left"
"right"
"footer";
grid-template-columns: 1fr;
}
}
Construye una página con un layout completo que demuestre el uso de Flexbox y CSS Grid de forma combinada. Puede ser un dashboard de administración, un portafolio personal o una tienda con sección de productos.
grid-template-areas (header, main, footer mínimo).
justify-content.
grid-template-columns: repeat(auto-fill, minmax(...)).
grid-column: span N o grid-row: span N.
flex-direction: column y flex: 1.
gap para los espacios (no margin entre ítems).
justify-contentalign-itemsflex-direction: columnflex: 1 para distribucióngrid-template-areasauto-fill / minmaxspan de columnas o filasgapfloat ni position para el layout💡 Herramientas recomendadas: Flexbox Froggy y Grid Garden son juegos interactivos para practicar. El inspector de Chrome/Firefox tiene herramientas visuales para depurar Grid y Flexbox.
Recuerda: No uses float ni position: absolute
para construir el layout. Esas técnicas son de generaciones anteriores de CSS.
Flexbox y Grid son la forma correcta y moderna.