Examples
Inline with text
Changes sync every 30 seconds
<p>
Changes sync every 30 seconds
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
</p>
Fixed sizes
is-xs · 1rem
is-sm · 1.25rem
is-lg · 1.75rem
is-xl · 2.25rem
<div class="cluster">
<span class="stack is-tight is-center text-center">
<svg
class="icon is-xs"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
<small class="text--2 text-muted">is-xs · 1rem</small>
</span>
<span class="stack is-tight is-center text-center">
<svg
class="icon is-sm"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
<small class="text--2 text-muted">is-sm · 1.25rem</small>
</span>
<span class="stack is-tight is-center text-center">
<svg
class="icon is-lg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
<small class="text--2 text-muted">is-lg · 1.75rem</small>
</span>
<span class="stack is-tight is-center text-center">
<svg
class="icon is-xl"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
<small class="text--2 text-muted">is-xl · 2.25rem</small>
</span>
</div>
The default is em-sized
Small text, small icon
Body text, body-sized icon
Larger text, larger icon -- the default consumes --default-icon-size (1.1em), so it tracks the surrounding text
<p class="text--1">
Small text, small icon
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
</p>
<p>
Body text, body-sized icon
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
</p>
<p class="text-1">
Larger text, larger icon -- the default consumes --default-icon-size (1.1em), so it
tracks the surrounding text
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
<path d="M21 3v5h-5" />
</svg>
</p>
Any source, any paint
Stroke icons keep their strokes
.icon sets size and nothing else, so a stroke-based set stays stroke-based at any size.
Filled icons keep their fills
The same class on a filled glyph: no fill or stroke is forced, so each icon keeps its own paint.
<div class="media">
<svg
class="icon is-lg media-figure"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" />
<path d="M13.73 21a2 2 0 0 1-3.46 0" />
</svg>
<div class="media-body">
<strong>Stroke icons keep their strokes</strong>
<p>
.icon sets size and nothing else, so a stroke-based set stays stroke-based at
any size.
</p>
</div>
</div>
<div class="media">
<svg
class="icon is-lg media-figure"
viewBox="0 0 24 24"
fill="currentColor"
stroke="none"
aria-hidden="true"
>
<path d="M12 2a10 10 0 1 0 10 10A10 10 0 0 0 12 2Zm1 15h-2v-2h2Zm0-4h-2V7h2Z" />
</svg>
<div class="media-body">
<strong>Filled icons keep their fills</strong>
<p>
The same class on a filled glyph: no fill or stroke is forced, so each icon
keeps its own paint.
</p>
</div>
</div>
Inside icon-box
<div class="cluster">
<span class="icon-box">
<svg
class="icon is-sm"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<circle cx="12" cy="12" r="10" />
<path d="M12 16v-4M12 8h.01" />
</svg>
</span>
<span class="icon-box is-primary is-lg">
<svg
class="icon"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z" />
</svg>
</span>
</div>
Source comments
Icons -- the bare glyph atom and the colored container
.icon (P3 atom) styles the consumer's own svg geometry and nothing
else: token sizing and flex-shrink: 0. It never touches fill,
stroke, or stroke-width, which is what makes it work with icons
from any source -- Lucide, Heroicons, tabler, a sprite, a
hand-drawn svg all keep their own paint (P8: content glyphs live
in consumer markup). The default size consumes the root
--default-icon-size token, so inline icons scale with surrounding text;
the is-* variants shadow the token locally with fixed sizes for
standalone glyphs. Inline alignment is part of the component: the
glyph sinks slightly below the text baseline (-0.125em) so it
reads as part of the line, the way an icon font would.
.icon-box is the container, not the glyph: a fixed-size square
for feature grids, media objects, and notification feeds. Pair
them when you want a tinted square -- .icon sizes the glyph,
.icon-box the box.
Markup:
<svg class="icon is-sm" aria-hidden="true">...</svg>
<div class="icon-box is-primary">
<svg class="icon" aria-hidden="true">...</svg>
</div>
Reference
Source: src/css/icon.css
Applies to
.icon
Classes
| Class | Kind | Description |
|---|---|---|
.is-xs | variant | 1rem glyph |
.is-sm | variant | 1.25rem glyph |
.is-lg | variant | 1.75rem glyph |
.is-xl | variant | 2.25rem glyph |