wandres.dev
ARQUITECTURA I · De BEM a los tokens de diseño

OOCSS y SMACSS: separar y categorizar

Las dos primeras metodologías serias: qué separaba exactamente OOCSS y por qué su segunda regla tardó quince años en ser posible, y qué aportó la taxonomía de SMACSS.

⏱ 17 min

En 2009 nadie hablaba de arquitectura de CSS. Nicole Sullivan, trabajando sobre hojas de estilo de portales enormes, publicó dos principios que sonaban a herejía: no escribas un estilo para cada cosa, y no hagas que un componente sepa dónde está. Dos años después Jonathan Snook publicó SMACSS, que no proponía principios nuevos sino algo distinto y más útil de lo que parece: una taxonomía. Las dos siguen vivas dentro de todo lo que escribes hoy, aunque ya nadie las nombre.

🎯 Al terminar esta lección sabrás
  • Explicar los dos principios de OOCSS y el patrón que los ilustra.
  • Entender por qué la separación de contenedor y contenido era imposible de cumplir hasta 2023.
  • Describir las cinco categorías de SMACSS y qué problema resolvía cada una.
  • Reconocer qué parte de ambas sobrevive intacta en el CSS de 2026.

OOCSS: dos separaciones

OOCSS no es programación orientada a objetos aplicada a CSS, pese al nombre. Son dos reglas de separación.

Primera: separa la estructura de la piel. Un componente tiene propiedades que definen su forma —el relleno, el modelo de caja, la disposición interna— y propiedades que definen su apariencia —el color, el borde, la sombra—. Si las escribes juntas en una clase, cada combinación de forma y apariencia necesita una clase nueva, y el número de clases crece como el producto de ambas. Si las separas, crece como la suma.

/* estructura: como se comporta */
.tarjeta {
  display: grid;
  gap: 1rem;
  padding: 1.25rem;
  border-radius: 0.75rem;
}

/* piel: como se ve */
.tono-neutro { background: var(--superficie); border: 1px solid var(--borde); }
.tono-aviso  { background: var(--superficie-aviso); border: 1px solid var(--borde-aviso); }

Tres estructuras y cuatro pieles son siete clases combinables en lugar de doce clases específicas. Con seis y ocho, son catorce en lugar de cuarenta y ocho. Esa es toda la matemática y sigue siendo válida.

Segunda: separa el contenedor del contenido. Un componente no debe depender de dónde se coloca. Escribir .sidebar .tarjeta { padding: 0.5rem } acopla la tarjeta a la barra lateral: la tarjeta deja de ser reutilizable y el número de excepciones crece con el número de sitios donde la pongas.

Este segundo principio es el más importante de toda la historia de la arquitectura de CSS, y también el que era imposible de cumplir de verdad. La razón es sencilla: un componente sí necesita adaptarse al espacio que le dan. Una tarjeta en una columna estrecha tiene que apilar su contenido y una en una ancha ponerlo en fila. Antes de las container queries, las únicas formas de expresar eso eran una media query —que consulta la ventana, no el hueco— o una clase modificadora que le dice al componente dónde está, que es exactamente el acoplamiento que la regla prohibía.

Es decir: durante catorce años, OOCSS te pedía algo que el lenguaje no permitía hacer. La gente lo cumplía a medias, se sentía culpable, y llamaba a eso “pragmatismo”. No lo era: era una carencia del lenguaje que se resolvió en 2023 con @container. La regla no estaba equivocada; le faltaba el mecanismo.

💡
El objeto media, el patrón que sobrevivió a todo

El ejemplo canónico de OOCSS es el objeto media: una imagen o icono a un lado y un bloque de texto al otro, con el texto ocupando el espacio restante. Sullivan señaló que ese patrón aparecía docenas de veces en la misma página con estilos distintos escritos desde cero cada vez. Hoy son tres líneas de Flexbox o Grid, y sigue siendo el mismo objeto. Que un patrón identificado en 2009 siga siendo la unidad de composición más frecuente de la web dice algo sobre lo bien elegido que estaba.

SMACSS: el valor de tener nombres para las cosas

SMACSS —Scalable and Modular Architecture for CSS, Jonathan Snook, 2011— no propone principios de diseño. Propone cinco categorías en las que clasificar cada regla que escribes, y afirma que el simple hecho de clasificarlas resuelve la mitad del desorden.

