icons in code, the 2026 answer

How to vertically align an icon with text

Your icon sits a little too high, or a little too low, and the old answers say “add top: 2px”. Here is what actually works now: flexbox and gap, a 1em icon, -0.125em for running text, and the new CSS text-box for a true optical centre.

Short answer
  • Icon next to a label (buttons, menus, chips)? Put both in a flex row: display: inline-flex; align-items: center; gap: 0.5em, and size the icon in em.
  • Icon inside a sentence? Make it 1em square and set vertical-align: -0.125em. vertical-align: middle lines up with the lower-case letters, so it often looks slightly off.
  • New in 2026: text-box: trim-both cap alphabetic on the label trims the empty space above capitals and below the baseline, so centring looks right. It became Baseline in August 2026, when Firefox 154 shipped it.
  • A small gap under an icon on its own line is the space kept for letters like g and y. Fix it with display: block on the SVG.
  • Skip magic numbers like position: relative; top: 2px. They break as soon as the font or size changes.
Written by
Published
Reading time
8 min
Facts checked
A white desk with a pink ruler and paper, with the giant word Home and the with icons home icon on it, and cyan cap height, x-height and baseline guide lines running across the whole picture
Photo: Jess Bailey Designs on Pexels
On this page 9 sections

To vertically align an icon with text, put them in a flex row: display: inline-flex; align-items: center; gap: 0.5em, with the icon sized in em. When the icon sits inside a sentence and you cannot add a wrapper, make it 1em square and nudge it with vertical-align: -0.125em. For a true optical centre, the new CSS text-box: trim-both cap alphabetic trims the label to its capital letters, and it has worked in every major browser since August 2026.

That covers almost every case. Below we explain why icons drift in the first place, which vertical-align values do what, how text-box changes the picture, how to line up icons inside buttons, and how to kill the mystery gap under an SVG. Every example uses real icons from with icons, but the CSS works with any SVG icon set.

Why is my icon not aligned with my text?

Because an icon and a word are measured differently. An SVG placed in a line of text behaves like a big letter: its bottom edge sits on the baseline, the invisible line letters stand on. But text has extra room around it. Above the capitals there is space for accents and line spacing, and below the baseline there is space for the tails of g, p and y.

So a 1em icon sitting on the baseline pokes up above the capital letters and looks too high. And when you centre the icon on the whole text box, you centre it on the letters plus that invisible padding, which is usually not where the eye puts the middle. Fixing alignment means deciding what “centre” you mean.

Diagram of the word Settings with guide lines for line box top, cap height, x-height, baseline, descender and line box bottom, tinted empty space above the capitals and below the baseline, and two settings icons: one sitting on the baseline marked with a red cross, one centred between cap height and baseline marked with a green tick
Where text really sits: baseline, x-height, cap height and the empty space a font keeps around them.Artwork: with icons

How do I centre an icon next to text with flexbox?

This is the answer for buttons, menu items, badges, chips and list rows: anywhere you can wrap the icon and its label in one element.

.with-label {
  display: inline-flex;
  align-items: center;   /* centre the icon and the text on each other */
  gap: 0.5em;            /* space between them, scales with the text */
}
.with-label svg {
  width: 1.25em;
  height: 1.25em;
  flex-shrink: 0;        /* never let a long label squash the icon */
}
<a class="with-label" href="/settings">
  <svg viewBox="0 0 24 24" aria-hidden="true">…</svg>
  <span>Settings</span>
</a>

Three small details make this hold up. gap replaces the old margin on the icon, and works in either direction (icon before or after). Sizing in em means the icon grows with the text, so a large heading and a small caption both stay balanced. And flex-shrink: 0 stops the icon shrinking when the label is long and the row runs out of room.

16px
20px
24px
32px
48px
Sized in em, an icon follows its text. The same four icons from 16 to 48 px: the range 1em to 2em covers with everyday 16 to 24 px text.

