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:

/* ❌ 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ónUsar
Distribuir items en una fila o columnaFlexbox
Layout completo de página (header, sidebar, main, footer)Grid
Galería de tarjetas responsivaGrid con auto-fill/fit
Centrar un elementoFlexbox (o Grid)
Componente con items que deben alinearse en dos ejesGrid

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