Skip to content

design-no-raw-color

Field Value
Tool ESLint
Enable via design() factory
Rule ID house-rules/design-no-raw-color
Type suggestion
Autofix no
Source packages/rules/src/design-no-raw-color.mjs
Docs packages/rules/docs/design-no-raw-color.md

Raw hex, rgb(), hsl(), etc. in CSS.

Disallow raw colours in CSS declaration values outside the design-token files.

  • rawColor: Raw colour “{{color}}”. Use a design token.
  • rawColorNearest: Raw colour “{{color}}”. Use a design token; the nearest is var({{token}}).
  • rawColorExact: Raw colour “{{color}}” is the value of var({{token}}). Use the token.
[
{
"tokenFiles": [],
"allowValues": [
"transparent",
"currentcolor",
"inherit",
"initial",
"unset"
],
"allowIn": [],
"suggestNearest": true
}
]

From packages/rules/docs/design-no-raw-color.md.

Rule ID: house-rules/design-no-raw-color

The rule runs on the @eslint/css language. It reports a colour written out in a CSS declaration value instead of taken from a design token. Use the @house-rules/rules/design factory to enable it.

.drop[data-over] {
background: var(--paper); /* passes */
background: #e8f4f5; /* reported: nearest token is var(--paper) */
}
.bundle {
--bundle-bg: #fff8ed; /* reported: a custom property outside the token files */
}
  • a hex colour with 3, 4, 6 or 8 digits
  • a call to rgb(), rgba(), hsl(), hsla(), hwb(), lab(), lch(), oklab(), oklch() or color()
  • a named colour such as red or rebeccapurple, plus transparent and currentcolor

The rule checks every declaration value, including custom-property values such as --x: #fff and the fallback in var(--x, #fff).

It skips:

  • text inside strings and url(), so url(#fff) and content: "red" pass
  • a colour function that uses var(), such as rgb(var(--ink-rgb) / 0.5), because it builds on a token
  • color-mix() itself; raw colours inside it are still reported
  • named colours in properties that take author-chosen names, such as animation-name, font-family, grid-area, transition-property and counter-reset
  • custom-property definitions inside the token files

A token file’s ordinary declarations are still checked. In Hosti’s hosti.css, --paper: #ecf2f3 inside :root passes, but ::selection { background: #bfe0e3; } in the same file is reported.

  • Raw colour "#e8f4f5". Use a design token; the nearest is var(--paper).
  • Raw colour "#2b3133" is the value of var(--ink). Use the token. when the colour equals a token, alpha included.
  • Raw colour "#fff". Use a design token. when there is no suggestion.

The nearest token is picked by distance in the OKLab colour space, which tracks how different two colours look. Alpha is ignored for the distance. Token values may be hex, named colours, rgb(), hsl(), hwb(), oklab() or oklch(). A token that aliases another, such as --text: var(--ink), takes that token’s colour. lab(), lch() and color() values get no suggestion.

type Options = [
{
tokenFiles?: string[]; // default: []
allowValues?: string[]; // default: ["transparent", "currentcolor", "inherit", "initial", "unset"]
allowIn?: string[]; // default: []
suggestNearest?: boolean; // default: true
},
];
  • tokenFiles: CSS files that define the tokens, relative to ESLint’s working directory. design() fills this from its own tokenFiles. A missing file stops the lint with an error.
  • allowValues: colour values that never count as raw. Case and whitespace are ignored, so "#FFF" allows #fff and "rgba(0,0,0,0)" allows rgba(0, 0, 0, 0). Setting it replaces the default list.
  • allowIn: file globs, relative to ESLint’s working directory, where the rule does nothing. It supports **, *, ?, [...] and {a,b}. As in minimatch, a wildcard does not match a name that starts with ., so **/*.css skips .storybook/x.css; write the dot, as in .storybook/**, to match one.
  • suggestNearest: set false to drop the token hint from messages.

Every --name: value declaration in a token file counts, whatever the selector or at-rule around it. When a name is defined more than once, the first definition supplies the colour for suggestions. Later ones are usually theme overrides. Files are read once per process and read again only when their modification time or size changes.

  • The rule has no autofix. A near colour is a hint; the token may not be the right one.
  • System colours such as Canvas are not reported.
  • A named colour used as a custom identifier in an unlisted property, or in a custom-property value, is reported.

All rules · ESLint rules