Icon
Fourteen inline SVGs. Deliberately few - an icon set grows without limit if you let it, and every addition is one more thing to keep visually consistent. These are what the components themselves need plus what an application reaches for in its first week.
Reference
sk-icon
Inline SVG, not a sprite and not an icon font. A sprite needs a fetch and a href that resolves against the document, which breaks the moment htmx swaps content into a page with a different base URL. An icon font fails to a tofu box rather than to nothing. Inline has neither problem, and the templ binding only compiles the icons a project references.
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"></path>
</svg>| Attribute | Type | Default | Notes |
|---|---|---|---|
data-scale | "lg" | "xl" | 1em | Optical sizing. An icon drawn at exactly 1em reads slightly small beside 1em text. |
data-fill | "true" | stroked | Solid glyph. The status icons read better filled at badge sizes. |
aria-hidden | "true" | "true" | Decorative by default, which is the common case. An icon beside text that already says the same thing must stay hidden or the label is read twice. |
role + <title> | role="img" | - | Set by the binding when Label is given, for an icon that carries meaning on its own. |
Examples
The set
Sized in em and stroked in currentColor, so an icon inherits whatever it sits inside.
Show markup
<div class="sink-icon-grid">
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="9">
</circle>
<path d="M12 11v5">
</path>
<path d="M12 8h.01">
</path>
</svg>
<code class="sink-swatch-note">
info
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="9">
</circle>
<path d="m8.5 12.5 2.5 2.5 4.5-5">
</path>
</svg>
<code class="sink-swatch-note">
success
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M10.3 4.3 2.6 17.4a2 2 0 0 0 1.7 3h15.4a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0Z">
</path>
<path d="M12 10v4">
</path>
<path d="M12 17h.01">
</path>
</svg>
<code class="sink-swatch-note">
warning
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="9">
</circle>
<path d="m15 9-6 6">
</path>
<path d="m9 9 6 6">
</path>
</svg>
<code class="sink-swatch-note">
danger
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M18 6 6 18">
</path>
<path d="m6 6 12 12">
</path>
</svg>
<code class="sink-swatch-note">
close
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5">
</path>
</svg>
<code class="sink-swatch-note">
check
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="m18 15-6-6-6 6">
</path>
</svg>
<code class="sink-swatch-note">
chevron-up
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="m6 9 6 6 6-6">
</path>
</svg>
<code class="sink-swatch-note">
chevron-down
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="m15 18-6-6 6-6">
</path>
</svg>
<code class="sink-swatch-note">
chevron-left
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="m9 18 6-6-6-6">
</path>
</svg>
<code class="sink-swatch-note">
chevron-right
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<circle cx="11" cy="11" r="7">
</circle>
<path d="m20 20-3.5-3.5">
</path>
</svg>
<code class="sink-swatch-note">
search
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M12 5v14">
</path>
<path d="M5 12h14">
</path>
</svg>
<code class="sink-swatch-note">
plus
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M4 7h16">
</path>
<path d="M10 11v6">
</path>
<path d="M14 11v6">
</path>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-12">
</path>
<path d="M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2">
</path>
</svg>
<code class="sink-swatch-note">
trash
</code>
</div>
<div class="sink-icon-cell">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="xl" aria-hidden="true" focusable="false">
<path d="M14 4h6v6">
</path>
<path d="M20 4 11 13">
</path>
<path d="M18 14v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4">
</path>
</svg>
<code class="sink-swatch-note">
external
</code>
</div>
</div>Inheriting size and colour
No icon in the system sets its own dimensions. The same markup at three text sizes and three colours.
at body size
in a heading
Show markup
<div class="sk-flex sk-flex-col sk-gap-4">
<p class="sink-size-md">
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5">
</path>
</svg>
at body size
</p>
<h4>
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5">
</path>
</svg>
in a heading
</h4>
<div class="sk-flex sk-items-center sk-gap-4">
<span class="sink-fg-success">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="lg" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="9">
</circle>
<path d="m8.5 12.5 2.5 2.5 4.5-5">
</path>
</svg>
</span>
<span class="sink-fg-warning">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="lg" aria-hidden="true" focusable="false">
<path d="M10.3 4.3 2.6 17.4a2 2 0 0 0 1.7 3h15.4a2 2 0 0 0 1.7-3L13.7 4.3a2 2 0 0 0-3.4 0Z">
</path>
<path d="M12 10v4">
</path>
<path d="M12 17h.01">
</path>
</svg>
</span>
<span class="sink-fg-danger">
<svg class="sk-icon" viewBox="0 0 24 24" data-scale="lg" aria-hidden="true" focusable="false">
<circle cx="12" cy="12" r="9">
</circle>
<path d="m15 9-6 6">
</path>
<path d="m9 9 6 6">
</path>
</svg>
</span>
</div>
</div>In components
Show markup
<div class="sk-flex sk-flex-wrap sk-items-center sk-gap-3">
<button class="sk-button" type="button" data-variant="solid" data-size="md">
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M12 5v14">
</path>
<path d="M5 12h14">
</path>
</svg>
New
</button>
<button class="sk-button" type="button" data-variant="neutral" data-size="md">
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<circle cx="11" cy="11" r="7">
</circle>
<path d="m20 20-3.5-3.5">
</path>
</svg>
Search
</button>
<button class="sk-button" type="button" data-variant="danger" data-size="md">
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M4 7h16">
</path>
<path d="M10 11v6">
</path>
<path d="M14 11v6">
</path>
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2l1-12">
</path>
<path d="M9 7V5a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2">
</path>
</svg>
Delete
</button>
<span class="sk-badge" data-status="success">
<svg class="sk-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5">
</path>
</svg>
Verified
</span>
</div>