Zudo Token Panel

Type to search...

to open search from anywhere

Highlight Token Users

このページはまだ翻訳されていません。原文のまま表示しています。

Inspect which DOM elements consume a token by toggling its eye icon

The Highlight Token Users feature lets you visually inspect which DOM elements in the host page are consuming any given design token. Toggle the eye icon next to a token row and every matching element gets an outline; open the gear settings to customise each highlight slot’s color and outline width.

Overview

Eye icon — toggle button next to each token row. Clicking it activates an inspection highlight for that token: every element whose computed style is influenced by that CSS custom property receives a colored outline overlay in the host page. Clicking the icon a second time removes the highlight.

Gear icon — opens the settings popover in the panel header. From there you can change the color and outline width of each of the 10 available highlight slots, and reset all slot colors to the vivid default palette.

Visual outcome — active highlights appear as colored outlines overlaid on top of the host page’s content. The overlays sit at z-index: 49 (below the panel at z-index: 50, but above typical host content). Up to 10 tokens can be highlighted at the same time.

📝 Note

Up to 10 simultaneous highlights are supported. Click the eye icon again to disable a highlight.

Quick start

  1. Open the panel.
  2. Navigate to the tab containing the token you want to inspect.
  3. Click the eye icon next to a token row.
  4. Observe the colored outlines that appear on elements in the host page.
  5. Click the eye icon again to remove the highlight.

Reservation-sheet semantics

Highlights are allocated from a fixed 10-slot “reservation sheet”. Each slot has an index (0–9), a color, and an outline width. The lowest available index is always claimed first; releasing a slot in the middle leaves higher-index slots at their current positions.

Slot allocation rules:

  1. When you activate a token, the highlight system finds the lowest free slot index and claims it.
  2. That slot’s color and outline width are applied to the token’s outlines.
  3. When you deactivate a token, its slot is freed; all other slots stay put.
  4. The next activation claims the lowest free slot again (which may be a previously-freed lower index).

Worked example:

  • Toggle token A → claims slot 0.
  • Toggle token B → claims slot 1.
  • Toggle token C → claims slot 2.
  • Disable A → slot 0 is freed. B stays at slot 1, C stays at slot 2.
  • Toggle token D → claims slot 0 (the lowest free index).

Result: D is at slot 0, B is at slot 1, C is at slot 2.

Settings popover

Click the gear icon in the panel header to open the highlight settings popover. It lists all 10 slots in a 4-column grid:

| Column | What it shows | | --- | --- | | Index | Slot number (0–9) | | Ring swatch | A ring whose border is a live preview of the slot’s current outline color | | Token label | The CSS variable name of the token currently using this slot, or “available” if the slot is free | | Slider + readout | Outline width control from 1–10 px; the readout shows the current value (e.g. 4px) |

Changing the color: click the ring swatch to open a color picker for that slot. The outline on any currently-highlighted element updates live.

Changing the width: drag the slider to change the outline width. The ring swatch’s border and the outline on any highlighted element update live.

Reset to defaults

The Reset to defaults button in the settings popover footer restores all 10 slot colors to the vivid built-in default palette (red, pink, skyblue, and so on).

💡 Tip

Reset to defaults only restores slot colors and widths. It does NOT clear the active inspection set — any tokens you currently have highlighted stay highlighted, with their slots now showing the default colors.

Disable all highlights

The Disable all highlights button in the settings popover footer clears the entire active inspection set in one click — all outline overlays are removed immediately. Slot colors and outline widths are preserved; only the active map is cleared. There is no confirmation dialog. If you change your mind, you can re-enable individual tokens by clicking their eye icons again.

Persistence model

The feature uses two distinct storage layers:

ℹ️ Info

Slot configuration (colors + widths) — stored in localStorage. Persists across browser sessions. These are your personalised settings and should survive a page reload or a new browser tab.

Active inspection set (which tokens are highlighted) — stored in sessionStorage. Cleared on a full page reload (Ctrl+Shift+R / Cmd+Shift+R). Each debug session starts fresh with no outlines active.

This split means you can set up your preferred slot colors once and keep them permanently, while the list of things you are currently inspecting resets automatically when you reload — preventing leftover debug state from a previous session from polluting a fresh page load.

How it works

When you click the eye icon next to a token, the panel runs a sentinel-substitution probe:

  1. The panel temporarily writes a unique marker value (the “sentinel”) to the token’s CSS custom property — overriding both :root and every other element where a stylesheet rule defines that token directly. This ensures cascade-scoped overrides (such as [data-theme="dark"] blocks) are covered, not just :root.
  2. A style recalculation is forced synchronously.
  3. Every element in the page body — along with their ::before and ::after pseudo-elements — is asked for its computed CSS values. Elements whose computed value contains the sentinel are consumers of the token.
  4. The original token value is restored immediately, in the same browser tick. There is no visible flicker.

