skip to Main Content

I have three of fonts I may use together on a single line. (Emojis I wrap in <span> and set the emoji font-family since Inter has its own characters for some glyphs like heart.) I’ve found the ascent/descent (ascent: 2728, descent: 680) for Inter and set ascent-override and descent-override for all fonts so they match Inter. That way if the three fonts are used on the same line their vertical layout is consistent and background-colors (from highlights) are consistent.

@font-face {
  font-family: 'Fira Code';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/firacode/v22/uU9NCBsR6Z2vfE9aq3bh3dSDqFGedA.woff2) format('woff2');
  ascent-override: 100%;
  descent-override: 19.953%;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(https://fonts.gstatic.com/s/inter/v13/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2) format('woff2');
  ascent-override: 100%;
  descent-override: 19.953%;
}

@font-face {
  font-family: Emoji;
  src:
    local("Apple Color Emoji"),
    local("Segoe UI Emoji"),
    local("NotoColorEmoji"),
    local("Noto Color Emoji"),
    local("Segoe UI Symbol"),
    local("Android Emoji"),
    local("EmojiSymbols");
  ascent-override: 100%;
  descent-override: 19.953%;
}

p {
  font-size: 100px;
}

.inter {
  font-family: Inter;
  background-color: tomato;
}

.fira-code {
  font-family: Fira Code;
  background-color: tomato;
}

.emoji {
  font-family: Emoji;
  background-color: tomato;
}
<p>
  <span class="emoji">πŸ‘‹</span><span class="inter"> foo</span><span class="fira-code">bar</span>
</p>

But Safari doesn’t support ascent-override and descent-override (tracking bug). This is causing some unfortunate layout bugs in Safari.

Chrome:

Chrome screenshot

Safari:

Safari screenshot

Is there a way for me to workaround this lack of ascent-override/descent-override support?

For instance, by creating my own font files that set the right ascent and descent values so they’re consistent even in Safari. I know I can find Apple’s color emoji file at /System/Library/Fonts/Apple Color Emoji.ttc on MacOS but don’t know how to modify that file or Fira Code to get the results I want. I also don’t know enough about the font file format to know if a modification like this is possible.

Coincidentally, it looks like Apple Color Emoji and Fira Code have the same ascent/descent proportions so to simplify the problem I could just get a modified Inter file.

2

Answers


  1. One approach is to use relative positioning to adjust the vertical alignment of elements within the line. We can calculate the height of the ascenders and descenders of each font and then use CSS to position them accordingly.

    Here’s how you can implement this solution:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Font Alignment</title>
    <style>
      p {
        font-size: 100px;
        position: relative; * Ensure relative positioning for child elements */
        line-height: 1; /* Reset line height */
      }
    
      .inter, .fira-code, .emoji {
        position: relative;
        display: inline-block; /* Ensure inline block for proper positioning */
      }
    
      .inter::before, .fira-code::before, .emoji::before {
        content: "";
        display: block;
        height: 0;
      }
    
      .inter::before {
        margin-top: -6px; /* Adjust based on ascent value of Inter */
      }
    
      .fira-code::before {
        margin-top: -6px; /* Adjust based on ascent value of Fira Code */
      }
    
      .emoji::before {
        margin-top: -6px; /* Adjust based on ascent value of Emoji */
      }
    </style>
    </head>
    <body>
      <p>
        <span class="emoji">πŸ‘‹</span><span class="inter"> foo</span><span class="fira-code">bar</span>
      </p>
    </body>
    </html>

    Adjust the margin-top values ​​for each font to match the spacing, spacing, and ascending values ​​of the emoji.

    This solution should provide consistent vertical alignment across different fonts without relying on browser-specific features like ascent-override and descent-override. It is more robust and easier to maintain than modifying font files directly.

    Login or Signup to reply.
  2. The easiest solution was to set for span { display: inline-block; vertical-align: middle; line-height: 1.4; }:

    @font-face {
      font-family: 'Fira Code';
      font-style: normal;
      font-weight: 300 700;
      font-display: swap;
      src: url(https://fonts.gstatic.com/s/firacode/v22/uU9NCBsR6Z2vfE9aq3bh3dSDqFGedA.woff2) format('woff2');
    }
    
    @font-face {
      font-family: 'Inter';
      font-style: normal;
      font-weight: 100 900;
      font-display: swap;
      src: url(https://fonts.gstatic.com/s/inter/v13/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2) format('woff2');
    }
    
    @font-face {
      font-family: Emoji;
      src:
        local("Apple Color Emoji"),
        local("Segoe UI Emoji"),
        local("NotoColorEmoji"),
        local("Noto Color Emoji"),
        local("Segoe UI Symbol"),
        local("Android Emoji"),
        local("EmojiSymbols");
    }
    
    p {
      font-size: 100px;
    }
    
    .inter {
      font-family: Inter;
      background-color: tomato;
      @supports{ascent-override: 100%}
    }
    
    .fira-code {
      font-family: Fira Code;
      background-color: tomato;
    }
    
    .emoji {
      font-family: Emoji;
      background-color: tomato;
    }
    
    p span{
      line-height: inherit;
    }
    
    p span{
      line-height: 1.4;
      display: inline-block;
      vertical-align: middle;
    }
    <p>
      <span class="emoji">πŸ‘‹</span><span class="inter"> foo</span><span class="fira-code">bar</span><span> fb</span>
    </p>

    But, if you want it to work only on Safari, then you have to check ascent-override support with js, something like this:

    const div = document.createElement('div');
    div.style.fontVariationSettings = '"XXXX" 1';
    if(div.style.fontVariationSettings !== '"XXXX" 1'){
      document.querySelector('p').style.cssText = `
        --display: inline-block;
        --vertical-align: middle;
        --line-height: 1.4;
      `;
    }
    @font-face {
      font-family: 'Fira Code';
      font-style: normal;
      font-weight: 300 700;
      font-display: swap;
      src: url(https://fonts.gstatic.com/s/firacode/v22/uU9NCBsR6Z2vfE9aq3bh3dSDqFGedA.woff2) format('woff2');
      ascent-override: 100%;
      descent-override: 19.953%;
    }
    
    @font-face {
      font-family: 'Inter';
      font-style: normal;
      font-weight: 100 900;
      font-display: swap;
      src: url(https://fonts.gstatic.com/s/inter/v13/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7W0Q5nw.woff2) format('woff2');
      ascent-override: 100%;
      descent-override: 19.953%;
    }
    
    @font-face {
      font-family: Emoji;
      src:
        local("Apple Color Emoji"),
        local("Segoe UI Emoji"),
        local("NotoColorEmoji"),
        local("Noto Color Emoji"),
        local("Segoe UI Symbol"),
        local("Android Emoji"),
        local("EmojiSymbols");
      ascent-override: 100%;
      descent-override: 19.953%;
    }
    
    p {
      font-size: 100px;
    }
    
    .inter {
      font-family: Inter;
      background-color: tomato;
      @supports{ascent-override: 100%}
    }
    
    .fira-code {
      font-family: Fira Code;
      background-color: tomato;
    }
    
    .emoji {
      font-family: Emoji;
      background-color: tomato;
    }
    
    p span {
      line-height: inherit;
      display: var(--display);
      vertical-align: var(--vertical-align);
    }
    <p>
      <span class="emoji">πŸ‘‹</span><span class="inter"> foo</span><span class="fira-code">bar</span><span> fb</span>
    </p>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search