Programación Web · Capítulo 19
Diseño Responsivo Avanzado: CSS Grid, Flexbox y Mobile-First
Domina las herramientas modernas de CSS para crear layouts que se adaptan perfectamente a cualquier tamaño de pantalla.
1. Filosofía Mobile-First
El enfoque mobile-first significa diseñar primero para pantallas pequeñas y luego añadir estilos para pantallas más grandes. Es la estrategia correcta porque:
- Más del 60% del tráfico web es móvil.
- Obliga a priorizar el contenido esencial.
- Los estilos base son más simples; se añade complejidad progresivamente.
- Google indexa primero la versión móvil (Mobile-First Indexing).
/* ❌ Desktop-first: estilos base para desktop, se "reducen" */
.contenedor { display: grid; grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 768px) {
.contenedor { grid-template-columns: 1fr; } /* Sobrescribir */
}
/* ✅ Mobile-first: estilos base para móvil, se "expanden" */
.contenedor { display: grid; grid-template-columns: 1fr; }
@media (min-width: 768px) {
.contenedor { grid-template-columns: 1fr 1fr; }
}
@media (min-width: 1024px) {
.contenedor { grid-template-columns: 1fr 1fr 1fr; }
}
<!-- Viewport meta tag: OBLIGATORIO para diseño responsivo -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Sin esto, móviles simulan una pantalla de 980px y hacen zoom out -->
2. CSS Flexbox en Profundidad
Flexbox es ideal para layouts en una dimensión (fila o columna). Es perfecto para: navbars, listas de tarjetas, centrar elementos, distribuir espacio.
/* Propiedades del CONTENEDOR flex */
.nav {
display: flex;
/* Dirección del eje principal */
flex-direction: row; /* row | row-reverse | column | column-reverse */
/* Alineación en el eje principal (horizontal si row) */
justify-content: space-between; /* flex-start | center | flex-end | space-between | space-around | space-evenly */
/* Alineación en el eje cruzado (vertical si row) */
align-items: center; /* stretch | flex-start | center | flex-end | baseline */
/* Permitir que los items salten a la siguiente línea */
flex-wrap: wrap; /* nowrap | wrap | wrap-reverse */
gap: 16px; /* Espacio entre items */
}
/* Propiedades de los ITEMS flex */
.item {
flex-grow: 1; /* Cuánto espacio extra tomar (0 = no crecer) */
flex-shrink: 1; /* Cuánto encogerse si no hay espacio (0 = no encoger) */
flex-basis: 200px; /* Tamaño base antes de distribuir espacio extra */
/* Shorthand: grow shrink basis */
flex: 1 1 200px;
flex: 1; /* Equivale a: 1 1 0 — crece y encoge igual */
/* Alineación individual (sobreescribe align-items del padre) */
align-self: flex-end;
}
Layouts Prácticos con Flexbox
/* Navbar clásico */
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 24px;
height: 64px;
}
/* Centrar vertical y horizontalmente */
.centrado {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* Tarjetas que ocupan igual espacio */
.lista-tarjetas {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.tarjeta {
flex: 1 1 300px; /* Mínimo 300px, crecen para llenar espacio */
max-width: 400px;
}
/* Footer pegado al fondo (sticky footer) */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
main { flex: 1; } /* Main ocupa todo el espacio disponible */
footer { /* Footer queda al fondo */ }
3. CSS Grid en Profundidad
CSS Grid es ideal para layouts en dos dimensiones (filas Y columnas). Es perfecto para: layouts de página completa, galerías, dashboards.
/* Grid básico */
.galeria {
display: grid;
/* Definir columnas */
grid-template-columns: 200px 1fr 1fr; /* Fija + dos flexibles */
grid-template-columns: repeat(3, 1fr); /* 3 columnas iguales */
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* Responsivo */
/* Definir filas */
grid-template-rows: auto; /* Altura automática */
grid-auto-rows: 200px; /* Todas las filas: 200px */
/* Espaciado */
gap: 24px;
column-gap: 16px;
row-gap: 24px;
}
/* Colocar items en posiciones específicas */
.destacado {
grid-column: 1 / 3; /* Ocupa desde columna 1 hasta 3 */
grid-column: span 2; /* Ocupa 2 columnas */
grid-row: span 2; /* Ocupa 2 filas */
}
/* Nombrar áreas (muy legible) */
.layout {
display: grid;
grid-template-areas:
"header header header"
"sidebar main main "
"footer footer footer";
grid-template-columns: 250px 1fr 1fr;
grid-template-rows: 64px 1fr 80px;
min-height: 100vh;
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main { grid-area: main; }
.footer { grid-area: footer; }
Grid Responsivo: auto-fill y auto-fit
/* auto-fill: llena con tantas columnas como quepan */
.galeria {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 16px;
}
/* En 800px de ancho: 3 columnas de 250px
En 600px de ancho: 2 columnas de 250px
En 300px de ancho: 1 columna
¡Sin media queries! */
/* auto-fit: igual que auto-fill pero colapsa columnas vacías */
.tarjetas {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
| Situación | Usar |
| Distribuir items en una fila o columna | Flexbox |
| Layout completo de página (header, sidebar, main, footer) | Grid |
| Galería de tarjetas responsiva | Grid con auto-fill/fit |
| Centrar un elemento | Flexbox (o Grid) |
| Componente con items que deben alinearse en dos ejes | Grid |
4. Media Queries y Breakpoints
/* Sistema de breakpoints estándar (similar a Tailwind) */
/* Mobile: 0px - 639px (base, sin media query) */
@media (min-width: 640px) {
/* sm: tablets pequeñas */
}
@media (min-width: 768px) {
/* md: tablets */
}
@media (min-width: 1024px) {
/* lg: laptops */
}
@media (min-width: 1280px) {
/* xl: desktops */
}
/* También puedes consultar orientación */
@media (orientation: landscape) { }
/* Y preferencias del usuario */
@media (prefers-color-scheme: dark) {
body { background: #0f172a; color: #e2e8f0; }
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; transition: none !important; }
}
5. CSS Custom Properties (Variables)
/* Definir variables en :root (alcance global) */
:root {
--color-primario: #0d9488;
--color-texto: #1a1a2e;
--color-fondo: #f8f9fa;
--fuente-base: 'Georgia', serif;
--espaciado-sm: 8px;
--espaciado-md: 16px;
--espaciado-lg: 32px;
--radio-borde: 8px;
--sombra: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
/* Usar las variables */
.boton {
background: var(--color-primario);
padding: var(--espaciado-sm) var(--espaciado-md);
border-radius: var(--radio-borde);
box-shadow: var(--sombra);
}
/* Sobrescribir para modo oscuro */
@media (prefers-color-scheme: dark) {
:root {
--color-texto: #e2e8f0;
--color-fondo: #0f172a;
}
/* El resto del CSS no necesita cambiar */
}
6. Tipografía Fluida con clamp()
/* clamp(mínimo, preferido, máximo) */
/* El tamaño crece suavemente entre el mínimo y máximo */
h1 {
/* En móvil: 1.5rem, crece hasta 3rem en desktop, fluidamente */
font-size: clamp(1.5rem, 4vw, 3rem);
}
p {
font-size: clamp(1rem, 2.5vw, 1.25rem);
line-height: 1.7;
}
.hero {
padding: clamp(40px, 8vw, 120px) clamp(24px, 5vw, 80px);
}
/* Sin clamp tendrías que hacer esto: */
h1 { font-size: 1.5rem; }
@media (min-width: 768px) { h1 { font-size: 2rem; } }
@media (min-width: 1024px) { h1 { font-size: 3rem; } }
7. Patrones Responsivos Modernos
/* Patrón: Sidebar + Contenido principal */
.con-sidebar {
display: grid;
grid-template-columns: 1fr; /* Móvil: una columna */
}
@media (min-width: 1024px) {
.con-sidebar {
grid-template-columns: 280px 1fr; /* Desktop: sidebar fija + main */
}
}
/* Patrón: Holy Grail (header, footer, sidebar izq, sidebar der, main) */
.holy-grail {
display: grid;
grid-template:
"header" auto
"main" 1fr
"footer" auto
/ 1fr;
min-height: 100vh;
}
@media (min-width: 768px) {
.holy-grail {
grid-template:
"header header header" auto
"sidebar main aside" 1fr
"footer footer footer" auto
/ 200px 1fr 200px;
}
}
/* Patrón: Card grid perfectamente responsivo */
.card-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
gap: clamp(16px, 3vw, 32px);
}
Resumen del Capítulo
- El enfoque mobile-first diseña primero para móvil y expande con
min-width media queries; es el estándar de la industria y requerido por Google.
- Flexbox maneja layouts unidimensionales (fila o columna): navbars, centrado, distribución de espacio con justify-content y align-items.
- CSS Grid maneja layouts bidimensionales: usa
grid-template-areas para layouts de página legibles y auto-fill/fit para grids responsivos sin media queries.
- Los breakpoints estándar son 640px, 768px, 1024px y 1280px; úsalos consistentemente y evita breakpoints arbitrarios.
- Las CSS Custom Properties (variables) centralizan colores, espaciados y fuentes, facilitando cambios globales y la implementación de temas.
clamp(min, ideal, max) crea tipografía y espaciados fluidos que se adaptan suavemente entre móvil y desktop sin media queries.
- El patrón
minmax(min(100%, 320px), 1fr) con auto-fill crea grids de tarjetas completamente responsivos con una sola línea de CSS.