Tokens that pass through CSS functions — if a token’s value flows through calc(), min(), max(), clamp(), color-mix(), or a similar CSS function, the single-sentinel equality check is unreliable (because the function may transform the sentinel beyond recognition). In this case the panel automatically falls back to a two-probe strategy: it applies two different sentinel values in sequence and marks elements whose computed properties differ between the two probes. This slower fallback catches transform-wrapped consumers that the fast equality path would miss.

Token type drives property inspection — the panel needs to know which CSS properties to interrogate. The type hint is supplied by the panel manifest via the token’s type.kind field. Supported kinds are color, length, number, text, easing, time, cursor, content, and mask-image. For tokens the manifest does not know about, the type is auto-detected from the token’s resolved value on documentElement. The type determines the list of computed longhand and compound properties that are compared against the sentinel.

  • color — inspects color properties (color, background-color, border-color, etc.) and compound properties like box-shadow.
  • length — inspects dimension properties (padding, margin, width, font-size, etc.) and compound properties like transform.
  • number — inspects unitless numeric properties (opacity, line-height, z-index, etc.).
  • text — inspects custom-ident properties (font-family, animation-name, transition-property, will-change).
  • easing — inspects timing-function properties (transition-timing-function, animation-timing-function).
  • time — inspects duration and delay properties (transition-duration, transition-delay, animation-duration, animation-delay). Token values like 0.3s or 150ms are automatically classified as this kind.

The three new string-property kinds added in #285 have important probe characteristics:

  • cursor — uses bare cursor-keyword sentinels (crosshair / move). Chrome’s getComputedStyle drops the url() part from cursor values (the fallback keyword is also discarded when the image cannot load, returning auto), so url()-based cursor sentinels are not viable. Keyword sentinels round-trip correctly. Trade-off: elements with a literal cursor: crosshair or cursor: move (without a CSS variable) will be reported as false-positives. Auto-detect does NOT route to cursor; you must supply kind: 'cursor' explicitly in the manifest.

  • content — uses double-quoted string sentinels. Quoted-string values survive Chrome computed-style serialization intact. Auto-detect routes to content when the token’s resolved value matches the pattern "..." (a quoted string on :root).

  • mask-image — uses url() sentinels with a high-entropy needle. Chrome preserves url() in getComputedStyle for mask-image (unlike cursor). Chrome may normalise single to double quotes inside url(); the needle is a substring of the data URI that is quote-style-agnostic. Auto-detect for url() resolved values is ambiguous — a url() value could be cursor, mask-image, or background-image. Auto-detect falls through to text with a warning; supply kind: 'mask-image' explicitly in the manifest to disambiguate.

⚠️ Migrating from the previous algorithm

If you were relying on the previous algorithm’s alias-chain expansion depth limit (5 hops), that concept no longer applies. The new algorithm uses the browser’s own cascade resolution to detect consumers, which has no artificial hop limit. Consumers reachable through any depth of var() alias chain are now detected automatically.

Documented limitations

Cross-origin stylesheets — the browser blocks reading CSS rules from stylesheets served from a different origin without CORS headers. Consumers defined exclusively in such sheets won’t be detected. A warning is emitted to the browser console when a cross-origin sheet is skipped.

adoptedStyleSheets — constructed stylesheets attached to the document via the adoptedStyleSheets API are not part of document.styleSheets and are not inspected by the algorithm.

Shadow DOM — the DOM walk does not pierce shadow roots. Consumers inside Web Components (whether open or closed shadow roots) will not be detected.

Pseudo-elements beyond ::before and ::after::placeholder, ::marker, ::selection, ::backdrop, and other pseudo-elements are not inspected.

Browser “minimum font-size” preference — if the user has configured a minimum font-size in their browser above the algorithm’s length sentinel (typically around 7.13px), font-size consumers may be missed by the fast equality probe. The two-probe differential fallback usually catches these.

CSS-in-JS frameworks — frameworks that inject styles via adoptedStyleSheets or shadow DOM are subject to the limitations above. Frameworks that inject plain <style> tags are fully supported.

Very-high host z-index — overlays sit at z-index: 49. Modals or other elements at very high z-index values (e.g. z-index: 99999) will visually cover the outlines. The panel itself sits at z-index: 50, so overlays appear below the panel but above typical page content.

No auto-update for dynamically inserted elements — the DOM walk runs once when you click the eye icon, against the elements present at that moment. If a new element is inserted into the DOM after the highlight is activated, it will not automatically receive an overlay. Click the eye icon again to re-run the probe.

Revision History