Web Icons

Last update: 2022-09-26 18:12:04 +0800 +0800
tags: Web | Icons
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Web icons can be text glyphs, SVG graphics, or bitmap images. Format selection affects rendering fidelity, caching, styling, security, and the accessible name exposed by the surrounding control.

Treat Icon Fonts as Fonts #

An icon font maps character codes or ligatures to pictograms:

html
<span class="material-icons" aria-hidden="true">add_location</span>

Glyphs inherit color, font-size, and other text properties, so one font file can theme a monochrome icon set. The same dependency creates its limitations:

  • A blocked or late font displays missing-glyph boxes or fallback text.
  • User styles that replace fonts can remove the icon.
  • Private-use code points have no interoperable textual meaning.
  • Ligature names may be announced by assistive technology.
  • Font smoothing and hinting can change the shape at small sizes.

Hide a decorative font glyph from the accessibility tree and put the accessible name on its control:

html
<button type="button" aria-label="Add location">
  <span class="material-icons" aria-hidden="true">add_location</span>
</button>

Do not place a required label only in generated ::before content. Font loading, custom styles, and accessibility APIs can each remove that channel.

Account for Unicode Glyph Variation #

A Unicode symbol carries a standardized character identity, not a standardized icon design. The selected font controls its outline, metrics, and whether it is rendered as monochrome text or a color emoji. Variation selectors can request text or emoji presentation for some characters, but platforms can still use different artwork.

Use Unicode when the character itself belongs in the text, such as a mathematical operator or directional arrow. Do not use a visually similar character as the only label for an application-specific action. A screen reader announces the character’s semantics, which may not match the intended operation.

Choose an SVG Integration Model #

SVG describes resolution-independent shapes and supports multiple fills, strokes, gradients, and animation. Integration determines styling and security behavior.

Inline SVG #

Inline markup participates in the document cascade:

html
<button type="button">
  <svg
    aria-hidden="true"
    focusable="false"
    width="20"
    height="20"
    viewBox="0 0 20 20">
    <path fill="currentColor" d="M3 10l4 4L17 4"></path>
  </svg>
  Save
</button>

currentColor follows the button’s text color. Inline markup increases HTML size when the same complex icon appears many times, but it provides direct styling and avoids a separate image request.

A meaningful standalone graphic needs an accessible name:

html
<svg role="img" aria-labelledby="network-title" viewBox="0 0 24 24">
  <title id="network-title">Network topology</title>
  <circle cx="12" cy="12" r="8"></circle>
</svg>

Decorative SVGs should instead use aria-hidden="true" and focusable="false". For an icon-only button, name the button itself because the button is the interactive object.

SVG Sprites #

An inline sprite defines reusable symbols:

html
<svg aria-hidden="true" hidden>
  <symbol id="icon-check" viewBox="0 0 24 24">
    <path d="M4 12l5 5L20 6"></path>
  </symbol>
</svg>

<svg aria-hidden="true" focusable="false">
  <use href="#icon-check"></use>
</svg>

An external same-origin sprite moves definitions into a cacheable file:

html
<svg aria-hidden="true" focusable="false">
  <use href="/icons/sprite.svg#icon-check"></use>
</svg>

Browser styling of cloned <use> content is intentionally constrained. Put fill="currentColor" or stable presentation attributes in the symbol and style the outer <svg>. Cross-origin external fragments are not portable even when the server returns CORS headers, so serve the sprite from the same origin or fetch, validate, and inline it.

SVG as an Image #

An SVG loaded through <img> is an isolated image document:

html
<img src="/icons/product-mark.svg" alt="Example product">

Page CSS cannot reach its internal paths, and currentColor does not inherit from the host element. Scripts are disabled in the image context, which makes <img> safer for a trusted static asset than injecting its markup. An empty alt="" marks a decorative image; meaningful images need alternative text.

Treat arbitrary SVG markup as active content when it is embedded inline or served as a navigable document. Sanitize untrusted files, disallow script and event-handler attributes, control external references, and serve the intended media type with an appropriate content security policy.

Size Bitmap Icons for Their Display Density #

PNG, WebP, or AVIF preserves authored pixels, multicolor detail, and effects that may be awkward to reproduce as vectors. A bitmap cannot gain detail when scaled, so provide density variants:

html
<img
  src="/icons/avatar-24.png"
  srcset="/icons/avatar-24.png 1x, /icons/avatar-48.png 2x"
  width="24"
  height="24"
  alt="">

The explicit dimensions reserve layout space. Downsampling a dense source can produce sharp small icons, but large density variants consume bandwidth and memory. Pixel-art icons may require image-rendering rules and integer scaling; photographic or textured icons should use an image format selected for the required alpha channel and compression behavior.

CSS background images suit decoration because they do not contribute an accessible name:

css
.status::before {
  background: url("/icons/status.svg") center / contain no-repeat;
  content: "";
}

Keep the text label in the DOM when the background conveys status.

Select by Semantics and Delivery Constraints #

Use the representation that satisfies the actual contract:

RequirementSuitable Representation
Character belongs in proseUnicode glyph with a tested fallback stack
Monochrome UI icon with direct stylingInline SVG or same-origin SVG sprite
Cacheable static vector with no host stylingSVG through <img>
Multicolor vector markSVG image or carefully scoped inline SVG
Photographic or pixel-authored detailDensity-aware bitmap
Existing legacy icon-font systemIcon font with fallback and accessibility tests

Cacheability can favor one external sprite or image; component isolation can favor inline SVG; a strict content security policy can favor inert image loading over injected markup. Format does not provide semantics by itself. Decorative icons must remain hidden from assistive technology, while controls and meaningful graphics need accessible names that survive asset-loading failure.

Comments

Read or comment on GitHub (sign-in required to comment)