DEV Community

Franklin
Franklin

Posted on

Notas desde el pase: qué pasa cuando el estado se esconde dentro de un token

Also available in Inglés

La afirmación a prueba

La última entrega de esta serie sostuvo que un sistema sin exclusiones declaradas terminará recibiendo la petición de hacerlo todo, porque nada dentro de él tiene argumentos para negarse. El ejemplo fue una sola línea: --is-modal-open junto a --spacing-md. Sintácticamente idénticas. Semánticamente sin ninguna relación.

Esa es una afirmación sobre los sistemas en general. Esto es lo que parece dentro de un archivo que realmente existe, con un mecanismo que depende en la práctica de que el límite se mantenga.

El artefacto

quell-base.css declara una capa ghost_tokens. Su propósito, expresado de forma simple en el comentario de cabecera del propio archivo, es proveer valores de respaldo (fallback) completamente resueltos antes del pintado (paint) para cada token que consume la base. No es decoración: es un cortafuegos contra el FOUC (Flash of Unstyled Content). Las llamadas var() descendientes nunca se quedan con una cadena vacía, incluso si una hoja de estilos de un tema aún no se ha cargado.

Aquí hay un fragmento real:

@layer ghost_tokens {

  :root {

    --color-accent:          #0057cc;  /* WCAG AA on white; override freely */
    --color-accent-hover:    #003fa3;
    --color-accent-subtle:   #dbeafe;
    --color-surface:         #ffffff;
    --color-surface-subtle:  var(--color-neutral-50);

  }

}
Enter fullscreen mode Exit fullscreen mode

Ahora imagina que el commit que describió el último artículo aterriza aquí:

@layer ghost_tokens {

  :root {

    --color-accent:          #0057cc;
    --color-accent-hover:    #003fa3;
    --color-accent-subtle:   #dbeafe;
    --is-modal-open:         0;   /* tracks modal visibility */

  }

}
Enter fullscreen mode Exit fullscreen mode

La sintaxis no pone objeciones. El navegador procesa --is-modal-open con la misma facilidad que --color-accent. Nada en la capa @layer ghost_tokens lo rechaza. Ese es el punto central del último artículo, ahora ubicado dentro de un archivo con una tarea documentada que proteger.

Ya existe otro límite en el archivo: la convención de nomenclatura de tokens define el vocabulario esperado como font, color, space, size, radius, border, shadow y motion.

--color-accent pertenece a ese vocabulario.

--is-modal-open no.

El navegador no puede imponer esa distinción. La arquitectura tiene que hacerlo.

Qué se rompe realmente

ghost_tokens no solo contiene valores: hace una promesa específica sobre cuándo están disponibles esos valores. Se resuelven como respaldos de la base antes del pintado, antes de que exista necesariamente una hoja de estilos de tema. Para un color, esa promesa es inofensiva. --color-accent no cambia de significado según el estado de la aplicación (application state); el azul resuelto temprano sigue siendo el azul resuelto más tarde.

--is-modal-open es diferente. En el momento en que vive en esta capa, se trata como si el estado de la aplicación fuera otro valor base. El valor de respaldo ya no es un simple respaldo. Es una afirmación: la página ahora tiene una opinión sobre el estado del modal antes de que la aplicación haya establecido ese estado.

Ese es el cortafuegos contra el FOUC que la capa fue construida para proporcionar, al que ahora se le pide proteger una suposición del estado de la aplicación en lugar de un valor base.

El archivo también documenta tres formas en que los autores descendientes pueden tomar el control del sistema, en orden de poder ascendente: volver a declarar una propiedad personalizada (custom property) en un :root sin capa, añadir contenido a una capa existente o escribir una regla sin capa directamente. La primera es la sobrescritura de tokens documentada; las otras operan a nivel de capas y de hojas de estilo.

Todos estos mecanismos asumen que el contrato subyacente permanece intacto: los tokens son valores que los autores descendientes son libres de reemplazar. Un autor de temas que sobrescribe --color-accent cambia lo que significa el azul. Un autor de temas que sobrescribe --is-modal-open no está personalizando un valor de diseño. Está afirmando un hecho sobre el estado de la aplicación mediante un mecanismo que fue diseñado para proporcionar valores base.

El momento en que realmente divergir

Redúcelo a dos declaraciones, la misma capa, la misma sintaxis:

--color-accent:   #0057cc;  /* a value */
--is-modal-open:  0;        /* application state */
Enter fullscreen mode Exit fullscreen mode

En el momento del análisis (parse time), el navegador no puede distinguirlos. Nada en el algoritmo de la cascada diferencia un valor de diseño de un valor de estado de la aplicación. Ambos son propiedades personalizadas (custom properties). Ambos son declaraciones válidas.

Esa distinción debe decidirse antes de que la capa exista, por quienquiera que escriba la regla en la que se permite cualquiera de los dos tokens.

El navegador nunca lo hará por ti.

Lo que esto realmente demuestra

ghost_tokens no se rompe por --is-modal-open. Hace exactamente aquello para lo que fue construido: resolver la propiedad personalizada como parte de la base antes del pintado. El problema es arquitectónico: el contrato de la capa consiste en proporcionar valores de respaldo base, mientras que el estado de la aplicación es un hecho establecido por la aplicación.

CSS puede responder al estado. quell hace esto en otras partes del sistema: su capa de formularios (forms) proporciona valores por defecto accesibles para estados como disabled, readonly e invalid.

Por lo tanto, el límite no es que CSS nunca debe contener estado.

El límite es más estrecho y más útil:

Una capa de tokens base no debe convertirse en el almacén de estado de la aplicación solo porque CSS otorgue la misma sintaxis a ambos tipos de información.

Eso es lo que expone el ejemplo de --is-modal-open.

El límite del último artículo no es una preferencia de estilo. Es la diferencia entre una capa que cumple su promesa y otra que ha sido redirigida silenciosamente para cumplir una promesa para la que nunca fue diseñada.

La mejor arquitectura de CSS comienza por decidir qué no debe hacer nunca CSS

Top comments (0)