Skip to content
forked from unjs/fontaine

Automatic font fallback based on font metrics

License

Notifications You must be signed in to change notification settings

atinux/fontaine

 
 

Repository files navigation

fontaine

npm version npm downloads Github Actions Codecov

Automatic font fallback based on font metrics

Features

⚠️ fontaine is under active development. ⚠️

  • 💪 Reduces CLS by using local font fallbacks with crafted font metrics.
  • ✨ Generates font metrics and overrides automatically.
  • ⚡️ Pure CSS, zero runtime overhead.

On the playground project, enabling/disabling fontaine makes the following difference rendering /, with no customisation required:

Before After
CLS 0.24 0.054
Performance 92 100

Installation

With pnpm

pnpm add -D fontaine

Or, with npm

npm install -D fontaine

Or, with yarn

yarn add -D fontaine

Usage

import { FontaineTransform } from 'fontaine'

const options = {
  fallbacks: ['BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica Neue', 'Arial', 'Noto Sans'],
  // You may need to resolve assets like `/fonts/Roboto.woff2` to a particular directory
  resolvePath: (id) => 'file:https:///path/to/public/dir' + id,
}

// Vite
export default {
  plugins: [FontaineTransform.vite(options)]
}

// Next.js
export default {
  webpack(config) {
    config.plugins = config.plugins || []
    config.plugins.push(FontaineTransform.webpack(options))
    return config
  },
}

Note If you are using Nuxt, check out nuxt-font-metrics which uses fontaine under the hood.

How it works

fontaine will scan your @font-face rules and generate fallback rules with the correct metrics. For example:

@font-face {
  font-family: 'Roboto';
  font-display: swap;
  src: url('/fonts/Roboto.woff2') format('woff2'), url('/fonts/Roboto.woff')
      format('woff');
  font-weight: 700;
}
/* This will be generated. */
@font-face {
  font-family: 'Roboto override';
  src: local('BlinkMacSystemFont'), local('Segoe UI'), local('Roboto'), local(
      'Helvetica Neue'
    ), local('Arial'), local('Noto Sans');
  ascent-override: 92.7734375%;
  descent-override: 24.4140625%;
  line-gap-override: 0%;
}

Then, whenever you use font-family: 'Roboto', fontaine will add the override to the font-family:

:root {
  font-family: 'Roboto';
  /* This becomes */
  font-family: 'Roboto', 'Roboto override';
}

💻 Development

  • Clone this repository
  • Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev; launch a vite server using source code with pnpm demo:dev

Credits

This would not have been possible without:

License

Made with ❤️

Published under MIT License.

About

Automatic font fallback based on font metrics

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 81.8%
  • JavaScript 7.7%
  • HTML 7.6%
  • CSS 2.5%
  • Shell 0.4%