🎯 Objetivo del tema
El administrador aún no ha insertado un video para esta sección.
🗺️ Mapa del tema
En 2007 Steve Jobs presentó el iPhone y cambió la web para siempre. Lo que diseñabas para 1024x768 ahora debe verse en 375x812 (un iPhone), 768x1024 (un iPad) y 1920x1080 (un monitor Full HD). Hacer esto bien se llama diseño responsive. No es opcional: más del 60% del tráfico web mundial es móvil.
Por qué diseñar primero para móvil te obliga a priorizar.
Las 4 reglas @media que necesitas conocer y los breakpoints estándar.
srcset, picture, max-width, aspect-ratio: que nada se rompa.
clamp(), vw, rem: cómo escalar sin media queries.
De columna única a multi-columna, navegación hamburguesa, tarjetas apiladas.
El cambio de paradigma: estilos según el CONTENEDOR, no la pantalla.
Por qué y cuándo usar Bootstrap, Tailwind, Bulma o escribir CSS puro. Comparativa con ejemplos.
1.7.1 Mobile-first vs desktop-first
Hay dos mentalidades al diseñar responsive: partir del escritorio y agregar estilos para móvil (desktop-first), o partir del móvil y agregar estilos para pantallas grandes (mobile-first). La industria se decantó hace años por mobile-first, y hay razones sólidas para ello.
Las dos mentalidades en código
/* Desktop-first: empezamos con todo y 'achicamos' para móvil */
.card { display: grid; grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 768px) {
.card { grid-template-columns: 1fr; } /* quitamos columnas */
}
/* Mobile-first: empezamos simple y 'agrandamos' para desktop */
.card { display: grid; grid-template-columns: 1fr; } /* una columna */
@media (min-width: 768px) {
.card { grid-template-columns: 1fr 1fr; } /* sumamos columnas */
}
@media (min-width: 1024px) {
.card { grid-template-columns: 1fr 1fr 1fr; } /* tres columnas */
}Desktop-first (arriba) vs mobile-first (abajo)
| Aspecto | Desktop-first | Mobile-first |
|---|---|---|
| Punto de partida | Pantalla grande (1920px). | Pantalla pequeña (375px). |
| Crecimiento del CSS | RESTAS estilos para móvil. | SUMAS estilos para desktop. |
| Rendimiento en móvil | Carga CSS que luego se sobreescribe. Más KB. | Carga solo lo esencial. Menos KB. |
| Forzá a priorizar | No. Es fácil agregar de más. | Sí. Te obliga a decidir qué es importante. |
| Adoptado por | Sitios viejos (pre-2012). | Sitios modernos, Google, framework CSS. |
El administrador aún no ha insertado un video para esta sección.
1.7.2 Media queries y breakpoints
Las media queries son condicionales para tu CSS: 'si el viewport cumple esta condición, aplica este bloque'. Son la base del diseño responsive, aunque las técnicas modernas (Grid con auto-fit, clamp, container queries) las usan cada vez menos.
Sintaxis básica
/* Sintaxis: @media (condición) { reglas } */
@media (min-width: 768px) {
/* aplica cuando el viewport mide 768px o MÁS */
.sidebar { display: block; }
}
/* Múltiples condiciones con 'and' */
@media (min-width: 768px) and (max-width: 1023px) {
/* solo tablets */
.sidebar { width: 200px; }
}
/* Orientación */
@media (orientation: landscape) {
.hero { height: 100vh; }
}Sintaxis de media queries
Los 5 breakpoints estándar de la industria
| Nombre | Breakpoint | Dispositivo típico |
|---|---|---|
| xs | 0 - 479px | Móvil vertical (iPhone SE, Galaxy pequeño). |
| sm | 480 - 767px | Móvil horizontal / móvil grande. |
| md | 768 - 1023px | Tablet vertical (iPad). |
| lg | 1024 - 1279px | Tablet horizontal / laptop pequeño. |
| xl | 1280px+ | Desktop / monitor. |
El administrador aún no ha insertado un video para esta sección.
1.7.3 Imágenes y videos responsive
Las imágenes son el componente que más se rompe en responsive. Si no las tratas bien, una imagen de 4000px en una pantalla de 375px hace que el usuario descargue 4 MB innecesarios y tarde 10 segundos en ver la página. Hay 3 técnicas modernas que resuelven esto: max-width, srcset y picture.
Regla #1: que NUNCA se desborde
/* La regla sagrada: */
img, video, iframe {
max-width: 100%; /* nunca más ancho que su contenedor */
height: auto; /* mantiene la proporción */
}Reset para medios
srcset: el navegador elige la mejor imagen
<!-- El navegador elige entre 3 versiones según el viewport y la densidad -->
<img
src="img-hotel-800.jpg"
srcset="img-hotel-400.jpg 400w,
img-hotel-800.jpg 800w,
img-hotel-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px"
alt="Hotel visto desde la playa">
<!-- El usuario móvil descarga la de 400px (50 KB), -->
<!-- el de desktop descarga la de 1200px (200 KB). -->Imágenes responsive con srcset
picture: para imágenes muy diferentes (no solo tamaños)
<picture>
<!-- En móvil, una imagen recortada y cuadrada -->
<source media="(max-width: 600px)" srcset="hotel-cuadrado.jpg">
<!-- En desktop, una imagen panorámica -->
<source media="(min-width: 601px)" srcset="hotel-panoramico.jpg">
<img src="hotel-panoramico.jpg" alt="Hotel visto desde la playa">
</picture>Imágenes diferentes con picture
El administrador aún no ha insertado un video para esta sección.
1.7.4 Tipografía y espaciado fluidos
Una buena tipografía responsive escala suavemente entre móvil y desktop, sin saltos bruscos en los breakpoints. Las técnicas modernas (clamp, vw) eliminan la necesidad de media queries para tipografía y te dan transiciones suaves.
La fórmula mágica: clamp()
/* font-size: clamp(MÍNIMO, IDEAL, MÁXIMO) */
h1 {
font-size: clamp(1.75rem, 4vw, 3.5rem);
/* mínimo: 28px (móvil) */
/* ideal: 4% del ancho del viewport (escala fluida) */
/* máximo: 56px (monitor 4K) */
}
/* Para padding, gaps, márgenes: igual */
.contenedor {
padding: clamp(1rem, 3vw, 3rem);
gap: clamp(0.5rem, 2vw, 1.5rem);
}Tipografía y espaciado fluidos con clamp()
La fórmula del espacio fluido
Hay una fórmula famosa del diseñador Mike Riethmuller para espaciado responsive perfecto:
/* Fórmula: clamp(min, calc(preferida + slope*100vw), max) */
.section {
padding: clamp(2rem, 4vw + 1rem, 6rem);
/* en móvil (375px): ~2.5rem */
/* en desktop (1440px): ~5.8rem */
/* en 4K: se topa con 6rem */
}Espaciado fluido con fórmula de Mike Riethmuller
El administrador aún no ha insertado un video para esta sección.
1.7.5 Patrones comunes de layout responsive
Hay 4 patrones de layout que se repiten en el 80% de los sitios web modernos. Aprenderlos de memoria te permite resolver el resto por analogía.
| Patrón | Móvil | Desktop | Técnica |
|---|---|---|---|
| Mostly fluid (mayormente fluido) | Una columna que ocupa todo. | Ancho máximo, centrado. | max-width: 1200px; margin: 0 auto. |
| Column drop (caída de columnas) | 1 columna. | N columnas, con 'caída' en móvil. | Grid con auto-fit + media queries. |
| Layout shifter (cambio de layout) | Reordenamiento total con order o display:none. | Layout completamente diferente. | order en Flexbox/Grid + media queries. |
| Off canvas (fuera del lienzo) | Menú lateral oculto, se abre con botón. | Menú lateral visible siempre. | transform: translateX(-100%) en móvil, translateX(0) en desktop. |
El patrón más usado: el menú hamburguesa
<button class="menu-toggle" aria-label="Abrir menú">☰</button>
<nav class="menu">
<ul>
<li><a href="/">Inicio</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/contacto">Contacto</a></li>
</ul>
</nav>
<style>
.menu-toggle { display: block; } /* visible en móvil */
.menu { transform: translateX(-100%); transition: transform 0.3s; } /* oculto */
.menu.abierto { transform: translateX(0); } /* visible al abrir */
@media (min-width: 768px) {
.menu-toggle { display: none; } /* ocultar botón en tablet+ */
.menu { transform: translateX(0); } /* menú siempre visible */
}
</style>Menú hamburguesa responsive
El patrón moderno: auto-fit (sin media queries)
/* Galería que se adapta SOLA al ancho disponible */
.galeria {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Móvil: 1 columna (375 < 250*2) */
/* Tablet: 2 columnas (768 / 250 = 3.07, caben 2-3) */
/* Desktop: 4-5 columnas según el ancho */Galería auto-adaptable con auto-fit
El administrador aún no ha insertado un video para esta sección.
1.7.6 Container queries: el cambio de paradigma
Hasta 2022, las media queries respondían al VIEWPORT (tamaño de la pantalla). Pero a veces lo que importa es el tamaño del CONTENEDOR del elemento. Por ejemplo: una tarjeta de producto puede aparecer en una columna estrecha (sidebar) o en una galería amplia (main). Con media queries, no podías aplicar estilos diferentes según el caso. Con container queries, SÍ.
El ejemplo clásico: la tarjeta adaptable
/* 1. Marcar el PADRE como contenedor consultable */
.tarjeta-contenedor {
container-type: inline-size;
container-name: tarjeta;
}
/* 2. Aplicar estilos al HIJO según el tamaño del PADRE */
@container tarjeta (min-width: 400px) {
.tarjeta {
display: grid;
grid-template-columns: 200px 1fr; /* imagen a un lado */
gap: 1rem;
}
}
@container tarjeta (max-width: 399px) {
.tarjeta {
display: block; /* imagen arriba, texto abajo */
}
.tarjeta img { width: 100%; }
}Container queries en acción
Con container queries, la misma tarjeta `.tarjeta` se ve horizontal cuando tiene 400px+ de ancho (en una galería amplia) y vertical cuando tiene menos (en una columna estrecha). Sin tocar el viewport, sin duplicar el HTML, sin JavaScript. Es el futuro del responsive.
| Característica | Media queries | Container queries |
|---|---|---|
| Pregunta que responde | ¿De qué tamaño es la PANTALLA? | ¿De qué tamaño es el CONTENEDOR? |
| Soporte en navegadores | 100% (desde 2010). | ~95% (desde 2023). |
| Caso de uso típico | Layout general de página. | Componentes reutilizables (cards, modals, sidebars). |
El administrador aún no ha insertado un video para esta sección.
1.7.7 Frameworks CSS: Bootstrap y Tailwind en acción
Hasta ahora hemos escrito CSS a mano: media queries, grid, flexbox, unidades fluidas. Funciona, pero a medida que tu app crece (5 páginas, 50 componentes, 200 clases CSS), escribir todo a mano se vuelve lento e inconsistente. Aquí entran los FRAMEWORKS CSS: librerías que te dan componentes, utilidades y patrones pre-construidos para que te enfoques en lo que importa (la lógica de tu app) en vez de reinventar el botón cada vez. Los 2 gigantes son Bootstrap (componentes prefabricados, opinionado) y Tailwind CSS (utilidades, customización total). Cada uno tiene filosofía opuesta. Aquí vas a aprender cuándo usar cada uno, con ejemplos reales.
Los 4 frameworks CSS más usados en 2025
| Framework | Filosofía | Tamaño | Curva de aprendizaje | Ideal para |
|---|---|---|---|---|
| Bootstrap 5 | Componentes prefabricados | ~30 KB gzip | Baja | MVPs rápidos, sitios corporativos, dashboards. Aprendes en 1 día. |
| Tailwind CSS | Utility-first (componer) | ~10 KB gzip (purge) | Media | Diseño custom, design systems, apps modernas. Aprendes en 1 semana. |
| Bulma | Componentes con Flexbox | ~20 KB gzip | Baja | Alternativa más simple a Bootstrap, sin JS. |
| Foundation | Componentes profesionales | ~40 KB gzip | Alta | Apps enterprise, accesibilidad WCAG priorizada. |
Ejemplo real: el mismo botón con Bootstrap y con Tailwind
<!-- BOOTSTRAP 5: una clase semantica por 'concepto' -->
<button type="button" class="btn btn-primary btn-lg">
Guardar cambios
</button>
<!-- Como funciona por dentro (Bootstrap te lo da hecho): -->
<!-- .btn: base (padding, border-radius, font-size, transition) -->
<!-- .btn-primary: colores del tema primary -->
<!-- .btn-lg: padding mas grande -->
<!-- Personalizar el color requiere compilar Sass o usar variables CSS: -->
<style>
.btn-primary {
background-color: var(--bs-primary); /* CSS variable, customizable */
border-color: var(--bs-primary);
}
</style>
<!-- TAILWIND CSS: compones utilities para crear tu propio boton -->
<button type="button" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Guardar cambios
</button>
<!-- Como funciona por dentro: -->
<!-- bg-blue-500: background-color: rgb(59 130 246) -->
<!-- hover:bg-blue-700: en hover cambia a rgb(29 78 216) -->
<!-- text-white: color: white -->
<!-- font-bold: font-weight: 700 -->
<!-- py-2: padding-top y padding-bottom: 0.5rem -->
<!-- px-4: padding-left y padding-right: 1rem -->
<!-- rounded: border-radius: 0.25rem -->
<!-- Para personalizar el color, editas tailwind.config.js: -->
module.exports = {
theme: {
extend: {
colors: {
primary: '#1e40af', // tu color corporativo
}
}
}
}
<!-- Luego usas: bg-primary, text-primary, etc. -->Mismo botón con Bootstrap 5 y con Tailwind CSS
Cómo instalar Bootstrap en tu proyecto (3 formas)
<!-- FORMA 1: CDN (rapida para prototipos, NO para produccion) -->
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">Mi App</a>
</div>
</nav>
<div class="container py-5">
<h1>Hola Bootstrap</h1>
<button class="btn btn-primary">Click</button>
</div>
</body>
</html>
<!-- FORMA 2: npm (recomendado para apps reales) -->
<!-- Terminal: -->
<!-- npm install bootstrap -->
<!-- En tu main.jsx o index.js: -->
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
// Ahora puedes usar todas las clases de Bootstrap en JSX:
function MiNavbar() {
return (
<nav className="navbar navbar-expand-lg bg-body-tertiary">
<div className="container">
<a className="navbar-brand" href="#">Mi App</a>
</div>
</nav>
);
}
<!-- FORMA 3: Sass (customizacion profunda) -->
<!-- npm install bootstrap sass -->
<!-- Crea src/custom.scss: -->
$primary: #1e40af; // cambia el color primario
$border-radius: 0.5rem; // cambia el border-radius global
@import "bootstrap/scss/bootstrap";
<!-- En main.jsx: -->
import './custom.scss'; // importa tu version custom de Bootstrap3 formas de instalar Bootstrap: CDN, npm, Sass custom
Cómo instalar Tailwind CSS en tu proyecto Vite (recomendado)
# Terminal: instalar dependencias
npm install -D tailwindcss @tailwindcss/vite
# vite.config.js: agregar Tailwind como plugin
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
plugins: [react(), tailwindcss()],
});
# src/index.css: importar las directivas de Tailwind
@import "tailwindcss";
/* Tu CSS custom aqui (opcional) */
body {
font-family: system-ui, -apple-system, sans-serif;
}
# src/main.jsx: importar el CSS
import './index.css';
# Listo! Ya puedes usar utilities en cualquier archivo JSX:
function App() {
return (
<div className="min-h-screen bg-gray-50">
<nav className="bg-white shadow-md p-4 flex justify-between items-center">
<h1 className="text-2xl font-bold text-blue-600">Mi App</h1>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Iniciar sesion
</button>
</nav>
<main className="container mx-auto p-8">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<div className="bg-white rounded-lg shadow-md p-6 hover:shadow-lg transition-shadow">
<h2 className="text-xl font-semibold mb-2">Pais 1</h2>
<p className="text-gray-600">Descripcion del pais</p>
</div>
</div>
</main>
</div>
);
}Instalación completa de Tailwind CSS 4 en Vite + React
Bootstrap vs Tailwind: cuándo usar cada uno
- USA BOOTSTRAP si: necesitas entregar rápido (MVP, hackathon, proyecto junior), quieres componentes prefabricados sin pensar, tu equipo no tiene experiencia en CSS, el diseño no es prioridad (admin panels, dashboards internos).
- USA TAILWIND si: el diseño es CRÍTICO (landing page, SaaS, app de consumidor), quieres consistencia sin repetir CSS, tu equipo sabe CSS pero quiere ser más rápido, vas a usar React/Vue/Svelte (Tailwind brilla con componentes).
- USA CSS PURO si: tu sitio es muy pequeño (3-5 páginas), quieres aprender CSS a fondo, no quieres dependencias externas, tienes un diseñador que escribe CSS custom.
- USA BULMA si: quieres algo entre Bootstrap y Tailwind, sin JavaScript (solo CSS), con sintaxis más moderna que Bootstrap.
- REGLA DE ORO: para tu primer proyecto, USA BOOTSTRAP. Para tu segundo proyecto, USA TAILWIND. Para el tercero, escribe CSS puro y entiende por qué los frameworks son útiles.
El administrador aún no ha insertado un video para esta sección.
📚 Contenido ampliado
Material adicional, referencias externas verificadas y ejemplos extendidos.
🤖 AI Mission
El responsive se prueba ABRIENDO la página en muchos tamaños. La IA sugiere, tú verificas.
Misión: Toma la página 'Sobre mí' con todos los estilos acumulados (1.3, 1.5, 1.6). Pídele a la IA que te sugiera 3 mejoras responsive concretas. Implementa SOLO lo que entiendas. Después, abre DevTools y prueba en móvil (375px), tablet (768px) y desktop (1280px). Anota 2 problemas que NO hayas anticipado y cómo los resolviste.
Pasos sugeridos
- Abre tu página 'Sobre mí' con todos los estilos aplicados (temas 1.3, 1.5, 1.6).
- En Chrome DevTools, abre el Toggle Device Toolbar (Ctrl+Shift+M).
- Prueba en 5 anchos: 320px (móvil pequeño), 375px (iPhone), 768px (tablet), 1024px (laptop), 1920px (monitor).
- Anota en tu cuaderno: 3 problemas visibles en cada tamaño. ¿Se sale una imagen? ¿El texto se corta? ¿El menú no se ve?
- Pídele a la IA: 'Tengo esta página HTML/CSS. Sugiere 3 mejoras responsive concretas: imgs que se desbordan, tipografía que no escala, layout que no se adapta. Dame el código exacto.' Pega tu CSS actual.
- Implementa las 3 mejoras que sugirió. Ignora las que no entiendas.
- Vuelve a probar en los 5 anchos. ¿Se resolvieron los 3 problemas?
- Anota en tu cuaderno, bajo 'Problemas no anticipados': 2 cosas que NO estaban en la lista de la IA y cómo las resolviste.
📓 Entregable: Capturas de tu página en los 5 anchos (320, 375, 768, 1024, 1920px), las 3 mejoras de la IA implementadas con su diff, y tu cuaderno con los 2 problemas no anticipados.
🚫 Errores típicos de razonamiento
Por qué: Si defines tu contenedor principal con width: 1200px, en un móvil de 375px el contenedor se DESBORDA y aparece scroll horizontal. La solución: usa max-width: 1200px (límite superior) + width: 100% o 1fr (se adapta hacia abajo). Lo mismo con tipografía: rem o em en vez de px. Y con imágenes: max-width: 100% SIEMPRE.
Por qué: Si una sección cambia a 2 columnas a los 800px y otra a los 750px, el sitio se siente inconsistente. Define 4-5 breakpoints estándar (los de la industria: 480, 768, 1024, 1280) y úsalos en TODO el sitio. Documéntalos en una variable CSS o en un comentario al inicio del stylesheet.
Por qué: Sin <meta name='viewport' content='width=device-width, initial-scale=1.0'>, los móviles renderizan la página como si fuera un monitor de 980px y la achican, mostrando todo minúsculo. Es uno de los 4 cimientos del Tema 1.3. Sin él, NADA de responsive funciona. Verifica en cualquier página nueva: este tag debe estar.
Por qué: Si tu imagen pesa 4 MB y la pones en una página vista 60% desde móvil, el 60% de tus usuarios descarga 4 MB inútilmente. Solución: srcset con 3 versiones (móvil, tablet, desktop) + sizes correcto. También puedes usar formato WebP (50% más liviano que JPEG) y lazy loading (loading='lazy' en el <img>).
Por qué: Tu laptop probablemente es 1920x1080 o 1440x900. Pero el mundo usa 375x812 (iPhone), 412x915 (Android típico), 768x1024 (iPad), 1024x1366 (iPad Pro), 1280x800 (laptop pequeño), 2560x1440 (2K), 3840x2160 (4K). SIEMPRE prueba con DevTools > Toggle Device Toolbar en al menos 5 anchos. Y si puedes, prueba en un móvil real.
🧪 Laboratorio práctico
Responsive no se planea: se itera. Prueba, ajusta, repite.
Laboratorio: Página 'Sobre mí' responsive en 5 dispositivos
Objetivo: Tomar la página 'Sobre mí' con todos los estilos acumulados y asegurarse de que se vea perfecta en 5 anchos: 375, 768, 1024, 1280 y 1920 píxeles. Sin scroll horizontal, sin texto cortado, sin imágenes desbordadas.
Pasos
- Abre tu página 'Sobre mí' con los estilos de los temas 1.3, 1.5 y 1.6.
- Verifica que esté el viewport meta tag en el <head>.
- Aplica la regla de imágenes: img, video, iframe { max-width: 100%; height: auto; }.
- Aplica tipografía fluida a h1, h2, h3 con clamp(min, vw, max).
- Convierte el contenedor principal a max-width: 1200px; margin: 0 auto; padding: 1rem 2rem.
- Define los 4 breakpoints estándar en comentarios al inicio del CSS: sm 480, md 768, lg 1024, xl 1280.
- En cada breakpoint, ajusta: número de columnas, tamaño de tipografía, layout del header (hamburguesa vs horizontal), visibilidad de elementos secundarios.
- Prueba con DevTools Toggle Device Toolbar en 5 anchos: 375, 768, 1024, 1280, 1920.
- En cada ancho, verifica: ¿hay scroll horizontal? ¿se ve bien el texto? ¿se ven las imágenes completas? ¿el menú es usable?
- Corrige los problemas que encuentres. Anota los 3 más difíciles.
- Ejecuta Lighthouse > Mobile. El puntaje debe ser 90+.
- Abre en un móvil REAL (o pide prestado uno). Verifica que se ve bien con el dedo (botones suficientemente grandes).
- Haz commit: 'feat: diseño responsive mobile-first con 4 breakpoints'.
📓 Entregable: Capturas de tu página en los 5 anchos, código CSS del media queries con comentarios, Lighthouse Mobile 90+, y prueba en móvil real con captura.