If your label wraps onto two lines, align-items: center centres the icon on the whole block, which can look odd. Use align-items: flex-start and wrap the icon in a small flex box with height: 1lh (one line height, a unit every major browser has supported since 2023) that centres it, so the icon stays centred on the first line.

Should I use vertical-align: middle or -0.125em?

Inside running text, where an icon sits in a sentence like “Tap the ★ to save”, there is often no wrapper to make into a flex row. Then vertical-align on the icon itself is the tool. The values are easy to mix up:

vertical-align values for an icon inside a line of text (checked November 2026)
ValueWhat it lines upHow it looks with a 1em icon
baseline (default)Bottom of the icon on the text baseline Too high: the icon pokes above the capitals
middleMiddle of the icon on the baseline plus half the x-height (MDN’s definition) Close next to lower-case text, a little low next to capitals
-0.125emBottom of the icon one eighth of the font size below the baseline Balanced in most fonts
text-bottomBottom of the icon on the bottom of the text area Usually sits low
top: 2px (with position: relative)Whatever 2 pixels happened to fix on one screen Breaks when the font or size changes

The -0.125em value is a rule of thumb rather than a standard, but a widely shared one: Iconify’s docs recommend it for inline icons, and our own CSS classes use it. Because it is in em, it scales with the text instead of being tied to one size.

.inline-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
}

If an icon should match the height of capital letters exactly, size it with the cap unit: height: 1cap. It reads the real cap height from the font you use, and has been Baseline since December 2023.

What is CSS text-box, and does it fix icon alignment?

text-box is a newer CSS property that trims the empty space a font keeps above and below its letters. With text-box: trim-both cap alphabetic, the top of the text box moves down to the top of the capital letters, and the bottom moves up to the baseline. What is left is a box exactly as tall as an “H”.

That is exactly what icon alignment needs. Centre an icon on that trimmed box and it centres on the letters people actually see, not on invisible padding. The property applies to block containers and inline boxes, so put it on the label’s own element, not on the flex row:

.with-label { display: inline-flex; align-items: center; gap: 0.5em; }
.with-label > span { text-box: trim-both cap alphabetic; }

Support arrived in steps. Safari 18.2 shipped it in December 2024 and Chrome and Edge 133 in February 2025. Firefox 154 completed the set on 18 August 2026, and MDN now lists text-box as Baseline 2026, newly available. Browsers without it simply ignore the line, and the flexbox centring underneath still works, so it is safe to add today.

  • Results depend on the font. The trim reads the font’s own cap-height and baseline data, so check your real typeface.
  • Mostly lower-case labels? Try text-box: trim-both ex alphabetic, which trims to the x-height instead.
  • It also tidies padding. Trimmed buttons look evenly padded top and bottom, which was the property’s original purpose.
Before and after: two large Download buttons with the with icons download icon. The first, centred with align-items: center, shows a dashed text box taller than the letters and the icon sitting slightly low; the second adds text-box: trim-both cap alphabetic, so the dashed box hugs the letters and equal measures show the icon visually centred
Before and after text-box: the same button, centred on the text box and centred on the letters.Artwork: with icons

How do I align an icon inside a button?

  1. 1
    Make the button a flex row

    Set display: inline-flex; align-items: center; gap: 0.5em; on the button, and keep vertical padding equal top and bottom.

  2. 2
    Size the icon in em

    Use 1.25em for most buttons and flex-shrink: 0 so it keeps its shape. Skip margins: gap handles the spacing.

  3. 3
    Wrap the label and trim it

    Put the text in a <span> and add text-box: trim-both cap alphabetic for an optical centre in current browsers.

  4. 4
    Hide the icon from screen readers

    With a visible label, the icon is decoration: add aria-hidden="true". An icon-only button needs an aria-label instead.

Do

Centre with flexbox, size the icon in em, space with gap, and let text-box fine-tune the optical centre.

Don’t

Nudge icons with position: relative; top: 2px, set line-height: 0 on buttons, or add a margin to the icon that only works at one font size.

