Skip to content
Gloss v2.0.0
Source
Components

IconButton

A square icon-only button. Always pass a label — it becomes the accessible name and the native tooltip, since there is no visible text to fall back on.

Variants

ghost is the default and transparent. outline is a raised fill (no border — the name is kept for API compatibility, not for what it looks like), for an icon button sitting alone rather than in a toolbar. accent is a soft accent tint, for a toggled or active state — the segmented-tabs pattern this system does not otherwise reach for.

A square icon-only button is still a <button>, but there is no attribute that tells it apart from a plain Button sitting alone — variant/size mean different things for each — so .icon-button is the one class this component needs.

Variants
Markup
<button class="icon-button" aria-label="Delete">
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>
</button>
<button class="icon-button" data-variant="outline" aria-label="Settings">
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3" /><path d="M12 2.5v3M12 18.5v3M3.6 7.2l2.6 1.5M17.8 15.3l2.6 1.5M3.6 16.8l2.6-1.5M17.8 8.7l2.6-1.5" /></svg>
</button>
<button class="icon-button" data-variant="accent" aria-label="Filter (active)">
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 5h16l-6 8v5l-4 2v-7z" /></svg>
</button>

Sizes

The box is square and fluid, and it is not a number of its own: it is two rungs of the space scale around one line of the type a Button of the same size would set. So the three sizes come out at 25px, 35–38px, and 39–43px — level with their Button counterparts at any window width, and still level if the scale is ever retuned.

Sizes
Markup
<button class="icon-button" data-variant="outline" data-size="sm" aria-label="Back"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
<button class="icon-button" data-variant="outline" aria-label="Back"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>
<button class="icon-button" data-variant="outline" data-size="lg" aria-label="Back"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 18l-6-6 6-6" /></svg></button>

Paired with Tooltip

An icon-only control almost always wants a Tooltip too — the aria-label covers accessibility, the tooltip covers a sighted mouse user glancing for a hint.

With a tooltip
Delete
Markup
<span>
  <button class="icon-button" aria-label="Delete" aria-describedby="icon-btn-tip">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>
  </button>
  <span role="tooltip" id="icon-btn-tip">Delete</span>
</span>

API

Element / attributeValuesNotes
button.icon-buttonRequired base — the one class in this component, since nothing distinguishes it from Button structurally.
aria-labelstringRequired — becomes the accessible name and the native tooltip.
data-sizesm | lgSquare, matching the Button of the same size: 25px small, 39–43px large. Omit for the default, 35–38px.
data-variantoutline | accentOmit for the default, transparent ghost look.