Categoría Qué contiene Ejemplo
Base valores por defecto de elementos, sin clases body, a, h1
Layout las divisiones grandes de la página .l-cabecera, .l-columna
Module los componentes reutilizables .tarjeta, .menu
State estados que se activan y desactivan .is-abierto, .is-oculto
Theme variaciones de apariencia global .tema-oscuro

La aportación real no es la lista, es lo que la lista te obliga a hacer. Al clasificar una regla, tienes que responder una pregunta que antes nadie se hacía: ¿esto es un estado o es un componente distinto? Esa pregunta es sorprendentemente productiva. Un menú abierto no es otro menú, es el mismo con un estado. Una tarjeta destacada probablemente tampoco es otra tarjeta. Muchísima duplicación en las hojas grandes venía de tratar estados como componentes.

SMACSS aportó además dos ideas que se han quedado. La primera es el prefijo por categoría —l- para layout, is- para estado— que hace que la categoría de una clase sea visible en el HTML sin abrir el CSS. La segunda, más profunda, es la profundidad de aplicabilidad: la medida de cuánto árbol abarca un selector. .menu li a span tiene una profundidad de aplicabilidad enorme y por tanto una probabilidad enorme de alcanzar algo que no querías. Reducirla es reducir la superficie de daño de cada regla.

Ese concepto no tenía mecanismo en 2011 y hoy sí: @scope con techo y suelo es exactamente “profundidad de aplicabilidad” convertida en una función del lenguaje, con la ventaja de que el motor la aplica en lugar de confiar en que tú la respetes.

Qué sobrevive intacto

De OOCSS sobrevive todo, y en dos sentidos distintos.

La separación de estructura y piel es hoy la base de cualquier sistema de tokens: la estructura la escribes una vez en el componente y la piel viene de custom properties que el componente lee. Cuando en el nivel 52 construyas un contrato de componente con custom properties, estarás escribiendo OOCSS con mejores herramientas.

La separación de contenedor y contenido es hoy alcanzable de verdad. Un componente con @container y unidades de contenedor se adapta a su hueco sin saber nada de la página. Eso no es una mejora incremental sobre lo que OOCSS proponía: es la primera vez que se puede cumplir.

De SMACSS sobrevive la taxonomía, transformada. Las cinco categorías se parecen mucho a un orden de capas en cascada, y no es casualidad: son el mismo problema. La diferencia es que SMACSS te pedía mantener el orden a mano en el fichero, y @layer lo declara:

@layer base, layout, componentes, estados, utilidades;

La categoría “Theme” es la que peor ha envejecido, y por una razón concreta: SMACSS proponía temas como conjuntos alternativos de reglas, lo que multiplica el CSS por el número de temas. Con custom properties, un tema es un conjunto de valores, no de reglas, y cambiar de tema es reasignar variables en un ancestro. La diferencia de tamaño y de complejidad es de un orden de magnitud.

Las metodologías buenas describen restricciones; las malas describen sintaxis

Aquí hay un criterio para juzgar cualquier metodología, de CSS o de lo que sea, y explica por qué OOCSS envejeció mejor que casi todo lo que vino después. OOCSS y la profundidad de aplicabilidad de SMACSS son afirmaciones sobre propiedades deseables del sistema: quiero que el número de clases crezca como la suma y no como el producto; quiero que la superficie que alcanza cada regla sea pequeña; quiero que un componente no dependa de su contexto. Son verificables, son independientes de la sintaxis y siguen siendo ciertas cuando cambian las herramientas. Por eso hoy las cumples con @container y @scope en lugar de con convenciones de nombres, y siguen valiendo. Compara eso con la parte de cualquier metodología que consiste en cómo escribir los guiones bajos: eso es sintaxis, no es una propiedad del sistema, y muere en cuanto llega una herramienta que hace el trabajo. La consecuencia práctica para ti es que cuando adoptes o descartes una forma de organizar CSS —y esto vale para Tailwind, para los módulos y para lo que venga después— la pregunta útil no es “¿me gusta cómo se ve?” sino “¿qué propiedad del sistema me garantiza esto, y cómo sabría que la he roto?”. Si no hay respuesta, lo que estás evaluando es un estilo de escritura disfrazado de arquitectura.