Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>W3C Color ToolkitNew to Visual Studio Code? Get it now.
W3C Color Toolkit

W3C Color Toolkit

HeavenSky

| (0) | Free
Color highlighting, hover information and format conversion with CSS Color 4/5/6 and HDR support.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

W3C Color Toolkit

Color highlighting, hover information and format conversion for VS Code, built on a single color engine with CSS Color 4 / 5 / 6 and CSS Color HDR support.

中文文档: README.zh-cn.md

Why one extension

Highlighting, hovers and conversion share the same document color index, so all three agree on the range, the color value, the alpha, the original color space and the resolution state of every expression. Nothing is re-parsed per feature.

Specification support

Level State
CSS Color 3 (legacy comma syntax) supported
CSS Color 4 (ED 2026-07-28) supported, including all 148 named colors, four hex lengths, none, static calc(), angle units and the 10 predefined color() spaces
CSS Color 5 (ED 2026-07-31) statically evaluable parts: color-mix() including the multi-color form, relative color syntax, alpha(), contrast-color(), device-cmyk() naive fallback, @color-profile fallback
CSS Color 6 (ED 2026-01-11) experimental, on by default, switchable through w3cColorToolkit.experimental: color-layers(), extended contrast-color(), wcag2 / wcag2(), tbd-fg / tbd-bg
CSS Color HDR 1 (ED 2026-07-28) experimental, on by default, same switch: ictcp(), jzazbz(), jzczhz(), color(rec2100-pq | rec2100-hlg | rec2100-linear), hdr-color()

Run W3C Color Toolkit: Manage → Show specification support matrix to see the matrix with your current switches applied.

Context dependent values are never faked

currentColor, the 19 system colors, the 23 deprecated system colors, light-dark(), unresolved var(), custom @color-profile without a fallback, and non-static alpha all resolve to a contextual state. They are never converted, and unless an explicit preview assumption applies they are not highlighted either: the hover explains what they depend on instead of showing a made-up swatch. Deprecated system colors also show their replacement keyword.

One exception is previewable without guessing: light-dark() picks a branch according to advanced.contextualPreview, whose default auto follows the current editor theme. The value is still labelled as an assumption in the hover, and switching theme re-renders it. Set the option to off to go back to no preview at all.

hdr-color() depends on the display HDR headroom, so it stays contextual even with the HDR switch on.

One field list for hover and highlighting

advanced.fields.enabled / advanced.fields.excluded are the single scope for both features, so there is no second place to configure what gets highlighted:

Group Applies to Examples
CSS formats hover row and highlighting hex, rgb, oklch, display-p3, rec2100-pq, css-color-name
CSS syntax, read only highlighting only color-mix, relative-color, light-dark, contrast-color, system-color, device-cmyk, transparent, current-color, color-layers, color-custom-profile, hdr-color
Non-CSS representations hover only hsv, cmyk
Extra information, not a color hover only preview, source, spec-level, diagnostics, alpha, gamut, contrast-on-white, contrast-on-black

Turning a CSS syntax off stops highlighting it; turning a format off also removes its hover row. Configure Color Fields shows the same grouping with the applicable scope on every entry. Syntax that the registry does not know about is always highlighted, so a new parser feature never silently loses its decoration.

Inline swatch and native color picker

The extension registers a DocumentColorProvider, so VS Code draws its inline swatch in front of the color and offers its color picker in the hover — including oklch(), lab(), color(), color-mix(), relative color syntax, the HDR spaces, and colors inside comments and strings, none of which VS Code's own providers cover. The swatch range is filtered by the same field list as highlighting.

The picker is anchored on the swatch (VS Code only produces a color hover where a color decoration exists), so "picker without swatch" is not possible; turning editor.colorDecorators off removes both.

Picking a color rewrites the value in the original format first (falling back to hex, rgb, hsl, oklch) and skips any format that cannot express the current alpha. Values that are not a plain color — context dependent ones (light-dark(), system colors, …) and read-only syntax (color-mix(), relative colors, contrast-color(), device-cmyk(), color-layers()) — get a read-only swatch: no presentation is offered, so one stray drag cannot flatten the expression into a literal. Use Convert Color to rewrite those on purpose.

advanced.colorPicker.mode:

Mode Behaviour
dedupe (default) In css / less / scss — the three languages where the built-in CSS provider contributes colors — probe the other providers once per document version and report only the ranges they left uncovered. Everywhere else report everything. No color ever gets two swatches.
all Report every supported syntax in every language, even where another provider already did.
off Provide nothing; VS Code falls back to its own providers.

Why the probe is needed: VS Code renders the results of all color providers without deduplicating by range, it drops the built-in default provider as soon as any extension returns an array (even an empty one), and vscode.executeDocumentColorProvider does not tell you which provider produced which color. Probing the ranges is the only way to guarantee exactly one swatch.

For the same reason the extension sets "editor.defaultColorDecorators": "never" through contributes.configurationDefaults: everything the built-in default provider recognises (hex, rgb(), hsl()) is a subset of what this extension reports, so switching it off removes overlap without losing coverage. The Settings UI shows it as "default value overridden by extension" and you can set it back to auto or always at any time.

Two limits worth knowing: VS Code renders at most editor.colorDecoratorsLimit (500 by default) swatches per editor — the extension truncates its report to that number and logs it — and editor.colorDecoratorsActivatedOn decides whether the picker opens on hover, on click, or both.

