Ir al contenido principal

CSS mantenible sin guerras de metodologías

Hay proyectos que empiezan con una idea simple y acaban con un CSS que nadie quiere tocar. No porque el código sea malo, sino porque cada capa fue creciendo sin una regla clara. Un día alguien metió un !important para salir del paso, otro día se duplicó una variable de color, otro se añadió una utility encima de un componente, y al cabo de seis meses cualquier cambio pequeño tarda una hora.

La solución no es escoger una metodología perfecta y defenderla como si fuera una identidad. BEM, Atomic, OOCSS, Utility-first… ninguna te salva sola. La solución es repartir responsabilidades: hay partes del sistema donde la velocidad importa más, y hay otras donde la consistencia y la previsibilidad son lo que mantienen vivo el proyecto.

Estas son cuatro decisiones que llevo aplicando en proyectos reales y que reducen el dolor cuando el CSS empieza a crecer.

1) Extraer color desde una referencia visual acelera las primeras decisiones.

Cuando una landing, una web o una pieza de marca parte de una imagen real (un mockup de cliente, una foto de producto, una referencia de Pinterest), una paleta bien extraída evita horas de ida y vuelta.

No se trata solo de sacar 5 HEX. Se trata de generar una base que funcione en:

  • Color base (fondos, contenedores).
  • Color de marca (1 o 2 acentos fuertes).
  • Estados (success, error, warning, info — derivados, no inventados).
  • Jerarquía tipográfica (texto principal, secundario, deshabilitado).

Herramientas útiles: el plugin de Figma Image Palette, Coolors para generar variaciones (tints/shades), o un script con culori o chroma.js para sacar la escala completa desde un color base. Si tienes Figma, Variables + Modes te permite definir la paleta una vez y reutilizarla en light/dark sin duplicar.

Regla práctica: nunca pegues un HEX directo en un componente. Aunque sea un MVP. El día que ese color cambie te lo agradecerás.

2) El CSS mantenible importa más cuando el proyecto crece.

En un proyecto pequeño, cualquier solución que funcione parece válida. Pero en cuanto aparecen más páginas, más componentes o más manos tocando el código, el coste real no es escribir CSS rápido — es volver a entenderlo.

Utility CSS (Tailwind, UnoCSS) sirve para avanzar con velocidad. Variables CSS, componentes reutilizables y convenciones claras sirven para que el sistema siga siendo consistente cuando ya no eres tú solo quien lo toca.

La combinación que mejor me funciona:

/* Tokens en :root o @theme — fuente única */
:root {
   --color-brand: oklch(0.65 0.18 250);
   --space-1: 0.25rem;
   --radius-card: 0.75rem;
}

/* Componentes que encapsulan decisiones */
.card {
   padding: var(--space-4);
   border-radius: var(--radius-card);
   background: var(--color-surface);
}

/* Utilities para variaciones contextuales */
<div class="card mt-6 lg:mt-8">...</div>

Tres preguntas que aplico antes de añadir CSS nuevo:

  1. ¿Esta decisión existe ya como token o variable?
  2. ¿Esto es estructural (componente) o puntual (utility)?
  3. ¿En tres meses sabré por qué está aquí sin abrir Git blame?

Si las tres tienen respuesta clara, añade. Si no, para y refactoriza primero.

3) Cascade layers reducen peleas de especificidad.

@layer no es un adorno de modernidad. Es la herramienta más práctica que ha llegado a CSS en los últimos años para ordenar prioridades.

Cuando el proyecto crece, los parches empiezan a competir entre sí: este selector gana porque es más específico, este otro porque lo metieron al final, este tercero porque nadie quería tocar el anterior. Aparece el !important. Aparecen selectores con cuatro clases encadenadas. Aparece el miedo a borrar nada.

Con layers decides el orden de antemano:

@layer reset, base, components, utilities, overrides;
@layer base {
   body { font-family: system-ui; }
}
@layer components {
   .btn { padding: 0.5rem 1rem; }
}
@layer utilities {
   .mt-4 { margin-top: 1rem; }
}

Una declaración en utilities siempre vence a una en components, independientemente de la especificidad del selector. Eso significa que .btn con dos clases ya no le gana a .mt-4. Y los overrides quedan aislados en su propia capa, sin contaminar el resto.

Tailwind v4, Bootstrap 5.3+ y los frameworks modernos ya lo usan internamente. Si no lo aprovechas, estás peleando con las prioridades a mano.

4) Figma plugins y agentes están cambiando el handoff.

Ya no estamos solo en un flujo de diseño → entrega. Estamos en un flujo donde el sistema visual, el código y la iteración se mezclan más. Plugins como Locofy, Anima, Builder.io o Figma Make, y los nuevos servidores MCP de Figma, generan código a partir del diseño en segundos.

Eso no elimina la necesidad de criterio — la hace más importante. Cuanto más automatizado es el paso de diseño a implementación, más claro tiene que estar el sistema, porque la automatización amplifica lo que ya hay: si tu Figma usa colores sueltos y espaciados arbitrarios, el código generado heredará ese caos. Si tu Figma usa Variables, Auto Layout y componentes con variants, el código sale limpio.

Tres cosas que recomiendo si vas a apoyarte en estos flujos:

  • Variables y tokens en Figma alineados con tu CSS. Mismo nombre, misma escala.
  • Componentes con variants bien definidos, no frames sueltos copiados.
  • Revisar siempre la salida. Los agentes generan rápido pero no entienden tu sistema completo. El review es donde aplicas criterio.

En resumen

Si trabajas con Tailwind, Bricks o CSS custom, la pregunta útil es esta: ¿esta decisión hace más fácil mantener el sistema dentro de tres meses?

Si la respuesta no es un sí claro, probablemente no compense.

Menos pelea de metodologías. Más sistema. Más CSS que aguante el tiempo.

CSS mantenible sin guerras de metodologías