Common button icons. Solid icons hold up best at the small sizes buttons use.

How big should the button itself be, and how do you label an icon-only one? That is its own question, answered in how big an icon button should be. For the icon sizes that look sharp, see our icon sizes guide.

Why is there a gap below my inline SVG?

This one is not stale, just puzzling. An SVG is inline by default, so it sits on the baseline, and the browser keeps space below for letter tails even when there are no letters. You see a few pixels of empty space under an icon, or a parent that is taller than its icon.

/* an icon on its own: make it a block */
.icon-standalone { display: block; }

/* or keep it inline but stop baseline alignment */
.icon-standalone { vertical-align: middle; }

A flex or grid container fixes it too, because flex items are not aligned on a baseline unless you ask for it. That is one more reason the flex pattern above is the default answer.

How do with icons line up with text?

Our packages do the first steps for you. The CSS classes (<i class="with with-home">) are 1em square with vertical-align: -0.125em built in, and with-lg switches to -0.25em for its larger size. with-fw gives a fixed 1.25em width so icons in a menu line up in a neat column. The React, Vue, Svelte, Angular and Solid components and the <with-icon> web component render plain inline SVG, so they drop straight into the flex pattern above.

<button class="with-label">
  <i class="with with-download"></i>
  <span>Download</span>
</button>

Every one of the 1000 icons is drawn on the same 24 x 24 grid with the same padding, in all 34 styles, so once one icon lines up, they all do. Start with the settings icon or the HTML guide, and if you are placing icons with CSS alone, read SVG icons in CSS.

The short version

Flex row, align-items: center, gap, icon in em: that solves nine cases out of ten. In running text, 1em and vertical-align: -0.125em. For the last pixel of polish, text-box: trim-both cap alphabetic on the label, now that every major browser supports it. And never trust a magic top: 2px.

Frequently asked questions

Why is vertical-align: middle not centring my icon?

Because “middle” does not mean the middle of the text. MDN defines it as lining up the icon’s middle with the baseline plus half the x-height, the height of a lower-case x. Next to capitals and numbers, that sits low. Use a flex row with align-items: center, or vertical-align: -0.125em for a 1em icon in running text.

How do I centre an icon and text inside a button?

Make the button a flex row: display: inline-flex; align-items: center; gap: 0.5em;. Give the icon a size in em and flex-shrink: 0 so it never squashes. For a crisper optical centre, add text-box: trim-both cap alphabetic to the label’s span.

What is text-box-trim in CSS?

It removes the empty space a font keeps above and below its letters. text-box: trim-both cap alphabetic trims the top to the height of capital letters and the bottom to the baseline. MDN lists it as Baseline 2026: Chrome and Edge 133, Safari 18.2 and Firefox 154 (August 2026) support it.

Why is there a gap below my SVG icon?

An inline SVG sits on the text baseline like a letter, and the browser keeps room under the baseline for descenders such as g, p and y. Set display: block on the SVG (or vertical-align: middle), or put it in a flex container, and the gap disappears.

What size should an icon be next to text?

Size it in em so it follows the text: 1em matches the font size, and 1.25em suits most buttons. With 16 px text that gives 16 or 20 px icons. Size in pixels only when the icon must stay fixed whatever the text size.

Sources and notes

  1. MDN: text-box (Baseline 2026, newly available since August 2026), checked November 2026
  2. MDN: Firefox 154 release notes (text-box support, 18 August 2026)
  3. Can I use: text-box-trim (Chrome 133, Safari 18.2, Firefox 154), checked November 2026
  4. Chrome for Developers: CSS text-box-trim
  5. MDN: vertical-align (baseline, middle and length values), checked November 2026
  6. Web platform features explorer: the cap and lh units, checked November 2026
  7. Iconify docs: inline icons and vertical-align -0.125em
  8. Stack Overflow: How do you align text with SVG elements? (question 37742099)

Facts about other icon sets were checked against their official sites in November 2026. Libraries change, so check the links above for the latest numbers.

Published November 6, 2026