The icon in a ToolbarButton sits noticeably above the button's vertical center. It is invisible on a bare toolbar and obvious the moment a hover background appears behind it.
Cause
ToolbarButton renders the icon as a plain span:
<span {...pt?.icon} data-cratis-part='icon'>
<IconDisplay icon={resolvedIcon} className='cratis:text-lg' />
</span>
inside a button that is cratis:flex cratis:items-center cratis:justify-center. Nothing in Toolbar.css styles that span, so it stays display: block and the icon inside it is positioned by baseline alignment against the span's line-box strut rather than being centered. The text variant does not have this problem, because .toolbar-button__text carries line-height: 1; the icon span was never given the equivalent.
Two things then combine:
- The strut comes from the consuming application's inherited
line-height. With a root line-height: 24px, the span is a 24px line box whose baseline sits ~25px down, and the 18px glyph hangs its box from that baseline instead of from the button's center.
- An icon font has essentially no descender. Measured on PrimeIcons
pi-sitemap and pi-cog at 18px, the ink runs from 15.75px above the baseline to roughly the baseline itself. So centering the glyph's box is not the same as centering its ink.
Measured in a 40px (cratis:w-10 cratis:h-10) button, the ink center lands about 3px above the button center:
| icon |
ink offset from button center |
pi-sitemap |
-3.32px |
pi-cog |
-2.87px |
Suggested fix
Give the icon span the same treatment the text span already gets — take it out of baseline alignment:
.toolbar-button [data-cratis-part='icon'] {
display: flex;
align-items: center;
justify-content: center;
line-height: 1;
}
With that applied the same measurements become -0.32px and +0.13px — centered to within a third of a pixel. It applies equally to the SVG icons (react-icons and similar) that some toolbars pass instead of a PrimeIcons class, and it makes the button independent of whatever line-height the host application happens to set.
Verified against @cratis/components 4.13.1; the same markup and CSS are present in 4.2.2, so it is not a recent regression.
The icon in a
ToolbarButtonsits noticeably above the button's vertical center. It is invisible on a bare toolbar and obvious the moment a hover background appears behind it.Cause
ToolbarButtonrenders the icon as a plain span:inside a button that is
cratis:flex cratis:items-center cratis:justify-center. Nothing inToolbar.cssstyles that span, so it staysdisplay: blockand the icon inside it is positioned by baseline alignment against the span's line-box strut rather than being centered. The text variant does not have this problem, because.toolbar-button__textcarriesline-height: 1; the icon span was never given the equivalent.Two things then combine:
line-height. With a rootline-height: 24px, the span is a 24px line box whose baseline sits ~25px down, and the 18px glyph hangs its box from that baseline instead of from the button's center.pi-sitemapandpi-cogat 18px, the ink runs from 15.75px above the baseline to roughly the baseline itself. So centering the glyph's box is not the same as centering its ink.Measured in a 40px (
cratis:w-10 cratis:h-10) button, the ink center lands about 3px above the button center:pi-sitemappi-cogSuggested fix
Give the icon span the same treatment the text span already gets — take it out of baseline alignment:
With that applied the same measurements become -0.32px and +0.13px — centered to within a third of a pixel. It applies equally to the SVG icons (react-icons and similar) that some toolbars pass instead of a PrimeIcons class, and it makes the button independent of whatever
line-heightthe host application happens to set.Verified against
@cratis/components4.13.1; the same markup and CSS are present in 4.2.2, so it is not a recent regression.