Saltar al contenido

no-arbitrary-value ​

Regla de oxlint que reporta valores arbitrarios de Tailwind CSS como w-[200px] o bg-[#ff0000], para que salgan de tu theme; una allow list cubre excepciones.

De un vistazo ​

AutofixSugerencias en el editorDesign systemOpciones
NoNoOpcional — se usa si hay entryPointallow, allowVariables, entryPoint

Qué hace esta regla ​

Marca cualquier utility de Tailwind que use un arbitrary value — la escotilla — para forzar al equipo a usar un token del design system o extender el theme en vez de literales sueltos. Cualquier cosa que el parser reconozca como arbitrary value califica: dimensiones (w-[200px], text-[14px]), colores (bg-[#ff0000]), expresiones calc (p-[calc(1rem+2px)]), gradients, y lo mismo dentro de variants (hover:w-[200px]) o con el modificador ! (!w-[200px], w-[200px]!).

Las dos formas cuentan. bg-(--brand) es el azúcar de Tailwind v4 para bg-[var(--brand)] — el mismo arbitrary value, escrito de dos maneras — y antes solo se reportaba la forma con corchetes. Eso convertía a enforce-consistent-variable-syntax en un lavadero: con su ajuste por defecto shorthand, su autofix reescribía la forma reportada en la no reportada y la violación desaparecía sin que el código cambiara en el fondo.

DS-opcional — no necesitas entryPoint: saber si una clase es un arbitrary value es un chequeo sintáctico, barato en repos grandes. Con uno configurado, el reporte además nombra el arreglo — los pasos y tokens más cercanos de tu theme, con sus valores, y el archivo donde agregar un token:

text
"w-[203px]" uses an arbitrary value. Closest in your theme: w-50.5 (202px) or w-51 (204px).
If none fits, add a token to src/styles.css.

Un paso o token exacto se ofrece solo (h-[26px] → h-6.5 (26px)); si no, el más cercano por debajo y por arriba. Un valor que no es una longitud (un color, un calc()) recibe solo el archivo. El design system se carga en la primera violación, nunca para un archivo limpio; allowVariables: 'runtime' también lo usa, para saber qué variables CSS define tu stylesheet. No hay autofix: reemplazar un arbitrary value por un token requiere criterio humano, así que la regla solo reporta.

Los variants arbitrarios ([&>svg]:w-4) no son values arbitrarios y la regla los deja tranquilos. Mira el lado del valor de la utility, no el prefijo de selector.

Opciones ​

allow ​

string[], default [].

Una lista de prefijos de utilities donde los arbitrary values están tolerados. El match es un String.prototype.startsWith literal contra la forma bare de la utility (después de sacar ! y los variants), así que entradas como "grid-cols-" permiten grid-cols-[18rem_1fr] sin habilitar grid-rows-[...]. Candidatos típicos: container queries (@container), grid templates (grid-cols-, grid-rows-), y transforms genuinamente a medida (bg-[url().

jsonc
{
  "tailwindcss/no-arbitrary-value": ["error", {
    "allow": ["grid-cols-", "grid-rows-", "bg-[url("]
  }]
}

Tip: empieza con [] para ver dónde tu codebase realmente necesita escapes, después promueve los legítimos a allow en vez de desactivar la regla entera.

allowVariables ​

'none' | 'runtime' | 'all', default 'none'.

Qué hacer con un valor que no es más que una variable CSS — w-(--sidebar-width), h-[var(--radix-select-trigger-height)], text-(length:--size), con o sin fallback o modificador de opacidad:

  • 'none' las reporta, como cualquier arbitrary value.
  • 'runtime' permite las variables que ningún CSS de tu design system define — las que JavaScript o un style inline definen en runtime, como las --radix-* de Radix o el --sidebar-width de un sidebar, para las que no existe un token. Una variable que define tu stylesheet (--primary) se sigue reportando: existe una utilidad con nombre para ella (mira prefer-theme-tokens). Este modo lee el design system; sin entryPoint no se puede probar que una variable no esté definida, así que las referencias se reportan.
  • 'all' permite toda referencia pura a una variable.

Un valor que hace algo más que leer una variable — w-[calc(var(--x)*2)] — es un arbitrary value en todos los modos.

jsonc
{ "tailwindcss/no-arbitrary-value": ["warn", { "allowVariables": "runtime" }] }

entryPoint ​

string, opcional. Override por regla de settings.tailwindcss.entryPoint, que solo lee allowVariables: 'runtime'.

Ejemplos ​

✗ Incorrecto ​

tsx
// Dimensión one-off en vez de un token de spacing
<div className="w-[200px] p-[10px]" />

// Literal hex en vez de un color del theme
<div className="bg-[#ff0000] text-white" />

// El variant no cambia el veredicto
<div className="hover:w-[200px]" />

// El modificador `!` tampoco
<div className="!w-[200px]" />

// El shorthand de v4 es el mismo arbitrary value
<div className="bg-(--brand) border-(length:--stroke)" />

✓ Correcto ​

tsx
// Usa tokens de spacing
<div className="w-64 p-2.5" />

// Usa un color de theme declarado en @theme
<div className="bg-brand text-white" />

// Los variants arbitrarios están bien — apuntan a selectores, no a valores
<div className="[&>svg]:w-4" />

// Permitido vía `allow: ["grid-cols-"]`
// options: { "allow": ["grid-cols-"] }
<div className="grid grid-cols-[18rem_1fr]" />

Interacciones con otras reglas ​

  • no-hardcoded-colors: un subset estricto enfocado en utilities de color (bg-[#ff0], text-[rgb(...)]). Activa esa si quieres el mensaje granular específico de colores; activa ambas para enforcement por capas. Las dos van a disparar sobre la misma clase, lo cual suele ser deseable durante una migración.
  • no-unnecessary-arbitrary-value: esta regla prohibe los arbitrary values directamente; no-unnecessary-arbitrary-value es más suave — solo marca arbitraries que tienen equivalente nombrado exacto (w-[100%] → w-full). Pueden coexistir: la suave autofixea los casos triviales y esta atrapa lo que queda.
  • prefer-theme-tokens: misma intención, pero DS-dependiente. prefer-theme-tokens consulta tu @theme y sugiere el token que coincide. Combínalas: esta regla es tu freno de mano cuando todavía no existe el token.
  • enforce-consistent-variable-syntax: convierte entre bg-[var(--x)] y bg-(--x). Como las dos formas se reportan aquí, correrla — en cualquier dirección — no puede sacar una clase del alcance de esta regla.

Cuándo desactivarla ​

  • Prototipos / branches de spike donde la velocidad le gana a la disciplina. Reactívala antes de integrar.
  • Archivos que genuinamente necesitan un arbitrary value (landing pages one-off, shims de CSS-in-JS dinámico). Prefiere allow con una lista corta de prefijos, o desactiva por línea con // oxlint-disable-next-line tailwindcss/no-arbitrary-value.
  • Librerías que publican utilities de Tailwind que el consumidor re-skinea: a veces la forma arbitraria es el contrato más limpio. Documenta la decisión y desactiva la regla en ese paquete.

Released under the MIT License.