Iconography
Icons communicate meaning quickly and reinforce text labels. Tessera UI provides design guidelines that work with any icon library, plus a built-in ts-icon component with Lucide icons available out of the box.
For setup and configuration details, see the Icons setup guide.
Sizing
Section titled “Sizing”Icons should align with the type scale for visual consistency:
| Context | Icon Size | Matching Font Token |
|---|---|---|
| Badge, caption | 12px | --ts-font-size-xs |
| Button (sm), label | 14px | --ts-font-size-sm |
| Button (md), body text | 16px | --ts-font-size-md |
| Button (lg), subheading | 18px | --ts-font-size-lg |
| Section header | 20px | --ts-font-size-xl |
| Hero, display | 24px+ | --ts-font-size-2xl+ |
Rule of thumb: Icon size should match the font-size of adjacent text. If an icon sits next to 14px text, the icon should be 14px.
Stroke Width
Section titled “Stroke Width”For outlined icon libraries, maintain consistent stroke width across all icons:
- Recommended:
1.5px–2pxstroke width - Avoid mixing stroke widths within the same interface — this creates visual noise
- Choose a weight and apply it consistently (most libraries support this via props or CSS)
Vertical Alignment
Section titled “Vertical Alignment”Icons should vertically center with their adjacent text. Tessera UI components handle this automatically via inline-flex and align-items: center:
<ts-button> <ts-icon slot="prefix" name="save" size="sm"></ts-icon> Save</ts-button>For standalone icons next to text, use flexbox:
.icon-text { display: inline-flex; align-items: center; gap: var(--ts-spacing-2);}Slot Integration
Section titled “Slot Integration”Tessera UI components provide prefix and suffix slots for icon placement:
Button
Section titled “Button”<ts-button> <ts-icon slot="prefix" name="download" size="sm"></ts-icon> Download <ts-icon slot="suffix" name="external-link" size="sm"></ts-icon></ts-button><ts-input label="Search"> <ts-icon slot="prefix" name="search" size="md"></ts-icon></ts-input><ts-alert variant="info"> <ts-icon slot="icon" name="info" size="md"></ts-icon> Your changes have been saved.</ts-alert>Accessibility
Section titled “Accessibility”- Decorative icons (next to text that conveys meaning): omit the
labelprop —ts-iconsetsaria-hidden="true"automatically - Meaningful icons (no adjacent text): set the
labelprop —ts-iconsetsrole="img"andaria-labelautomatically - Icon-only buttons: always provide an
aria-labelon the button
<!-- Decorative — text conveys meaning, icon is supplementary --><ts-button> <ts-icon slot="prefix" name="trash-2"></ts-icon> Delete</ts-button>
<!-- Meaningful — icon IS the label --><ts-button aria-label="Close"> <ts-icon slot="prefix" name="x" label="Close"></ts-icon></ts-button>Choosing an Icon Library
Section titled “Choosing an Icon Library”| Library | Style | License | Best For |
|---|---|---|---|
| Lucide (built-in) | Outlined, geometric | ISC | General-purpose UI |
| Phosphor | Six weight variants | MIT | Flexible, multi-weight designs |
| Heroicons | Outlined + solid | MIT | Tailwind-adjacent projects |
| Material Symbols | Outlined + filled + rounded | Apache 2.0 | Material Design ecosystems |
| Tabler Icons | Outlined, consistent stroke | MIT | Clean, minimal UI |
Lucide is available out of the box. To use a different library, see Swapping icon libraries.
Guidelines
Section titled “Guidelines”- One icon library per project. Mixing libraries creates visual inconsistency in stroke width, style, and proportions.
- Use semantic icons. A trash can means “delete,” a pencil means “edit.” Don’t repurpose icons for unrelated actions.
- Don’t use icons as the sole indicator of state. Always pair icons with text or ARIA labels for accessibility.
- Size icons to match text. An oversized icon next to small text looks unbalanced. Use the sizing table above.
- Prefer
ts-iconover raw SVG. The component handles sizing, color inheritance, and accessibility attributes consistently.