If you want a swatch that does not depend on VS Code's color feature at all, use the marker styles square-before / square-after: they draw a filled square with the extension's own decoration, in every language and every position, limited only by advanced.highlight.maxMatchesPerDocument.

Settings

Only 8 settings appear in the Settings UI:

Setting Default Purpose
w3cColorToolkit.enabled true Master switch
w3cColorToolkit.languages ["*"] Language filter; !id excludes, exclusions win
w3cColorToolkit.highlight underline Marker style: background, foreground, outline, underline, dot-before, dot-after, square-before, square-after; off disables highlighting
w3cColorToolkit.info true Hover information
w3cColorToolkit.convertSyntax legacy rgb() / hsl() output style
w3cColorToolkit.precision 5 Significant digits
w3cColorToolkit.experimental ["cssColor6", "cssColorHdr"] cssColor6, cssColorHdr; both on by default
w3cColorToolkit.advanced {} Incremental overrides for the 35 built-in options

Everything else is built in with a sensible default and overridden incrementally through w3cColorToolkit.advanced, using dotted keys:

{
  "w3cColorToolkit.advanced": {
    "output.hexCase": "upper",
    "highlight.maxMatchesPerDocument": 3000,
    "variables.includePaths": ["src/styles"]
  }
}

Rules:

  • keys not listed keep their built-in default; arrays and objects are replaced as a whole;
  • the 8 top-level settings must not appear here — they are ignored with a warning, which removes any ambiguity about precedence;
  • unknown keys and wrong types are ignored, out-of-range numbers are clamped, and every case is logged instead of throwing;
  • User / Workspace / Folder scopes are merged key by key by the extension, because VS Code replaces object settings wholesale;
  • Manage → Show effective configuration prints the merged result with the origin of each key.

Commands

Five entries appear in the Command Palette:

Command What it does
Convert Color Flat Quick Pick grouped by category
Copy Color As Same picker, writes to the clipboard
Enable Features Multi-select Quick Pick for the feature switches
Configure Color Fields Multi-select Quick Pick for the shared hover + highlight field list
Manage Migration, effective configuration, support matrix, rescan, clear cache, log

The 24 direct w3cColorToolkit.convertTo.* commands and the 7 Manage actions are hidden from the Command Palette but are fully bindable: they appear in the Keyboard Shortcuts editor. No default keybindings are shipped, to avoid conflicting with your existing bindings:

// keybindings.json
[
  { "key": "ctrl+alt+h", "command": "w3cColorToolkit.convertTo.hex", "when": "editorTextFocus" },
  { "key": "ctrl+alt+o", "command": "w3cColorToolkit.convertTo.oklch", "when": "editorTextFocus" },
  {
    "key": "ctrl+alt+p",
    "command": "w3cColorToolkit.convertTo.rec2100Pq",
    "when": "editorTextFocus && w3cColorToolkit.hdrEnabled"
  }
]

Migrating from the original extensions

Manage → Migrate legacy plug-in settings reads explicit color-highlight.* and colorInfo.* values, shows a preview, and only writes after you confirm. It never modifies the old settings, is idempotent, and writes each scope back to that same scope.

Old command New command
extension.changeColorFormat.commands w3cColorToolkit.convert
extension.changeColorFormat.hexSmartConvert w3cColorToolkit.convertTo.hex (hidden, bindable)
extension.changeColorFormat.hslSmartConvert w3cColorToolkit.convertTo.hsl (hidden, bindable)
extension.changeColorFormat.rgbSmartConvert w3cColorToolkit.convertTo.rgb (hidden, bindable)
extension.colorHighlight w3cColorToolkit.toggleFeatures

color-highlight.enable and color-highlight.markerType collapse into the single w3cColorToolkit.highlight setting. The four colorInfo preview field variants collapse into the preview field plus info.previewSize and info.previewShape.

Running alongside the originals

If the original extensions are installed, this extension warns once per workspace that highlighting, hovers or commands may be duplicated. It never disables, uninstalls or modifies them, and it does not register their command ids. Set advanced.coexistence.notify to false to silence the notice.

Gamut and HDR handling

  • sRGB output uses the CSS-specified gamut mapping by default, not per-channel clipping (advanced.output.gamutMapping can switch to clip or none).
  • Wide gamut colors are mapped for the preview swatch only; the hover keeps showing the original value and the gamut status.
  • HDR colors are tone mapped for the preview (advanced.highlight.hdrToneMapping) and flagged as tone mapped in the hover.
  • Conversion tells you before it happens whether the value will be gamut mapped, whether alpha will be dropped, and whether none components will be lost. The default policy is to refuse rather than silently lose information.

Known limitations

  • Scanning very large documents is slower than the target performance budget; see the plan document for the pending optimisation. advanced.scan.maxDocumentSizeKb and advanced.highlight.maxMatchesPerDocument bound the work.
  • CSS Color 6 and CSS Color HDR are drafts; values and syntax may change.
  • Untrusted workspaces resolve variables only within the current document.
  • No remote ICC profile download; device-cmyk() uses the naive fallback and is marked approximate.

Localisation

English and Simplified Chinese. Other locales fall back to English.

License

MIT. See NOTICE.md for how the three reference extensions were used.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft