Icons
Hypermedia Components ships no icon set — by design. Icons are an
app-level choice, and a CSS + behaviors library shouldn’t lock you into
one. (HC’s own chrome — the select chevron, checkbox tick, accordion
caret — is inline SVG drawn with currentColor, so it already tracks
your theme.)
Pick any set you like; the ones below pair especially cleanly with HC because they meet four criteria:
currentColor— the icon inherits the surrounding text / button / accent color, so it tracksdata-coloranddata-neutralfor free.- Framework-free — works in plain server-rendered HTML and survives htmx swaps (no React/Vue runtime needed).
em-sizable — scales with the surrounding text and density.- Open license.
Recommended
Section titled “Recommended”1. Iconify <iconify-icon> — best fit for hypermedia
Section titled “1. Iconify <iconify-icon> — best fit for hypermedia”A framework-free web component. Drop the script once, then reference any
of 200k+ icons (Lucide, Tabler, Phosphor, Remix, Material, …) by name.
It colors from CSS currentColor, sizes from font-size, and
re-renders itself after htmx swaps with no re-init.
<script type="module" src="https://cdn.jsdelivr.net/npm/iconify-icon@2"></script>
<button class="hc-button" data-variant="primary"> <iconify-icon icon="lucide:check" class="hc-icon"></iconify-icon> Save</button>Pick the set per-icon via the prefix: lucide:check, tabler:check,
ph:check, ri:check-line, material-symbols:check.
2. Lucide — best single set for HC’s look
Section titled “2. Lucide — best single set for HC’s look”24px grid, 1.5–2px stroke, currentColor — visually consistent with
HC’s built-in stroke chrome. Use it three ways: copy the inline SVG, the
lucide vanilla initializer, or via Iconify (lucide:*).
The vanilla initializer needs re-running after an htmx swap:
<i data-lucide="check"></i><script> lucide.createIcons(); document.body.addEventListener('htmx:afterSwap', () => lucide.createIcons());</script>3. SVG sprite — most hypermedia-pure (zero JS)
Section titled “3. SVG sprite — most hypermedia-pure (zero JS)”Bundle the icons you use into one sprite and reference them with <use>.
No runtime, server-renderable, fastest, currentColor.
<button class="hc-button"> <svg class="hc-icon" aria-hidden="true"><use href="/icons.svg#check"></use></svg> Save</button>Other good sets (all available through Iconify too): Tabler, Phosphor (regular / bold / fill / duotone), Remix, Heroicons, Material Symbols (variable font). Prefer an outline / stroke set to match HC’s built-in chrome.
Wiring with HC
Section titled “Wiring with HC”Color — let currentColor do the work
Section titled “Color — let currentColor do the work”Don’t set an icon color. Leave the icon on currentColor and it inherits
whatever HC color is in scope — the button’s foreground, body text, or the
active accent. It then tracks data-color / data-neutral / dark mode
automatically.
Size — the .hc-icon utility
Section titled “Size — the .hc-icon utility”The .hc-icon utility sizes an icon to the surrounding text
(--hc-icon-size: 1em), sets flex: none, and aligns it to the
baseline. Override per-instance:
<svg class="hc-icon" style="--hc-icon-size: 1.25rem" aria-hidden="true">…</svg>Accessibility
Section titled “Accessibility”- Decorative icon next to a text label →
aria-hidden="true". - Icon-only control → give it an accessible name and hide the glyph:
(Or put a visible-to-AT label in<button class="hc-button" aria-label="Search"><svg class="hc-icon" aria-hidden="true"><use href="/icons.svg#search"></use></svg></button>
.hc-sr-only.)
Live examples
Section titled “Live examples”These use inline Lucide SVGs with .hc-icon — no library loaded, just
currentColor + the utility. Switch the header Color / Neutral /
theme pickers and watch the icons follow.
Done
3 notifications
<button class="hc-button" data-variant="primary"> <svg class="hc-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"> <path d="M20 6 9 17l-5-5"/> </svg> Save</button>Related
Section titled “Related”- Color themes · Neutral ramps — what
currentColoricons follow. - Accessibility — icon-only control labelling.