How to apply SLDS styling correctly using hooks, utilities, and custom CSS.
---
## Styling Hook Hierarchy
SLDS hooks follow a three-tier naming system:
| Tier | Prefix | Use |
|------|--------|-----|
| **Global Semantic** | `--slds-g-*` | System-wide. Use these by default. |
| **Shared** | `--slds-s-*` | Private/internal. **DO NOT USE.** Reserved for Salesforce. |
| **Component** | `--slds-c-*` | Scoped to specific LBCs. Use to customize LBC appearance. |
**Rule: Always use `--slds-g-*` hooks unless `--slds-c-*` hooks exist for your specific LBC.**
### Discovering `--slds-c-*` Hooks
Component hooks are scoped to specific Lightning Base Components. To find available hooks for an LBC:
1.**Inspect the LBC docs**: Check the component's [Lightning Component Library](https://developer.salesforce.com/docs/component-library/overview/components) page — look for "Styling Hooks" or "Custom Properties" sections
2.**Browser DevTools**: Render the LBC, inspect the element, and look for `--slds-c-*` properties in the computed styles
There is no centralized metadata file for `--slds-c-*` hooks — they are documented per-component. Some examples exist in `references/overviews/shadows.md` and `references/styling-hooks/index.md`.
**Never reassign hook values.** Salesforce controls them and can change them.
### Choosing Fallback Values
The fallback in `var(--slds-g-*, fallback)` is used when the hook isn't loaded (e.g., outside Lightning Experience, in static HTML previews, or during SSR). Use the **light-mode default** value:
2.**Use the search script**: `node scripts/search-hooks.cjs --prefix "--slds-g-color-surface-"` shows values
3.**Common defaults**: `#ffffff` for surfaces, `#181818` for text, `1rem` for spacing-4, `0.25rem` for radius-border-2
Always use the light-mode default. Dark-mode values are applied automatically when the hook is active — the fallback only matters when hooks aren't loaded at all.
---
## Color: The 85-5-10 Rule
All SLDS UIs should maintain this approximate color distribution:
**CRITICAL:** All color hooks require a numbered variant. There is no unnumbered base form (e.g., `--slds-g-color-on-surface` does not exist -- use `on-surface-1`, `-2`, or `-3`):
| `--slds-g-font-scale-var-*` | Density-aware | Adapts to compact/comfy display density settings |
**Common mappings:**
| Size | Hook | Approximate value |
|------|------|-------------------|
| Small body text | `--slds-g-font-scale-neg-1` | 12px |
| Default body | `--slds-g-font-size-base` | 13px |
| Larger body | `--slds-g-font-scale-1` | 14px |
| Subheading | `--slds-g-font-scale-2` | 16px |
| Heading | `--slds-g-font-scale-4` | 20px |
| Page title | `--slds-g-font-scale-6` | 28px |
| Display | `--slds-g-font-scale-8` | 40px |
**CRITICAL:** `--slds-g-font-size-3`, `--slds-g-font-size-4`, etc. do NOT exist. Only `--slds-g-font-size-base` is valid. For numbered sizes, use `--slds-g-font-scale-*`.
---
## When Hooks Don't Exist
Not all CSS properties have styling hooks. Not all values have hook equivalents either (e.g., `min-width: 7rem` for label alignment). Use this decision tree:
```
Does a hook exist for this property?
├─ YES → Use it: var(--slds-g-*, fallback)
├─ NO → Is there a utility class?
│ ├─ YES → Use the utility class
│ └─ NO → Use minimal custom CSS with:
│ 1. Custom class prefix (my-*, c-*)
│ 2. Use hooks for related values (e.g., hook colors in gradients)
│ 3. Document why no hook/utility exists
```
**Properties without hooks (use custom CSS):**
-`transform`, `transition` (use `--slds-g-duration-*` for timing only)
-`z-index` (use SLDS utility classes when possible)
-`cursor`, `overflow`
- Complex gradients (use hook colors within gradient syntax)
**Values without hook equivalents (acceptable hardcoding):**
Some dimension values have no SLDS hook (e.g., `min-width: 7rem` for label alignment, `max-height: 20rem` for scrollable panels). This is acceptable when:
1. No SLDS sizing hook or utility class covers the value
2. A comment explains the value is intentional
3. SLDS grid utilities (`slds-size_*`) were considered as alternatives
```css
.c-field-label {
/* No SLDS hook exists for this width; intentional for label alignment */