Complete CSS Course Module 5: Beginner: Styling Common Elements

CSS Icons: SVG Icons, Icon Fonts and Emoji

  • Beginner
  • Lesson 5.2
  • 5 min read
  • 21 of 77 in the course

In short

CSS icons make buttons and menus easier to understand. Learn to style inline SVG icons with currentColor, use icon libraries, align icons with text, and build accessible icon buttons.

CSS icons make buttons and menus easier to understand. Learn to style inline SVG icons with currentColor, use icon libraries, align icons with text, and build accessible icon buttons.

Three ways to add icons to a website

Icons are small pictures, like a magnifying glass for "search" or a trash can for "delete". There are three common ways to add them:

MethodHow it worksGood for
Inline SVGYou paste the icon's <svg> code into your HTML.Most projects in 2026. Sharp, easy to color, no extra download.
Icon libraryYou load a font or stylesheet (Font Awesome, Google Material Symbols) and add a class or a word.Quick prototypes, many icons.
EmojiYou type a character like a magnifying glass or a check mark emoji.Fun, casual content.

SVG stands for Scalable Vector Graphics. It describes a picture with shapes and lines instead of pixels, so it stays sharp at any size, like a drawing made with a ruler instead of a mosaic of tiles.

Styling inline SVG icons with currentColor

The best trick for SVG icons is currentColor. It's a CSS keyword that means "the current text color". If the icon uses currentColor for its stroke or fill, it automatically matches the text around it, and changes color on hover together with the text.

<a class="nav-link" href="/search">
  <svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
    <circle cx="11" cy="11" r="7"></circle>
    <line x1="16.5" y1="16.5" x2="21" y2="21"></line>
  </svg>
  Search
</a>
.nav-link {
  color: #334155;
  text-decoration: none;
}

.nav-link:hover {
  color: #2563eb;
}

.icon {
  width: 1.25em;
  height: 1.25em;
  vertical-align: -0.25em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

You'll see a magnifying glass next to the word "Search", both in dark gray. When you hover, the text and the icon turn blue together, because the icon's stroke follows color. The viewBox attribute tells the browser the drawing's coordinate system; CSS then decides the real size.

  • fill colors the inside of shapes.
  • stroke colors the outlines of shapes, and stroke-width sets their thickness.
  • aria-hidden="true" hides a decorative icon from screen readers, because the word "Search" already explains the link.

Free SVG icon sets like Heroicons, Lucide and Feather let you copy the <svg> code for any icon.

Using icon libraries: Font Awesome and Material Symbols

Icon libraries give you thousands of icons through one <link> in your <head>. Google Material Symbols is an icon font: a font file where each "letter" is an icon. You write the icon's name as text, and the font turns it into a picture.

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined">

<p class="status">
  <span class="material-symbols-outlined" aria-hidden="true">check_circle</span>
  Payment received
</p>
.status {
  color: #15803d;
}

.status .material-symbols-outlined {
  font-size: 1.5rem;
  vertical-align: middle;
}

The word check_circle becomes a green circle with a tick, because icon fonts are text: they follow color and font-size like any letter. Font Awesome works in a similar way. You load its stylesheet from a CDN (its website gives you a link or "kit") and write <i class="fa-solid fa-house"></i> where you want a house icon.

Note: Icon fonts download a whole font file, even if you use only three icons, and if the font fails to load, users may see the raw word "check_circle". For small sites, a few inline SVGs are usually lighter and more reliable.

Sizing and aligning icons with text

Icons often look slightly too high or too low next to text. The most reliable fix is flexbox:

<button class="btn">
  <svg class="icon" viewBox="0 0 24 24" aria-hidden="true">
    <path d="M12 5v14M5 12h14"></path>
  </svg>
  Add item
</button>
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.6em 1.2em;
  font-size: 1rem;
  color: white;
  background: #16a34a;
  border: none;
  border-radius: 8px;
}

.btn .icon {
  width: 1.2em;
  height: 1.2em;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
}

The plus icon and the words "Add item" sit perfectly centered on one line, with a gap between them. display: inline-flex with align-items: center lines them up, and sizing the icon in em means it grows and shrinks with the button's font size. flex-shrink: 0 stops the icon from getting squashed in a narrow button.

For icons inside a running paragraph, where you can't use flexbox, vertical-align: middle or a small nudge like vertical-align: -0.125em works well (you saw this in the first example).

Accessible icon buttons

An icon-only button (a button with an icon and no visible words) is a problem for screen readers: they have nothing to read out. Always give it a text label.

<button class="icon-btn" aria-label="Close menu">
  <svg viewBox="0 0 24 24" aria-hidden="true">
    <path d="M6 6l12 12M18 6L6 18"></path>
  </svg>
</button>
.icon-btn {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: #334155;
  background: transparent;
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.icon-btn:hover { background: #f1f5f9; }

.icon-btn svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

You'll see a round close button with an "X". A screen reader announces it as "Close menu, button" thanks to aria-label. The button is 44 by 44 pixels, which is easy to tap, even though the icon is only 24px.

Common mistake: Using an emoji as the only label of a button, like a button containing just a wastebasket emoji. Screen readers read out the emoji's official name, which may not match the action, and emoji look different on every device. Use emoji as decoration next to real words, and mark purely decorative ones with aria-hidden="true" inside a <span>.

Practice exercise

Build a small toolbar with four icon buttons: Home, Search, Settings and Log out. Use inline SVG icons that use currentColor, make each button 44 by 44 pixels, give each one an aria-label, and change the color on hover. Add a visible text label under each icon on wide screens.

Hint: copy icons from a free SVG set like Lucide and remove any fixed width, height or color attributes so your CSS controls them.

Key takeaways

  • Inline SVG is the modern default for icons: sharp, light and easy to style.
  • Use stroke: currentColor or fill: currentColor so icons match and follow the text color.
  • Icon fonts like Material Symbols and Font Awesome are text, so color and font-size style them.
  • Align icons with text using display: inline-flex, align-items: center and a gap.
  • Give icon-only buttons an aria-label and hide decorative icons with aria-hidden="true".