afv-library/skills/uplifting-components-to-slds2/references/non-color-hooks-decision-guide.md
Kenam e850eb1a25
W-21831072: Add skill: uplifting-components-to-slds2 (#152)
Add skill: uplifting components to slds2

Made-with: Cursor
2026-03-31 21:03:28 +05:30

13 KiB
Raw Blame History

Non-Color Styling Hooks Guide

Reference for replacing hardcoded spacing, sizing, typography, border, radius, and shadow values with SLDS 2 styling hooks. These hooks use numbered scales with straightforward mappings — unlike color hooks, they rarely require context-based decisions.

Pattern for all replacements:

property: var(--slds-g-[hook], originalValue);

Important: Only replace values that match a hook's actual rendered value. If a hardcoded value falls between two hooks (e.g., 3px when hooks offer 4px and 8px), leave it unchanged. The linter auto-fix handles exact matches; manual fixes should only apply when there's a clear correspondence. Forcing a non-matching value into the nearest hook changes the component's visual appearance.


Critical Rule: Never Invent Hooks

Only use hooks that actually exist in SLDS 2. The linter is the source of truth for which hooks exist and what values they map to. Do not:

  • Guess hook names — Hooks like --slds-g-spacing-medium, --slds-g-font-weight-bold, --slds-g-radius-large do NOT exist. SLDS 2 uses numbered scales only (e.g., --slds-g-spacing-4, --slds-g-font-weight-7).
  • Extrapolate patterns — If you see --slds-g-spacing-1 through --slds-g-spacing-12, do not assume --slds-g-spacing-13 exists. Each category has a fixed scale defined by the design system.
  • Invent semantic names — There are no --slds-g-spacing-page, --slds-g-font-heading, or --slds-g-shadow-modal hooks. Hooks are numeric, not semantic.

When unsure whether a hook exists: Run the linter (npx @salesforce-ux/slds-linter@latest lint --fix .). It will suggest valid hooks for flagged values. If the linter doesn't flag a value or doesn't suggest a hook, leave it hardcoded.


Table of Contents


Spacing Hooks

Prefix: --slds-g-spacing-* Use for: margin, padding, gap, row-gap, column-gap Do NOT use for: width, height, or other dimension properties (use sizing hooks)

Scale range: 112. There is no --slds-g-spacing-13 or higher. If a value exceeds 5rem/80px, leave it hardcoded.

Density-Aware Spacing

For components that adapt between comfy and compact display density, use density-aware variants:

Hook Pattern Applies To
--slds-g-spacing-var-* All sides (margin, padding)
--slds-g-spacing-var-block-* Vertical only (top/bottom)
--slds-g-spacing-var-inline-* Horizontal only (left/right)

Use density-aware hooks for data tables, forms, cards, tabs, and navigation components that need to respond to the user's density preference.

Examples

/* Before */
.card-body { padding: 1rem; }
.list-item { margin-bottom: 0.5rem; }
.grid { gap: 1.5rem; }

/* After — hook names come from the linter, not guesswork */
.card-body { padding: var(--slds-g-spacing-4, 1rem); }
.list-item { margin-bottom: var(--slds-g-spacing-2, 0.5rem); }
.grid { gap: var(--slds-g-spacing-5, 1.5rem); }

/* Multi-value shorthand */
.button { padding: var(--slds-g-spacing-2, 0.5rem) var(--slds-g-spacing-4, 1rem); }

Sizing Hooks

Prefix: --slds-g-sizing-* Use for: width, height, min-width, max-width, min-height, max-height Do NOT use for: margin, padding, gap (use spacing hooks) Scale range: 116. There is no --slds-g-sizing-17 or higher.

Examples

/* Before */
.icon { width: 32px; height: 32px; }

/* After */
.icon { width: var(--slds-g-sizing-9, 32px); height: var(--slds-g-sizing-9, 32px); }

Typography Hooks

Font Scale

Prefix: --slds-g-font-scale-* (and --slds-g-font-size-base for 13px) Use for: font-size Scale range: neg-4 through 10, plus base (0.8125rem/13px). Negative values (neg-1 to neg-4) are for small/caption text. There is no --slds-g-font-scale-11 or higher.

Density-aware variant: --slds-g-font-scale-var-* (also 110) — adapts between comfy and compact.

Font Weight

Prefix: --slds-g-font-weight-* Use for: font-weight Scale range: 17. Maps to CSS weight values 100700. There is no --slds-g-font-weight-8 or higher.

Weight pairing guidance in SLDS 2:

  • Display text (large scale) → lighter weight
  • Titles/headings → regular weight
  • Buttons/small body titles → semi-bold weight
  • Inline emphasis within body → bold weight (sparingly)

Line Height

Prefix: --slds-g-font-lineheight-* Use for: line-height Scale range: 16. Values range from 1 to 2. There is no --slds-g-font-lineheight-7 or higher.

Font Family

Hook Use Case
--slds-g-font-family Default font family
--slds-g-font-family-base Base font family
--slds-g-font-family-monospace Code snippets

Content Width

Prefix: --slds-g-sizing-content-* and --slds-g-sizing-heading-* Use for: max-width on text containers (uses ch units for readable line lengths) Scale range: content 13, heading 13.

Typography Examples

/* Before */
.title { font-size: 18px; font-weight: bold; line-height: 1.25; }
.body { font-size: 14px; font-weight: normal; line-height: 1.5; }

/* After — let the linter confirm the correct scale numbers */
.title {
  font-size: var(--slds-g-font-scale-4, 18px);
  font-weight: var(--slds-g-font-weight-4, bold);
  line-height: var(--slds-g-font-lineheight-2, 1.25);
}
.body {
  font-size: var(--slds-g-font-scale-1, 14px);
  font-weight: var(--slds-g-font-weight-4, normal);
  line-height: var(--slds-g-font-lineheight-4, 1.5);
}

Border Width Hooks

Prefix: --slds-g-sizing-border-* Use for: border-width, border, border-top, etc. (the width component) Scale range: 14. Maps to 1px4px. There is no --slds-g-sizing-border-5 or higher.

Border widths are NOT density-aware — they stay constant regardless of comfy/compact settings.

SLDS 2 philosophy: Use borders sparingly. Prefer spacing or shadows for visual separation. Use borders purposefully for structure, interactivity indication, and state communication.

Examples

/* Before */
.input { border: 1px solid #ccc; }

/* After */
.input { border: var(--slds-g-sizing-border-1, 1px) solid var(--slds-g-color-border-2, #ccc); }

Border Radius Hooks

Prefix: --slds-g-radius-border-* Use for: border-radius Scale range: 14 plus special values circle and pill. There is no --slds-g-radius-border-5 or higher.

Choose radius by component type, not by matching px values. The hook resolves to the design-system value; the original value is preserved as fallback only.

Hook Components
--slds-g-radius-border-1 Badges, checkboxes
--slds-g-radius-border-2 Text inputs, comboboxes, text areas, tooltips
--slds-g-radius-border-3 Menus, popovers
--slds-g-radius-border-4 Cards, modals, docked composers
--slds-g-radius-border-circle Buttons, button icons, avatars, radios, pills
--slds-g-radius-border-pill Pill-shaped elements

Border radius hooks are NOT density-aware.

Examples

/* Before */
.card { border-radius: 8px; }
.button { border-radius: 50%; }

/* After — chosen by component type, not px value */
.card { border-radius: var(--slds-g-radius-border-4, 8px); }
.button { border-radius: var(--slds-g-radius-border-circle, 50%); }

Shadow Hooks

Prefix: --slds-g-shadow-* Use for: box-shadow Scale range: 16. Directional variants (-block-start-*, -block-end-*, -inline-start-*, -inline-end-*) use range 14. Focus variants (-outline-focus-*, -outset-focus-*, -inset-focus-*, -inset-inverse-focus-*) only have 1.

Match shadow depth to the element's stacking order — higher shadows for elements visually above others:

Hook Components
--slds-g-shadow-1 Page headers, joined tables, filter panels, dropdowns, inline edit, slider handles
--slds-g-shadow-2 Menus, docked form footer, docked utility bar, color picker, notifications
--slds-g-shadow-3 Panels, docked composer, tooltips, toasts
--slds-g-shadow-4 Modals, popovers, App Launcher

Directional Shadows

For components positioned against screen edges:

Hook Pattern Direction
--slds-g-shadow-block-start-* Upward
--slds-g-shadow-block-end-* Downward (inherits from base)
--slds-g-shadow-inline-start-* Left
--slds-g-shadow-inline-end-* Right

Focus Shadows

Hook Pattern Use Case
--slds-g-shadow-outline-focus-* Simple outline focus
--slds-g-shadow-outset-focus-* Double ring outset focus (white inner, brand outer)
--slds-g-shadow-inset-focus-* Single ring inset focus
--slds-g-shadow-inset-inverse-focus-* Double ring inset focus (brand inner, white outer)

SLDS 2 philosophy: Don't apply shadows to base-level components that sit on a surface without covering other components.

Examples

/* Before */
.modal { box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
.dropdown { box-shadow: 0 2px 4px rgba(0,0,0,0.1); }

/* After */
.modal { box-shadow: var(--slds-g-shadow-4, 0 4px 8px rgba(0,0,0,0.1)); }
.dropdown { box-shadow: var(--slds-g-shadow-1, 0 2px 4px rgba(0,0,0,0.1)); }

Uplift Decision Tree — Non-Color

When the linter flags a non-color hardcoded value, follow this process:

Step 1: Run the Linter First

Always run npx @salesforce-ux/slds-linter@latest lint --fix . before manual fixes. The linter handles exact value-to-hook matches automatically. Only proceed to manual fixes for values the linter flags but cannot auto-fix.

Step 2: Density-Aware or Standard?

Only use density-aware hooks if the original value was a variable density token:

  • --lwc-varSpacingMedium--slds-g-spacing-var-4
  • --lwc-spacingMedium--slds-g-spacing-4 (non-variable, use standard hook)

Step 3: No Exact Match — Should You Replace?

Shadow: If a shadow hook is nearly identical (e.g., offset differs by 1px), replace with the closest equivalent. Otherwise, leave as-is.

Border Radius: Replace by component type (see table above), not by px value. If the element doesn't match a known component type, leave hardcoded.

Typography: If between two scale values, use the closest. If far outside the available range, leave as-is.

Spacing/Sizing: If within 10% of a hook value, update to the closest hook. Otherwise leave as-is.

Hardcoded numerical/structural values: Never change or remove values like width: 100%, height: 50%, max-width: 200px, flex: 1, height: auto, display: none, line-height: 1.5, or 0. These are layout and structural values, not candidates for hooks. Leave them exactly as they are in the source CSS.


Common Mistakes

  1. Inventing hooks that don't exist — This is the most common and damaging mistake. Named hooks (--slds-g-spacing-medium) and out-of-range numbered hooks do not exist. Always verify with the linter.

  2. Confusing spacing and sizing — Spacing is for margins/padding/gaps. Sizing is for width/height/dimensions. Using the wrong one makes the value density-unaware or disrupts the grid system.

  3. Replacing or removing hardcoded numerical values — Never change width: 100%, height: 50%, max-width: 200px, flex: 1, height: auto, display: none, line-height: 1.5, or 0. These are structural/layout values — do not replace them with hooks and do not remove them.

  4. Missing fallback values — Always include the original value as fallback: var(--slds-g-spacing-4, 1rem). Without fallbacks, the component breaks if the hook is unavailable.

  5. Ignoring density-aware variants — For data-dense components (tables, forms, lists), use --slds-g-spacing-var-* and --slds-g-font-scale-var-* so spacing and text adapt to comfy/compact settings.

  6. Using --slds-c-* or --slds-s-* hooks — Only --slds-g-* (global) hooks are valid for migration. Component and scoped hooks are not for direct use in CSS.


Accessibility Notes

Touch Targets

  • Minimum 24x24 CSS pixels for pointer inputs (WCAG 2.2 Level AA)
  • Minimum 44x44 for touch inputs (industry standard)
  • Use spacing hooks for padding to achieve target sizes on interactive elements

Typography Readability

  • Use body-level font scale or larger for primary body text
  • Default base font size (13px) is at the lower limit for comfortable reading
  • Use a line height of 1.5 as default for body text (WCAG 1.4.12)
  • Optimal line length: 45-75 characters (use content width hooks for max-width)

Focus Visibility

  • Use appropriate border-width hooks for focus state borders
  • Use --slds-g-shadow-outset-focus-* for focus rings (double-ring pattern visible on any background)
  • Focus borders must maintain 3:1 minimum contrast with adjacent surfaces

Border Contrast

  • Borders must maintain 3:1 contrast ratio with adjacent surfaces
  • Use higher-contrast border color hooks for interactive elements
  • Use lower-contrast border color hooks for decorative/non-interactive borders