Search code examples
cssgoogle-chromefontssafari

Chrome/MacOS and Firefox/MacOS are able to render a string with glyphs from two fonts, but Chrome/iOS and Safari/Any are not


I want to declare a font-family property naming two fonts and have any glyphs not present in the first be rendered in the second. This works great in Chrome and Firefox on MacOS, but Safari/MacOS and both Chrome and Safari on iOS will only respect the first-listed font.

Minimal repro case:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Example</title>
        <meta charset="utf-8">
        <link href="https://fonts.googleapis.com/css2?family=Redacted+Script&family=Noto+Emoji&display=swap" rel="stylesheet">
        <style>
            p {
                font-family: "Redacted Script", "Noto Emoji", sans-serif;
                font-weight: 400;
                font-style: normal;
            }
        </style>
    </head>
    <body>
        <p>Hello 😊</p>
    </body>
</html>

The 😊 smiley here should render in Noto Emoji, not whatever the browser's default emoji font is. That's what Chrome/MacOS and Firefox/MacOS do.

This is what I expect:

Rendering in Firefox

But in the bad cases I get this instead (the smiley is coming from Apple Emoji font, I think):

Rendering in Safari

What am I doing wrong? Or is this mixing of fonts in a single string not supported in all browsers? Is there a workaround?


Solution

  • In Safari it works if you change the order of families.

    font-family: "Noto Emoji", "Redacted Script", cursive;
    

    In fact, listing the emoji font first makes a lot more sense, because an emoji font is not going to attempt to render anything which is not an emoji, whereas a regular font is more likely to try to fill in any gaps in its repertoire by borrowing from other fonts.

    A snippet to demonstrate – run this in Safari.

    @import url('https://fonts.googleapis.com/css2?family=Noto+Emoji:wght@300..700&family=Redacted+Script&display=swap');
    
    body {
      font-size: 2em;
    }
    
    .p1 {
      font-family: "Redacted Script", "Noto Emoji", cursive;
    }
    
    .p2 {
      font-family: "Noto Emoji", "Redacted Script", cursive;
    }
    <p class="p1">hello 😀😍👹🤡🤢</p>
    
    <p class="p2">hello 😀😍👹🤡🤢</p>