The modern recommendation is to use SVG for icons. SVGs scale crisply at any size, support multiple colors, and can be styled with CSS (e.g., fill: currentColor). Icon fonts (like Font Awesome) still work but have downsides (glyph mapping, multi-color is hard, accessibility quirks).
CSS Icons
1) Icon Fonts (Font Awesome)
<!-- Already loaded in <head> -->
<i class="fa fa-home"></i>
<i class="fa fa-envelope"></i>
fa-home
fa-check
fa-star
Icon fonts size with font-size and color with color (like text).
- ✅ Easy to drop in; works like text.
- ⚠️ Hard to do multicolor; dependent on font loading; screen readers may read them as letters unless hidden.
- ✅ Use
aria-hidden="true"when icons are decorative, or wrap with accessible text.
2) Inline SVG (recommended) with currentColor
<!-- SVG uses fill="currentColor" so CSS color controls icon color -->
<span class="icon icon-md text-danger">
<svg viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor"
d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 ..." />
</svg>
</span>
Inline SVG (heart)
Inline SVG (check)
Color/size come from parent text styles (color, font-size).
- ✅ Crisp scaling, multi-color, easy theming with CSS variables.
- ✅ Accessible — add
aria-hidden="true"if decorative, or a<title>for meaningful icons. - ✅ No glyph mapping; direct control over paths.
3) External SVG Sprite
<!-- sprite.svg contains <symbol id="icon-search">... -->
<svg class="icon icon-md text-primary" aria-hidden="true">
<use xlink:href="../asset/img/sprite.svg#icon-search" />
</svg>
One network request for many icons; use currentColor inside symbols.
<!-- Example: ../asset/img/sprite.svg -->
<svg xmlns="http://www.w3.org/2000/svg" style="display:none;">
<symbol id="icon-search" viewBox="0 0 24 24">
<path fill="currentColor" d="M15.5 14h-.79l-.28-.27A6.5 6.5 0 1 0 14 15.5l.27.28h.79L20 21l1-1-5.5-6z"/>
</symbol>
<symbol id="icon-check" viewBox="0 0 24 24">
<path fill="currentColor" d="M9 16.2l-3.5-3.5 1.4-1.4L9 13.4l7.7-7.7 1.4 1.4z"/>
</symbol>
</svg>
4) Accessible Icon Button
<button class="icon-btn">
<svg class="icon icon-md" viewBox="0 0 24 24" aria-hidden="true">
<path fill="currentColor" d="M3 12h18M12 3v18" />
</svg>
<span class="sr-only">Add item</span>
</button>
Hide decorative SVGs with aria-hidden="true". Provide screen-reader text for buttons.
5) Bonus: CSS Masks as Icons (1-color)
.mask-icon{
background: #1E88E5;
-webkit-mask: url('../asset/img/star.svg') no-repeat 50% 50% / contain;
mask: url('../asset/img/star.svg') no-repeat 50% 50% / contain;
}
Good for simple, single-color shapes. For multicolor or semantic icons, prefer SVG.
Tips & Best Practices:
- Prefer SVG for clarity, theming (
currentColor), and accessibility. - Use
font-sizeto scale icons andcolorto tint when SVG paths usefill="currentColor". - Mark decorative icons
aria-hidden="true". For meaningful icons, include a text label (visually hidden if needed). - Consider an SVG sprite to reduce requests and keep icons centralized.
- Icon fonts are fine for legacy projects, but avoid relying on private glyph codes for meaning.