Ecosistema UI: Tailwind + componentes “headless”
El problema real no es el CSS, es la lógica de interacción
A partir de cierto tamaño, una UI deja de fallar por estilos y empieza a fallar por:
- estados mal sincronizados,
- accesibilidad incompleta,
- combinaciones imposibles,
- interacciones frágiles.
Aquí es donde aparecen los componentes headless.
Tailwind resuelve cómo se ve. Los headless resuelven cómo se comporta.
Qué es un componente headless (y qué no)
Un componente headless:
- No trae estilos
- Expone estado, roles y eventos
- Implementa accesibilidad correcta
- Delega el render al consumidor
No es:
- Un componente “feo”
- Un framework visual
- Una abstracción opcional
Es una capa de comportamiento reutilizable.
Por qué Tailwind encaja perfectamente con lo headless
Tailwind y los headless encajan porque:
- Tailwind necesita control total del markup
- Los headless no imponen markup
- Ambos favorecen composición explícita
- Ambos evitan cascadas ocultas
Resultado:
- Diseño libre
- Lógica sólida
- Accesibilidad correcta
- Sin peleas con CSS ajeno
El error clásico: confundir “headless” con “sin criterio”
Un componente headless no decide por ti, pero:
- Exige que tomes decisiones conscientes
- Expone estados que debes representar bien
- Te obliga a pensar en UX real
Error común:
- Renderizar estados sin jerarquía
- No diferenciar visualmente foco, hover, active
- Ignorar estados como
disabled,open,selected
Headless no es más fácil. Es más honesto.
Estados explícitos: la materia prima del diseño
Los headless exponen estados como:
open / closedactive / inactiveselected / unselecteddisabledfocused
El trabajo del diseñador/desarrollador es:
- Decidir cómo se ven
- Decidir qué prioridad tienen
- Decidir qué animación (si aplica)
Tailwind es ideal para mapear estados → decisiones visuales.
Accesibilidad “by default”, no “si hay tiempo”
Los componentes headless bien diseñados:
- Gestionan focus
- Respetan teclado
- Añaden roles ARIA correctos
- Cumplen expectativas del navegador
Esto elimina:
- hacks manuales,
- bugs sutiles,
- deuda invisible.
Accesibilidad no es un extra. Es una consecuencia de usar buenas abstracciones.
Ejemplos típicos de componentes headless
Casos donde no deberías reinventar la rueda:
- Menús desplegables
- Selects
- Combobox
- Dialogs / Modals
- Tabs
- Switches
- Tooltips
No por estética, sino por:
- gestión de foco,
- teclado,
- edge cases.
Qué aporta un ecosistema headless maduro
Un buen ecosistema headless:
- Tiene API estable
- Expone estados claros
- No impone estructura visual
- Se integra bien con frameworks modernos
Y lo más importante:
- No lucha contra Tailwind
Dónde vive la arquitectura cuando usas headless
En este punto, la arquitectura se reparte así:
- Headless: lógica, estado, accesibilidad
- Tailwind: diseño, microinteracciones, composición
- Componentes propios: identidad y sistema visual
Separación clara de responsabilidades.
Peligros comunes al integrar headless + Tailwind
- Estilizar sin entender el estado
- Usar solo el estado “feliz”
- Ignorar focus-visible
- Crear variantes visuales sin sentido semántico
- Copiar ejemplos sin integrarlos al sistema
Headless no elimina la necesidad de sistema
De hecho, la refuerza.
Si no tienes:
- tokens claros,
- variantes gobernadas,
- reglas de composición,
los headless se convierten en:
- caos estilístico,
- UI inconsistente,
- deuda rápida.
Señales de una buena integración
- El componente se entiende solo por su estado
- El foco es siempre visible
- El teclado funciona sin pensar
- El diseño sigue siendo coherente
- El componente se puede reutilizar sin miedo
Errores frecuentes en equipos intermedios
- Usar librerías visuales “por velocidad”
- Mezclar estilos propios con CSS externo
- Ignorar accesibilidad hasta el final
- Pensar que Tailwind reemplaza la lógica