Principles
- Slots, not glyphs: components reserve space and alignment; you provide SVG, an icon font, or inline markup.
currentColor: icons inherit semantic text colors (action, body, on-action) from the parent component.- One source per app: pick any library (Phosphor, Heroicons, Material Symbols, custom sprites) and use it consistently.
- Accessible names: decorative icons beside visible text use
aria-hidden="true"; icon-only controls needaria-label(see Accessibility guide).
Examples in context
Three common slots with Phosphor Regular (ph classes). Match the icon graphic size to the slot (20px in buttons, 24px in fields and alerts).
Slot reference
Default sizes come from Sass variables in scss/abstracts/_variables.scss (!default, overridable via @use "pimentcss-design-system" with ()). The _icon-slot.scss partial scales child svg, .ph, and i[class*="ph-"] to fill the slot.
| Slot class | Default size | Used in |
|---|---|---|
.tag__icon | 1rem (16px) | Tags |
.checkbox__icon | Control box (16px graphic) | Checkboxes |
.btn__icon, .btn-group__icon, .tab__icon, .table__icon, .tree__icon, .link__icon, .nav-item__icon | 1.25rem (20px) | Buttons, Button group, Tabs, Table, Tree, Links, Navigation |
.field__icon, .textarea-field__icon, .menu__item-icon | 1.5rem (24px) | Input fields, Menu & dropdown |
.alert__icon, .snackbar__icon, .pagination__item-icon, .carousel__arrow-icon | 1.5rem (24px) | Alerts, Snackbar, Pagination, Carousel |
.alert__close, .snackbar__link-icon | 1.25rem / 1rem | Alerts, Snackbar |
.list__indicator-icon | 1rem graphic in 1.5rem indicator | List |
.theme-toggle__option svg | Custom sun/moon SVG (not a __icon slot) | Theme toggle |
Chevrons in selects and dropdowns may use CSS masks (.field--select, .dropdown__chevron) instead of an icon library.
Phosphor (documentation example)
To mirror the doc site, install Phosphor Web and load the Regular stylesheet once per app shell.
npm install @phosphor-icons/web
<link rel="stylesheet" href="/docs/node_modules/@phosphor-icons/web/src/regular/style.css">
Set font-size on the ph element to match the slot (see table above). The slot box still comes from PimentCSS; Phosphor only draws the glyph.
Inline SVG
Prefer fill="currentColor" or stroke="currentColor" so light/dark semantics apply automatically.
<button type="button" class="btn btn--outline btn--icon-only" aria-label="Close"><svg class="btn__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">
<path d="M6 6l12 12M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
</svg></button>
Accessibility
Naming and visibility
- Decorative (text or label already names the control):
aria-hidden="true"on the icon, plusfocusable="false"on SVG. - Icon-only:
aria-labelon thebuttonora; never leave the glyph as the only accessible name. - Meaningful standalone icons (rare): use visible text or
aria-labelon the control; do not rely on shape alone.
Touch targets for icon-only buttons use .btn--icon-only (min 44×44px). See Buttons: icon-only and Accessibility: touch targets.
Customize slot sizes (Sass)
@use "pimentcss-design-system" with (
$btn-icon-size: 1.25rem,
$field-icon-size: 1.5rem,
$tab-icon-size: 1.25rem,
);
After changing sizes, redraw or re-export icons from your library at the new pixel grid.