
Browser Font Rendering Inconsistencies - jermier
https://blog.stephaniestimac.com/posts/2020/06/browser-fonts/
======
crazygringo
Summary: if you're specifying a bold font style (700) but not supplying a bold
version of the font (only 400 and 600), Safari creates a "faux bold" on its
own, while other browsers fall back to the next-closest weight (600).

Neither behavior seems more obviously correct, since you're asking for
something that doesn't exist.

Moral of the story: whenever you're using webfonts that come in a variety of
weights, make sure you're loading font files in the weights you're intending
to use! Otherwise behavior may vary.

(And in contrast to multiple comments here, this has _nothing_ to do with
macOS using different/darker types of antialiasing than other operating
systems. That is not what this article is about.)

------
threepio
The problem arises when you're invoking a style (like `h1` or `h2`) that by
default requests a bold weight, but the `font-face` declaration only supplies
a WOFF declared "font-weight: regular". In that case, the browser will try to
synthesize a bold style by "smearing" the regular.

One fix for this is to set heading tags to "font-weight: normal".

Another fix is to supply two `font-face` declarations for the same WOFF file,
covering both regular and bold, so that when the browser asks for the bold
version, it just gets the same thing.

(Strictly speaking, I would classify this as user error, not a browser flaw,
though it's an easy mistake to make)

~~~
ryanwhitney
People hit this so much, it's maddening.

In this case, they're using Google Fonts, which already does the latter:
[https://fonts.googleapis.com/css?family=Poppins:400,600](https://fonts.googleapis.com/css?family=Poppins:400,600)

Testing this on my own, I'm not seeing a difference between
safari/chrome/firefox on macos. If there's only 400 and 600 weights present,
they use the 600 for bold elements. If there's a 700, they use that. You only
see faux bolding when there's nothing provided in the 600–900 range.

I think the difference here might be moreso about browser font handling on
windows? Though I'm still not sure how they got to the bold result at the top
of the screenshot…I wouldn't expect safari to apply a faux bold when the 600
weight is there, and that sure looks like the proper 700 which apparently
wasn't being called.

Sidenote: I didn't know about the font-synthesis property until this. Looks
like it is intended to prevent any sort of faux bolding or faux italicizing
from happening. That's cool.

~~~
andrewmcwatters
Perhaps it would have been better then if the web standards never allowed for
defining usage of the nearest available weight. It seems to certainly have
created enough confusion in the microcosm of just this thread.

------
tinus_hn
Why would it be a bug if two browsers don’t render a h1 element the same, if
you don’t specify how you want it to look?

~~~
DavidVoid
That definitely makes it sound more like undefined behavior than a bug.

~~~
saagarjha
Implementation defined :P

------
kanobo
Maybe related — there was a Chrome bug regression that was recently fixed that
rendered the thickness of font-sizes above a certain threshold incorrectly,
large bold text wouldn't be bolded -
[https://bugs.chromium.org/p/chromium/issues/detail?id=105765...](https://bugs.chromium.org/p/chromium/issues/detail?id=1057654)

------
tomc1985
Damn it folks, stop trying to make your designs pixel perfect!

There will _always_ be font rendering inconsistencies. It's how the web works.

> The cross-platform problem is a harder one to solve as you can't control how
> the operating system handles font rendering.

Bingo.

So stop trying! Embrace flexible designs and differences in rendering

~~~
kevingadd
I think the problem described in the article is a bit beyond 'pixel perfect',
though. the font weight is DRAMATICALLY different. Text being way too thin or
too thick can have an impact on readability.

~~~
fomine3
A similar problem occurs with the valuable Japanese font "Yu Gothic", which is
available on both Windows and Mac by default (both availability is rare).

(Not surprisingly no English info available)
[https://neos21.hatenablog.com/entry/2019/01/05/000629](https://neos21.hatenablog.com/entry/2019/01/05/000629)

------
aahhahahaaa
These rendering differences also impact vertical alignment with specific
fonts, which will absolutely drive you mad if you're trying to troubleshoot.

Take a look at Github's redesign in Firefox. Button and icon alignment are
generally off by 1-2px everywhere because of it. Guessing they're just living
with it because Firefox is down in the single-digit percentages of
browsershare these days.

~~~
andrewmcwatters
It's important to keep in mind that the bitmap output of various font
rasterizers isn't universally the same. If you're designing websites expecting
text nodes to have the exact same dimensions, you're making a critical
mistake.

~~~
aahhahahaaa
Yes different fonts have different dimensions, but I'm talking about the same
font across different browsers. The issue is that Firefox and Webkit render
the baseline of some fonts with a 1-2px difference.

It's impossible to vertically align Helvetica consistently in Firefox and
Chrome without some browser-specific adjustments, but Arial works fine.

~~~
andrewmcwatters
I am, too. The same font rendered by Core Text, FreeType, and
Direct2D/DirectWrite will not have the exact same dimensions every time
despite coming from the same exact file.

Say I render a font with no anti-aliasing on an embedded device, because it's
marginally more expensive to do so. If I did anti-alias it, you have to
account for possibly growing the bitmap size to do so. If I did, am I no
longer compliant with web standards? No, because the web standards don't
specify dimension requirements for text nodes from source fonts.

Further, there are multiple different types of ways to anti-alias. Should the
web standards dictate how?

~~~
aahhahahaaa
Sorry, I misread.

The annoying aspect to me isn't the change in dimensions, but the inaccurate
baselines. If we could reliably align text based on its baseline it wouldn't
be an issue. "align-items: baseline" would be brilliant if it actually worked
cross-browser.

It's pretty telling that Github doesn't even bother to solve the issue in
their redesign, they've seemed to write off Firefox text alignment
idiosyncrasies.

~~~
andrewmcwatters
It would have been great had I known details like this much earlier in my
career, but when people talked then about "pixel perfect" designs, I don't
think most people understood then what sacrifices you have to make to do so!
Box size calculations should be the same, I think, surely. But text
specifically has no such requirements for equal precision.

In truth, that type of work would require you to know the output sizes across
every supported browser.

------
SambalOelek
Is there something happening in the font world I don't know about? I just
spent the past day struggling with fixing my fonts on Arch Linux. I finally
just deleted all xorg packages that give bitmap fonts becuase I couldn't get
any of them to load right in Firefox. This was after a font package totally
broke my installation a week ago.

------
shash7
Tangential but I made getsnapfont.com to test how fonts look like on various
OS/browsers.

Unfortunately most designers I've worked with don't acknowledge these
inconsistencies when designing. For them, their 2x retina mac represents the
vast majority of users.

------
andrewmcwatters
draw_down was downvoted for this, but I agree. If you're going to write an
article on this, you _should_ know, or at least try to.

This would have been more educational if perhaps instead of the author
guessing at what behavior should occur, they read the standards[1][2][3] and
told us what should occur. There are even definitions in the specifications
for how to lookup the nearest available weight.[1][4]

It seems like the author doesn't understand what liberties you have as an
implementor. For instance:

> In the computed tab, Edge, Chrome and Firefox are all showing font-weight:
> bold to be computed to a font-weight of 700, whereas Safari's computed font-
> weight doesn't have a numerical value, it just remains computed as "bold."
> But this still doesn't explain much.

Well, OK, but the _author_ didn't explain much. This little tidbit isn't
meaningful, it's just an observation without an explanation as to why. But a
cursory read shows the specifications clearly state that bold is the same as
700.

> Wait.

> I add ,700 to the end of this string: Poppins:400,600. My heading re-renders
> and now matches Safari.

Well, yeah.

From Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification, "15.6
Font boldness: the 'font-weight' property"

"If the desired weight is less than 400, weights below the desired weight are
checked in descending order followed by weights above the desired weight in
ascending order until a match is found. If the desired weight is greater than
500, weights above desired weight are checked in ascending order followed by
weights below the desired weight in descending order until a match is found.
If the desired weight is 400, 500 is checked first and then the rule for
desired weights less than 400 is used. If the desired weight is 500, 400 is
checked first and then the rule for desired weights less than 400 is used."[1]

From CSS Fonts Module Level 4, "5.2. Matching font styles"

"If the desired weight is inclusively between 400 and 500, weights greater
than or equal to the target weight are checked in ascending order until 500 is
hit and checked, followed by weights less than the target weight in descending
order, followed by weights greater than 500, until a match is found.

If the desired weight is less than 400, weights less than or equal to the
desired weight are checked in descending order followed by weights above the
desired weight in ascending order until a match is found.

If the desired weight is greater than 500, weights greater than or equal to
the desired weight are checked in ascending order followed by weights below
the desired weight in descending order until a match is found."[4]

> So what do I do to render headings consistently across browsers and
> platforms?

Read the specifications. If you're arguing that Core Text doesn't draw like
FreeType or Direct2D/DirectWrite, well, sure, but the specifications don't
force you to output particular bitmaps.

[1]: [https://www.w3.org/TR/CSS2/fonts.html#propdef-font-
weight](https://www.w3.org/TR/CSS2/fonts.html#propdef-font-weight) [2]:
[https://drafts.csswg.org/css-fonts-3/#font-weight-
prop](https://drafts.csswg.org/css-fonts-3/#font-weight-prop) [3]:
[https://drafts.csswg.org/css-fonts-4/#font-weight-
prop](https://drafts.csswg.org/css-fonts-4/#font-weight-prop) [4]:
[https://drafts.csswg.org/css-fonts-4/#font-matching-
algorith...](https://drafts.csswg.org/css-fonts-4/#font-matching-algorithm)

------
elondaits
It's a webkit thing.

Try

-webkit-font-smoothing: antialiased

and you'll get the version with less weight, while 'subpixel-antialiased' is
the heavier one. This weight difference is more noticeable in white text
against dark backgrounds.

Photoshop offers several options on how to render text that show different
"weight" in a similar way... they're called "Crisp", "Strong", "Smooth", etc.
In particular there's a "Mac LCD" one which I think matches this "issue" seen
in Safari.

~~~
andrewmcwatters
As far as I know, -webkit-font-smoothing doesn't change weight, it changes
rasterization. What you describe in Photoshop also isn't weight, it's
rasterization.[1]

See my post below. This is developer error from not understanding the font-
weight implementation. The real answer is browser implementors use an
algorithm to determine the nearest available weight. Succeeded standards,
depending on how up-to-date the browser is in compliance, use slightly
differing algorithms.

As a designer, you must specify exact weights, and understand what the keyword
values translate to in the CSS standards. All other behavior is fallback.

[1]: [https://www.thegraphicmac.com/improve-text-appearance-
with-p...](https://www.thegraphicmac.com/improve-text-appearance-with-
photoshops-anti-aliasing/)

~~~
BearOso
Yes, it changes rasterization. It’s because MacOS has a legacy of dilating the
pixel outlines when subpixel antialiasing is enabled.

When subpixel antialiasing first appeared on OS X, the FIR filter affected the
gamma curve, making the font seem too light or thin. Correcting gamma the
right way was expensive at the time, so they changed the rasterizer to dilate
the outlines, increasing the contrast of the text.

At that same time, the *nix APIs like Xft just cranked up the coefficients of
the filter so that the sum was ~40% higher than it was supposed to be, which
also worked. I think that was a better method than sabotaging the outline
shape.

~~~
andrewmcwatters
That's fascinating, I wasn't aware of such details!

------
dilandau
In which a novice web struggles aimlessly before giving up?

Compelling stuff.

------
kome
Do websites need to look exactly the same in every browser?
[http://dowebsitesneedtolookexactlythesameineverybrowser.com/](http://dowebsitesneedtolookexactlythesameineverybrowser.com/)

------
jibbers
Could this be related to macOS font smoothing? System Preferences > General >
uncheck "Use font smoothing when available"

~~~
wysiwtf
Yes, if you remove "use font smoothing" the font weight gets lighter and
closer to other OSes rendering. Big Sur gets rid of this option, but I don't
know if the underlying option is still on or not.

------
DiabloD3
This is a well known Mac thing, and its one of the top 5 reasons why I moved
away from OSX and refuse to support Apple users.

Safari enforces the OSX "thick antialiasing", causing really thick fonts. This
also causes really thick fonts, unreasonably so, in normal non-web apps.

The reverse, unfortunately, is true: a lot of web developers worship at the
altar of Apple, and have screwed up perfectly good websites by making their
fonts too thin: on _every other OS, with every other browser_ thin fonts
_break_.

If you are a web developer, for the love of all that is holy, test your
website on a normal Windows machine, with a normal 100% DPI conventional
monitor, in both Chrome and Firefox. If it misrenders, this is on _you_ , and
you will look positively incompetent to the 95% of users visiting your
website.

Apple users are a vocal minority, they do not represent the silent majority
who will easily click away from your website because its unreadable.

The fix on OSX, if you're still willing to use that, is `defaults -currentHost
write -globalDomain AppleFontSmoothing -int 1`, and if you have a non-Retina
display, combined with `defaults write -g CGFontRenderingFontSmoothingDisabled
-bool NO` to turn sub-pixel font rendering back on.

Defaults are 2 and YES, respectively. AppleFontSmoothing accepts values 0
through 3. 0 is off, 1 is light, 2 is medium, 3 is french roast columbian
bold.

~~~
reaperducer
_This is a well known Mac thing, and its one of the top 5 reasons why I moved
away from OSX and refuse to support Apple users_

Seriously? You changed operating environments because of font weights? That
seems a little over-the-top.

~~~
solarkraft
Only on Safari, even.

Yet this comment over all brings up a good point (re: downvotes).

