Optical Alignment
Two objects can share the same center and still look misaligned.
CSS aligns boxes. People see the shapes inside those boxes. Optical alignment is the small correction you make when those two things disagree.
Every SVG box is centered at 0px, but the shapes still feel uneven.
All three SVG boxes start in the mathematical center, but each shape feels off in a different way.
The play triangle feels too far left, so it moves right. The star feels low, so it moves up. The download icon also moves up, but by a smaller amount.
These corrections are for these icons at this size. A smaller version may need a smaller shift.
Inside a button
A button component can give every icon the same size, gap, and padding. Those defaults create a consistent layout, but they still align the SVG boxes rather than the shapes inside them.
The Button gives every icon the same size, gap, and padding, but it only centers their SVG boxes.
One shared icon style can look right with some glyphs and off with others. Keep the Button rules shared, then put the small correction on the icon that needs it. Do not move every SVG in the component by the same amount.
The correction can also change with the rendered icon size. The larger examples above use whole pixels. The smaller button icons use smaller values.
Equal boxes, different weight
Matching width and height is a good starting point, but different shapes fill their boxes in different ways. A square fills more space than a circle. A triangle fills less space than both.
All three boxes are 28px, but the filled shapes do not look equally large.
This is why icons in the same row do not always need the same numeric size. Adjust them as a group until their weight feels even. Check them at the size people will actually see.
Align the visible edge
Text has the same problem. A quote mark can sit on the layout edge while the first letter looks indented. Hanging the quote in the margin lines up the letters instead.
The quote begins on the guide, which pushes the first word inward.
This works well for large quotes and display text. CSS has a
hanging-punctuation property, but support is still limited. A small negative
text-indent is a practical fallback for a known quote style.
How to check it
- Start with Flexbox, Grid, or normal text alignment.
- Add a guide through the center or along the edge.
- Look at the result at 100% zoom and at its final size.
- Move the shape one pixel at a time.
- Keep the correction in the icon or text style that needs it.
Optical alignment is a finishing step. It should correct a visible problem, not replace a solid layout.
Usage
<Button>
<PlayIcon className="translate-x-px" />
Play
</Button>
<Button>
<StarIcon className="-translate-y-[0.5px]" />
Favorite
</Button>
<Button>
<DownloadIcon className="-translate-y-[0.5px]" />
Save
</Button>
<blockquote className="[text-indent:-0.42em]">
“Good alignment should disappear.”
</blockquote>.button-icon[data-icon="play"] {
transform: translateX(1px);
}
.button-icon[data-icon="star"],
.button-icon[data-icon="download"] {
transform: translateY(-0.5px);
}
.pull-quote {
text-indent: -0.42em;
}Keep each correction small and local. The value belongs to that shape at that size, not to every icon or quote in the product.