Frameworks CSS
Un framework CSS es una colección preconstruida de estilos, componentes y utilidades que acelera el desarrollo web al proveer una base sólida de diseño y layout. En lugar de escribir cada regla CSS desde cero, usás las clases y componentes del framework como bloques de construcción. Los dos más populares hoy son Tailwind CSS (enfoque utility-first donde aplicás clases directamente en el HTML) y Bootstrap 5 (enfoque component-based donde usás componentes predefinidos con HTML semántico). La elección entre uno u otro—o CSS puro—depende del proyecto, el equipo y las prioridades.
Los frameworks CSS nacieron para resolver problemas reales: inconsistencia entre navegadores, diseño responsivo complejo, accesibilidad básica y la necesidad de iterar rápidamente en prototipos. Sin embargo, usan un framework implica adoptar sus convenciones, su tamaño (aunque sea tree-shakeable), y su curva de aprendizaje. No es una decisión neutral—un framework moldea cómo escribís HTML y cómo piensas el layout. Por eso es crucial entender qué ofrece cada uno, cuándo vale la pena y cuándo CSS puro es la mejor opción.
Qué son y cuándo usarlos
Un framework CSS es una librería que provee un sistema de diseño predefinido: tipografía, colores, espaciado, componentes (botones, cards, modales, navbars), layouts (grids, containers, flex utilities) y a menudo funcionalidad JavaScript. La diferencia clave con una simple librería de CSS es que un framework impone una arquitectura y una filosofía: no solo te da herramientas, te dice cómo usarlas. Bootstrap te dice "usá un <div class="card"> con esta estructura HTML", mientras que Tailwind te dice "usá estas clases utility directamente en tus elementos".
Cuándo tiene sentido usar un framework
/* ============================================
CUANDO USAR UN FRAMEWORK
============================================ */
/* SI: Prototipado rápido */
/* Necesitás un MVP o un dashboard admin en días, no semanas.
Los frameworks te dan componentes listos (tablas, formularios,
modales, notificaciones) que te ahorran semanas de trabajo. */
/* SI: Equipos grandes o freelancers */
/* Un equipo de 5+ devs necesita consistencia visual.
Un framework estándariza colores, tipografía y componentes
sin depender de un solo diseñador. */
/* SI: Aplicaciones web internas */
/* Dashboards, paneles de admin, CRMs, ERPs.
No necesitás un diseño único—necesitás funcionalidad
rápida y consistencia. Bootstrap o Tailwind brillan aquí. */
/* SI: Poca experiencia en diseño CSS */
/* Si recién empezás, un framework te da un punto de partida
con decisiones de diseño ya tomadas (colores, spacing, fonts). */
/* ============================================
CUANDO NO USAR UN FRAMEWORK (CSS PURO)
============================================ */
/* NO: Sitios con identidad visual única */
/* Si el brief dice "diseño custom, nada genérico", un framework
te va a luchar. Vas a sobreescribir la mayoría de estilos
y terminarás con CSS puro + overhead del framework. */
/* NO: Sitios estáticos pequeños */
/* Un landing page de 5 secciones no necesita Bootstrap.
CSS puro es más ligero, más rápido de cargar,
y te da control total sin dependencias. */
/* NO: Cuando el rendimiento es crítico */
/* Incluso con tree-shaking, un framework añade peso.
Para sitios donde cada kilobyte cuenta (mobile en 3G,
PWAs, Core Web Vitals agresivos), CSS puro gana. */
/* NO: Quieres aprender CSS de verdad */
/* Los frameworks abstraen CSS. Si no entendés box model,
specificity y flexbox/grid, el framework es una muleta,
no una solución. */
| Criterio | Framework CSS | CSS Puro |
|---|---|---|
| Velocidad de desarrollo | Rápido (componentes prehechos) | Más lento (escribís todo) |
| Tamaño del CSS | Variable (PurgeCSS/Tailwind JIT: solo lo usado) | Mínimo (solo lo que necesitás) |
| Personalización | Limitada a la API del framework | Total y sin restricciones |
| Consistencia | Alta (el framework la impone) | Depende de tu disciplina |
| Curva de aprendizaje | Media (aprender las clases/API) | Baja (CSS es el estándar) |
| Dependencia | Alta (versiones, breaking changes) | Ninguna (CSS no tiene versiones) |
| Look genérico | Alto riesgo ("se nota que es Bootstrap") | Bajo riesgo (diseño único) |
Tailwind CSS: filosofía utility-first
Tailwind CSS es el framework CSS más popular del mundo en la actualidad según múltiples encuestas (State of CSS, State of JS). Su enfoque utility-first es radicalmente diferente a los frameworks tradicionales: en lugar de darte componentes prehechos (.card, .btn, .navbar), te da clases atómicas de una sola propiedad: flex, p-4, text-blue-500, rounded-lg, hover:bg-gray-100. El HTML termina con muchas clases, pero el resultado es un CSS extremadamente eficiente porque solo se genera lo que usás (gracias al compilador JIT, Just-In-Time).
Concepto utility-first
En el modelo utility-first, cada clase CSS hace una sola cosa. No hay un .card con padding, fondo, borde y sombra todo junto—en su lugar, aplicás las clases individuales que necesitás. Esto suena tedioso al principio, pero tiene ventajas enormes: no te peleás con nombres de clases ("¿será .card-title o .card__title?"), no hay specificity wars (todas las clases tienen la misma especificidad), y el diseño vive en el HTML donde lo podés ver completo, en lugar de estar repartido entre HTML y CSS. Tailwind v4 (2024) introdujo un motor basado en Rust aún más rápido y una sintaxis simplificada con CSS-first configuration.
<!-- ============================================
TAILWIND: utility-first en acción
Cada clase = una propiedad CSS
============================================ -->
<!-- Card con Tailwind -->
<div class="max-w-sm rounded-2xl border border-gray-200 bg-white
p-6 shadow-lg hover:shadow-xl transition-shadow">
<img src="foto.jpg"
alt="Foto de perfil"
class="h-48 w-full rounded-xl object-cover mb-4">
<h3 class="text-xl font-semibold text-gray-900 mb-2">
María González
</h3>
<p class="text-gray-600 text-sm leading-relaxed mb-4">
Desarrolladora frontend en Buenos Aires.
Apasionada por CSS y la accesibilidad web.
</p>
<div class="flex gap-2">
<button class="rounded-lg bg-blue-600 px-4 py-2 text-sm
font-medium text-white hover:bg-blue-700
transition-colors">
Seguir
</button>
<button class="rounded-lg border border-gray-300 px-4 py-2
text-sm font-medium text-gray-700
hover:bg-gray-50 transition-colors">
Mensaje
</button>
</div>
</div>
<!-- Equivalente en CSS puro (lo que se generaría) -->
<!--
.max-w-sm { max-width: 24rem; }
.rounded-2xl { border-radius: 1rem; }
.border { border-width: 1px; }
.border-gray-200 { border-color: #e5e7eb; }
.bg-white { background-color: #ffffff; }
.p-6 { padding: 1.5rem; }
.shadow-lg { box-shadow: 0 10px 15px rgba(0,0,0,0.1); }
.hover\:shadow-xl:hover { box-shadow: 0 20px 25px rgba(0,0,0,0.1); }
.transition-shadow { transition: box-shadow 150ms; }
-->
Configuración
Tailwind se configura con un archivo tailwind.config.js donde definís tu tema: colores custom, fuentes, breakpoints, espaciado, border-radius y más. A partir de v4, la configuración puede vivir directamente en CSS con @theme. El compilador JIT genera solo las clases que encontrá en tu HTML/JS/templating, así que el CSS final pesa apenas unos kilobytes sin importar cuántas clases tiene el framework. Esto resuelve la crítica histórica de "Tailwind genera CSS gigante".
// tailwind.config.js (Tailwind v3)
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
'./index.html',
'./src/**/*.{html,js,jsx,ts,tsx,vue,svelte}',
// Solo escanea estos archivos para generar CSS
],
theme: {
// Extender el tema por defecto (no lo sobreescribe)
extend: {
colors: {
brand: {
50: '#eff6ff',
100: '#dbeafe',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
900: '#1e3a5f',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
mono: ['JetBrains Mono', 'monospace'],
display: ['Space Grotesk', 'sans-serif'],
},
spacing: {
'18': '4.5rem',
'88': '22rem',
'128': '32rem',
},
maxWidth: {
'8xl': '88rem',
},
borderRadius: {
'4xl': '2rem',
},
// Keyframes custom
keyframes: {
'fade-in': {
from: { opacity: '0', transform: 'translateY(10px)' },
to: { opacity: '1', transform: 'translateY(0)' },
},
},
animation: {
'fade-in': 'fade-in 0.5s ease-out',
},
},
},
plugins: [
require('@tailwindcss/forms'), // Estilos para formularios
require('@tailwindcss/typography'), // Prose para contenido
require('@tailwindcss/container-queries'), // Container queries
],
}
Responsive con Tailwind
El sistema responsive de Tailwind es mobile-first y funciona con prefijos de breakpoint en las clases: sm: (640px+), md: (768px+), lg: (1024px+), xl: (1280px+), 2xl: (1536px+). Cada clase sin prefijo aplica en todos los tamaños, y con prefijo aplica solo desde ese breakpoint en adelante. Esto permite definir el layout completo de un elemento en una sola línea de HTML, sin necesidad de media queries separadas. Es una de las features más productivas de Tailwind.
<!-- ============================================
TAILWIND: responsive con prefijos
Mobile-first: sin prefijo = base (mobile)
============================================ -->
<!-- Grid responsivo -->
<div class="grid grid-cols-1 /* 1 columna en mobile */
md:grid-cols-2 /* 2 columnas desde 768px */
lg:grid-cols-3 /* 3 columnas desde 1024px */
xl:grid-cols-4 /* 4 columnas desde 1280px */
gap-4 md:gap-6 lg:gap-8">
<div class="p-4 md:p-6 lg:p-8">Card 1</div>
<div class="p-4 md:p-6 lg:p-8">Card 2</div>
<div class="p-4 md:p-6 lg:p-8">Card 3</div>
<div class="p-4 md:p-6 lg:p-8">Card 4</div>
</div>
<!-- Tipografía responsive -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl
font-bold text-gray-900 tracking-tight">
Título responsivo
</h1>
<!-- Navbar responsiva -->
<nav class="flex flex-col md:flex-row items-center
justify-between p-4 md:p-6 max-w-7xl mx-auto">
<div class="logo text-xl font-bold">Brand</div>
<div class="hidden md:flex gap-6"> /* Oculto en mobile */
<a href="#" class="hover:text-blue-600">Inicio</a>
<a href="#" class="hover:text-blue-600">Productos</a>
<a href="#" class="hover:text-blue-600">Contacto</a>
</div>
<!-- Hamburguesa solo en mobile -->
<button class="md:hidden">Menu</button>
</nav>
<!-- ============================================
ARBITRARY VALUES: valores custom inline
============================================ -->
<!-- Cuando necesitas un valor que no existe en la escala -->
<div class="w-[320px] /* width: 320px */
mt-[1.75rem] /* margin-top: 1.75rem */
text-[13px] /* font-size: 13px */
bg-[#1a1a2e]"> /* background: #1a1a2e */
Valores arbitrarios con corchetes
</div>
Dark Mode y estado
Tailwind soporta dark mode de dos formas: media (basado en la preferencia del sistema operativo, usando prefers-color-scheme) o class (basado en una clase en el <html>, generalmente dark, que permite un toggle manual). El enfoque class es el más usado porque permite que el usuario elija su tema independientemente del sistema. Las variaciones de estado (hover, focus, active, disabled, visited) se aplican con el prefijo del estado: hover:, focus:, disabled:, etc. Se pueden combinar con breakpoints: md:hover:bg-blue-700.
<!-- ============================================
DARK MODE (estrategia 'class')
============================================ -->
<!-- tailwind.config.js -->
<!-- darkMode: 'class', -->
<!-- El toggle agrega/quita la clase 'dark' en <html> -->
<!-- <html class="dark"> o <html> -->
<!-- Elementos con variante dark: -->
<div class="bg-white text-gray-900
dark:bg-gray-900 dark:text-gray-100
p-6 rounded-xl">
<p class="text-gray-600 dark:text-gray-400">
Este texto cambia de color en dark mode.
</p>
</div>
<!-- Card con dark mode completo -->
<div class="bg-white border border-gray-200 rounded-2xl p-6
shadow-sm
dark:bg-gray-800 dark:border-gray-700
dark:shadow-none">
<h3 class="text-lg font-semibold text-gray-900
dark:text-white">
Título de la card
</h3>
<p class="mt-2 text-gray-500 dark:text-gray-400">
Descripción que se adapta al tema.
</p>
</div>
<!-- ============================================
ESTADOS: hover, focus, active, disabled
============================================ -->
<!-- Botón con estados -->
<button class="rounded-lg bg-blue-600 px-4 py-2
text-sm font-medium text-white
hover:bg-blue-700
active:bg-blue-800
focus:outline-none focus:ring-2
focus:ring-blue-500 focus:ring-offset-2
disabled:opacity-50 disabled:cursor-not-allowed
transition-colors">
Guardar cambios
</button>
<!-- Input con estados -->
<input type="email"
class="w-full rounded-lg border border-gray-300
px-4 py-2 text-sm
placeholder-gray-400
focus:border-blue-500 focus:ring-2
focus:ring-blue-500/20
invalid:border-red-500
dark:bg-gray-800 dark:border-gray-600
dark:text-white">
<!-- Estados + responsive combinados -->
<!-- Este botón tiene diferente padding en mobile vs desktop -->
<button class="px-4 py-2 md:px-6 md:py-3
hover:bg-gray-100 md:hover:bg-gray-200
transition-colors">
Botón adaptativo
</button>
Componentes reutilizables
Aunque Tailwind es utility-first, no significa que debás repetir clases en cada elemento. Cuando un patrón se repite, lo extraes como componente usando las herramientas de tu framework JS (React components, Vue SFCs, Svelte components) o simplemente con clases CSS propias que agrupan las utilities. También puedes usar la directiva @apply en CSS, aunque el equipo de Tailwind recomienda usar componentes JS en su lugar.
/* ============================================
TAILWIND: @apply para componentes CSS
(use con moderacion, preferi componentes JS)
============================================ */
/* Con @apply: agrupas utilities en una clase CSS */
.btn-primary {
@apply rounded-lg bg-blue-600 px-4 py-2
text-sm font-medium text-white
hover:bg-blue-700 active:bg-blue-800
focus:outline-none focus:ring-2
focus:ring-blue-500 focus:ring-offset-2
transition-colors disabled:opacity-50;
}
.btn-secondary {
@apply rounded-lg border border-gray-300
bg-white px-4 py-2 text-sm
font-medium text-gray-700
hover:bg-gray-50 active:bg-gray-100
transition-colors;
}
.card {
@apply rounded-2xl border border-gray-200
bg-white p-6 shadow-sm
dark:border-gray-700 dark:bg-gray-800;
}
/* ============================================
MEJOR OPCION: Componentes en tu framework JS
============================================ */
/* Ejemplo conceptual (no es framework real) */
/*
<!-- ButtonComponent -->
<button class="btn-primary">Texto</button>
<!-- CardComponent -->
<div class="card">
<slot />
</div>
*/
Tailwind sin build tool (CDN Play)
Tailwind tiene un Play CDN para prototipos y experiments rápidos: agregás un <script src="https://cdn.tailwindcss.com"> y tenés Tailwind completo sin instalación ni build. Genera las classes en tiempo real en el navegador. Es perfecto para pruebas rápidas, CodePen, y aprendizaje. No lo usés en producción porque es más lento que el compilador JIT nativo.
Bootstrap 5: componentes y grid system
Bootstrap es el framework CSS más conocido y usado históricamente. Creado por el equipo de Twitter en 2011, revolucionó el desarrollo web al estandarizar un grid system, componentes UI consistentes y un ecosistema de plugins. La versión 5 (2021) eliminó la dependencia de jQuery, migró a CSS nativo (custom properties), reescribió los componentes con CSS puro y mejoró el soporte de dark mode. Aunque perdió terreno frente a Tailwind en los últimos años, sigue siendo la opción más popular para prototipado rápido, aplicaciones empresariales y proyectos donde la consistencia visual importa más que la personalización extrema.
Grid System
El grid system de Bootstrap es una de sus features más icónicas: un grid de 12 columnas que funciona con clases .container, .row y .col-*. El container centra el contenido con un max-width responsivo, la row crea un flex container, y las columnas se distribuyen dentro del grid de 12. Los breakpoints son: sm (576px), md (768px), lg (992px), xl (1200px), xxl (1400px). Se pueden combinar para layouts complejos, y las columnas que no especifican ancho se distribuyen equitativamente.
<!-- ============================================
BOOTSTRAP 5: Grid System
Grid de 12 columnas, mobile-first
============================================ -->
<!-- Layout básico: container > row > col -->
<div class="container">
<div class="row">
<div class="col">Col 1 (igual ancho)</div>
<div class="col">Col 2 (igual ancho)</div>
<div class="col">Col 3 (igual ancho)</div>
</div>
</div>
<!-- Columnas con ancho específico (de 12) -->
<div class="container">
<div class="row">
<div class="col-4">1/3 del ancho</div>
<div class="col-8">2/3 del ancho</div>
</div>
</div>
<!-- Responsive: diferente layout por breakpoint -->
<div class="container">
<div class="row">
<!-- Mobile: 12 (full), Tablet: 6 (1/2), Desktop: 3 (1/4) -->
<div class="col-12 col-md-6 col-lg-3">Card 1</div>
<div class="col-12 col-md-6 col-lg-3">Card 2</div>
<div class="col-12 col-md-6 col-lg-3">Card 3</div>
<div class="col-12 col-md-6 col-lg-3">Card 4</div>
</div>
</div>
<!-- Sidebar layout -->
<div class="container">
<div class="row">
<!-- Sidebar: 3 columnas, Main: 9 columnas -->
<aside class="col-12 col-lg-3">Sidebar</aside>
<main class="col-12 col-lg-9">Contenido</main>
</div>
</div>
<!-- Offset y orden -->
<div class="container">
<div class="row">
<!-- Empieza en la columna 3 (offset-2) -->
<div class="col-6 offset-md-3">Centrado</div>
</div>
<div class="row">
<!-- Invierte el orden visual en desktop -->
<div class="col-md-6 order-md-2">Primero visualmente</div>
<div class="col-md-6 order-md-1">Segundo visualmente</div>
</div>
</div>
Componentes
Bootstrap 5 incluye docenas de componentes listos para usar: navbar (navegación responsiva con colapso), cards (con header, body, footer), modals (diálogos con backdrop), accordion, tabs, carousel/slider, offcanvas (paneles laterales), toasts (notificaciones), dropdowns, collapse, alerts, badges, progress bars, spinners, tooltips y popovers. La mayoría tienen JavaScript incluido (ya no jQuery) y soporte de data attributes para activarlos sin escribir JS. Estos componentes son la principal razón por la que Bootstrap sigue siendo relevante: son consistentes, accesibles y funcionan out-of-the-box.
<!-- ============================================
BOOTSTRAP 5: Componentes esenciales
============================================ -->
<!-- Navbar responsiva (colapsa en mobile) -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">MiSitio</a>
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navContent">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navContent">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Inicio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Productos</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contacto</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Card -->
<div class="card" style="width: 18rem;">
<img src="imagen.jpg" class="card-img-top" alt="Foto">
<div class="card-body">
<h5 class="card-title">Título de la card</h5>
<p class="card-text">Descripción breve del contenido.</p>
</div>
<div class="card-body">
<a href="#" class="btn btn-primary">Ver más</a>
</div>
</div>
<!-- Modal (sin escribir JS, solo data attributes) -->
<!-- Botón que abre el modal -->
<button type="button" class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#miModal">
Abrir modal
</button>
<!-- El modal -->
<div class="modal fade" id="miModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Título</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Contenido del modal.</p>
</div>
<div class="modal-footer">
<button class="btn btn-secondary"
data-bs-dismiss="modal">Cerrar</button>
<button class="btn btn-primary">Guardar</button>
</div>
</div>
</div>
</div>
<!-- Alerts -->
<div class="alert alert-success" role="alert">
Operación exitosa.
</div>
<div class="alert alert-danger" role="alert">
Error: campos incompletos.
</div>
Dark Mode en Bootstrap 5
Bootstrap 5.3+ soporta dark mode nativo con la estrategia data-bs-theme="dark" en el <html> o en cualquier contenedor. Las custom properties de Bootstrap cambian automáticamente según el tema, igual que en nuestro proyecto WebForge. A diferencia de Tailwind donde necesitás duplicar clases (bg-white dark:bg-gray-900), Bootstrap aplica el cambio globalmente a través de variables CSS, lo que es más elegante pero menos granular (no podés tener un componente en light y otro en dark en la misma página sin JavaScript extra).
<!-- ============================================
BOOTSTRAP 5: Dark Mode
============================================ -->
<!-- Light mode (por defecto) -->
<html data-bs-theme="light">
<!-- Dark mode global -->
<html data-bs-theme="dark">
<!-- Toggle automático (respeta preferencia del SO) -->
<html data-bs-theme="auto">
<!-- Dark mode en un solo componente (no todo el page) -->
<div data-bs-theme="dark">
<!-- Este div y todo lo dentro está en dark mode -->
<nav class="navbar navbar-dark bg-dark">...</nav>
</div>
<!-- ============================================
Toggle JS para Bootstrap dark mode
============================================ -->
<!--
<script>
const toggle = document.getElementById('themeToggle');
const html = document.documentElement;
toggle.addEventListener('click', () => {
const current = html.getAttribute('data-bs-theme');
const next = current === 'dark' ? 'light' : 'dark';
html.setAttribute('data-bs-theme', next);
localStorage.setItem('theme', next);
});
// Restaurar tema guardado
const saved = localStorage.getItem('theme');
if (saved) html.setAttribute('data-bs-theme', saved);
</script>
-->
Bootstrap Icons
Bootstrap tiene su propia librería de iconos (bootstrap-icons) con más de 1800 iconos SVG. Son consistentes con el estilo de Bootstrap y se usan como clases CSS: <i class="bi bi-house"></i>. Son una alternativa a Lucide Icons o FontAwesome si ya usás Bootstrap en tu proyecto.
Comparativa: Tailwind vs Bootstrap
La elección entre Tailwind y Bootstrap es una de las decisiones más debatidas en el desarrollo frontend. No hay un ganador absoluto—cada uno brilla en contextos diferentes. La clave es entender sus filosofías opuestas: Tailwind te da herramientas atómicas para construir diseños custom, mientras Bootstrap te da componentes prehechos para prototipar rápidamente. La siguiente tabla resume las diferencias más importantes para ayudarte a elegir según tu proyecto.
| Aspecto | Tailwind CSS | Bootstrap 5 |
|---|---|---|
| Filosofía | Utility-first: clases atómicas, diseño en HTML | Component-based: componentes prehechos con HTML semántico |
| Apariencia | Indeterminada (lo hacés custom) | Determinada (look "Bootstrap" reconocible) |
| Curva de aprendizaje | Media (memorizar clases, pensar en utilities) | Baja (copiar/pegar componentes, HTML semántico) |
| Personalización | Máxima (cada pixel es controlable) | Media (customizar Sass variables, overrides) |
| Tamaño en producción | Pequeño (JIT genera solo lo usado: ~5-15KB gzipped) | Medio (~22KB CSS min + ~7KB JS gzipped) |
| Build tool | Requerido (PostCSS plugin o CLI) | Opcional (CDN funciona, pero Sass para customizar) |
| Componentes JS | No tiene (necesitás un framework JS: React, Vue, etc.) | Incluidos (modals, dropdowns, carousel via data attributes) |
| Dark mode | Clase por clase (dark:bg-...) - granular |
Global (data-bs-theme) - automático |
| HTML generado | Verboso (muchas clases por elemento) | Limpio (componentes semánticos) |
| Consistencia en equipo | Alta (las utilities limitan las opciones) | Muy alta (los componentes estándarizan todo) |
| Comunidad / ecosistema | Enorme (Tailwind UI, Headless UI, shadcn/ui) | Enorme (Bootswatch, THEMES, AdminLTE) |
Elige Tailwind si...
/* ============================================
ELIGE TAILWIND SI:
============================================ */
/* Necesitás un diseño visual único y custom.
No querés que tu sitio parezca "otro Bootstrap más".
Tailwind te da control total sobre cada detalle visual. */
/* Ya usás un framework JS (React, Vue, Svelte, Next.js).
Tailwind se integra naturalmente con componentes JS.
Los componentes de Bootstrap son innecesarios si tenés React. */
/* Te importa el tamaño del bundle.
JIT genera solo las clases que usás (~5-15KB gzipped).
Es prácticamente impossible superar ese tamaño con CSS puro. */
/* Tu equipo prefiere "todo en un lugar".
El diseño vive en el HTML, no repartido entre HTML y CSS.
Es fácil ver qué hace cada elemento mirando sus clases. */
/* Querés iterate rápido en el diseño.
Cambiar colores, espaciado y layouts es cuestion de
modificar clases, no de buscar reglas CSS en archivos. */
Elige Bootstrap si...
/* ============================================
ELIGE BOOTSTRAP SI:
============================================ */
/* Necesitás prototipar rápidamente.
Copiar/pegar un navbar, modal, o card y tenerlo
funcionando en 30 segundos es invalorable. */
/* No usás un framework JS.
Bootstrap trae sus propios componentes interactivos
(modals, dropdowns, tabs) que funcionan con Vanilla JS.
Sin React, sin Vue, sin build tool. */
/* Es un proyecto interno / admin panel / dashboard.
La consistencia visual importa más que el branding custom.
Bootstrap tiene themes admin (AdminLTE, Tabler) listos. */
/* Tu equipo tiene poca experiencia CSS.
Bootstrap impone buenas prácticas y estructura.
Es más fácil aprender que "un card va adentro de
un col-6 que va adentro de un row" que entender flexbox/grid. */
/* Querés usar CDN sin build tool.
Bootstrap funciona perfectamente con un solo link tag.
Ideal para sitios pequeños, demos, o aprendizaje. */
CSS Puro vs Frameworks: resumen final
La decisión entre CSS puro y un framework no es binaria—muchos proyectos exitosos usan un enfoque híbrido: un framework para prototipar y una base de CSS custom para la identidad visual. Sin embargo, es importante entender las trade-offs. CSS puro te da máximo control, cero dependencias y la mejor comprensión de lo que está pasando, pero es más lento para proyectos grandes. Un framework te da velocidad y consistencia, pero te ata a sus convenciones y puede generar un look genérico si no lo personalizás bien. La elección depende del contexto, no de la preferencia personal.
Escenarios por tipo de proyecto
| Tipo de proyecto | Recomendación | Por qué |
|---|---|---|
| Portfolio / Landing personal | CSS puro | Identity visual única, poco contenido, máximo control. |
| Blog / Sitio de contenido | CSS puro o Tailwind | Tipografía y layout son lo principal, pocos componentes. |
| E-commerce | Tailwind | Componentes custom, equipo grande, rendimiento crítico. |
| Dashboard / Admin panel | Bootstrap o Tailwind | Muchas tablas, formularios y cards. Consistencia = prioridad. |
| Prototipo / MVP | Bootstrap (CDN) | Velocidad máxima, componentes listos, sin build. |
| SaaS / App compleja | Tailwind + componentes | Diseño custom, many components, equipo con framework JS. |
| Proyecto educativo / aprendizaje | CSS puro | Aprender CSS de verdad sin abstracciones. Este manual lo demuestra. |
| Proyecto legacy / mantenimiento | Lo que ya tenga | No migres solo por gusto. La migración tiene costo. |
Alternativas menores
Más allá de Tailwind y Bootstrap, existen otros frameworks y librerías CSS que vale la pena mencionar, aunque con menor market share. Bulma es un framework CSS-only (sin JS) con una sintaxis basada en Flexbox y un diseño moderno. Pico CSS es minimalista: estiliza elementos HTML semánticos sin clases, ideal para contenido. Open Props de Adam Argyle es un set de custom properties CSS (no un framework) que te da variables de color, espaciado y tipografía listas para usar con CSS puro. UnoCSS es un engine utility-first similar a Tailwind pero más rápido y extensible. Windi CSS (ahora en mantenimiento) fue una alternativa a Tailwind con un runtime más rápido. Cada uno tiene su nicho, pero para la inmensa mayoría de proyectos la elección real es: CSS puro, Tailwind o Bootstrap.
No olvides: un framework no reemplaza aprender CSS
Saber usar Tailwind o Bootstrap no es lo mismo que entender CSS. Si no conocés box model, specificity, cascada, flexbox, grid, positioning y las unidades relativas, vas a tropezar constantemente con problemas que no sabrás resolver. Los frameworks son herramientas de productividad, no sustitutos de conocimiento. Aprender CSS puro primero (como en este manual) te hace más efectivo con cualquier framework después.
WebForge usa CSS puro
Este proyecto es una demostración viviente de que CSS puro es suficiente para un sitio complejo y con buen diseño. Sin frameworks, sin preprocesadores, sin build tools—solo HTML5 semántico, CSS3 con custom properties, y Vanilla JS. Si entendés todo lo que hay en este manual, tenés las herramientas para construir cualquier layout que un framework pueda dar, con ventaja de control total y cero dependencias.