DEV Community

137Foundry
137Foundry

Posted on

Why Icon Fonts Are a Bad Default for Modern Web Apps

Icon fonts had a good run. Bundling dozens of icons into a single font file was a genuinely clever way to ship a lot of visuals cheaply back when every image request cost a separate connection and SVG tooling was clunkier than it is now. Most of those constraints don't apply anymore, and the tradeoffs that were always there, the ones that were easy to overlook when the alternative was worse, are now the whole story.

A surprising number of production codebases still default to an icon font on new projects today, usually because it's what the team used on the last three projects and switching feels like unnecessary churn. It's worth walking through exactly why that default deserves reconsidering, because the reasons aren't cosmetic preferences, they're structural limitations that get more expensive to live with as a product and its icon set both grow.

A specimen poster showing letterforms and glyphs arranged on a grid
Photo by Lisa from Pexels on Pexels

The accessibility problem is structural, not incidental

An icon font works by mapping a Unicode private-use character to a glyph the font renders as a picture instead of a letter. Screen readers have no reliable way to know that a given private-use character should be silent or should announce something specific, so without careful aria-hidden and label markup on every single instance, assistive technology either announces garbled character codes or skips the icon's meaning entirely. The W3C accessibility guidance on non-text content spells out why every icon needs a reliable text alternative, and an icon font makes that discipline easy to skip precisely because the icon renders correctly for sighted users without it.

WebAIM has documented this exact failure pattern repeatedly in accessibility audits: icon fonts that look fine visually and are functionally invisible or actively confusing to screen reader users, because the accessible-name work was never done consistently across a growing icon set.

Font loading blocks more than it should

A font file has to load before any icon in it renders, and until it does, either nothing shows or a fallback glyph flashes briefly in its place. SVG icons, whether inline or referenced from a sprite, don't have this all-or-nothing loading behavior. Each one is just markup, styleable and stylable independent of a separate font request that can fail or arrive late on a slow connection.

You can't tree-shake a font file

A modern bundler can drop unused SVG icon components from a production build, so a page that uses ten icons out of a two-hundred-icon library only ships those ten. A font file doesn't work that way. The entire font, every glyph whether the page uses it or not, downloads as one unit. For a small icon set the difference is negligible. For a design system that's grown past a hundred icons over a couple of years, it's real, avoidable weight.

Styling flexibility is more limited than it looks

Icon fonts can be recolored and resized with standard CSS color and font-size, which feels flexible until you need a two-tone icon, a gradient fill, or an icon that changes stroke width on hover. Those effects are straightforward with SVG and effectively impossible with a font glyph, since a font character is fundamentally one shape with one fill.

What most teams should use instead

Individual inline SVG components, each carrying its own accessible markup and styled with normal CSS, are the more common modern default, and a sprite sheet referenced with <use> is the right middle ground for larger sets where individual component overhead matters. Font Awesome itself has shifted its own recommended integration toward SVG delivery over the older font-based approach, which is a reasonable signal about where the ecosystem has settled.

The migration is smaller than teams expect

Teams that inherit a codebase built on an icon font often assume replacing it means redrawing every icon, and that assumption is what keeps the migration permanently deprioritized. In practice, the visual design of most icons in a font-based set doesn't need to change at all, since the same shapes exist as SVG in whatever library the font was originally built from, or can be extracted from the font file itself with existing conversion tools. What actually needs rebuilding is the delivery layer: the CSS classes that reference font glyphs get replaced with components or sprite references, one icon usage at a time, without touching the icon designs themselves.

A reasonable migration path runs the old icon font and the new SVG-based system side by side for a release cycle or two, converting usages as pages get touched for other reasons rather than as a dedicated rewrite. That approach spreads the work across normal development instead of requiring a standalone project that competes with feature work for prioritization, which is usually where icon font migrations stall out indefinitely.

Why this keeps mattering more, not less

Accessibility compliance requirements have gotten stricter across most jurisdictions in the past several years, not looser, and an icon font's structural accessibility gap doesn't get smaller as scrutiny increases. A codebase that could get away with an icon font's accessibility shortcuts five years ago is increasingly less likely to get away with it going forward, which makes the migration a matter of when, not really if, for most production products still running one.

The build tooling argument has also flipped

Ten years ago, SVG tooling was genuinely more painful than it is now. Optimizing dozens of hand-exported SVG files, deduplicating paths, and wiring up a sprite build were real friction points that made a single font file look appealing by comparison. That friction has mostly disappeared. Modern bundlers handle SVG imports natively, optimization tools like SVGO run automatically as part of most build pipelines, and component frameworks treat an SVG icon as a first-class citizen rather than an awkward asset type bolted on afterward. The technical argument for icon fonts being "simpler to set up" hasn't just weakened, in most modern toolchains it's reversed.

What to check before assuming your icon font is fine

If you're not sure whether your product's icon font is causing real accessibility problems, the fastest check is turning on a screen reader, VoiceOver on macOS or NVDA on Windows both work and are free, and tabbing through your interface's icon-only buttons. If you hear "button" with no further description, or a string of nonsense characters, that's the exact failure mode this article describes, happening on your own product right now rather than as a hypothetical.

We go deeper on picking a format, setting a sizing grid, and governing additions in 137Foundry's guide to building an icon system that scales. If your team is still shipping an icon font from a few years back, migrating it is usually a smaller project than it looks, and 137Foundry can help scope that work.

One caveat worth stating plainly

None of this means every product currently running an icon font is in crisis. A well-labeled icon font, with careful aria-hidden and accessible-name markup applied consistently, is functionally accessible even if it carries more overhead than SVG would. The argument here isn't that every icon font deployment is broken today, it's that an icon font is a worse default to reach for on a new project, and an existing one deserves a real cost-benefit look rather than being left alone purely out of inertia.

Top comments (0)