fontaine

repository·main·Indexed 24 days ago

https://github.com/unjs/fontaine

A tool for automatic font fallback generation based on font metrics to reduce Cumulative Layout Shift (CLS). It creates crafted @font-face rules that match the visual dimensions of custom fonts using local system fonts. It includes integrations for Vite, Webpack (Next.js, Gatsby), and Docusaurus, and provides utilities like FontaineTransform, resolveCategoryFallbacks, and getMetricsForFamily.

Tokens
10.5K
Snippets
25
Records
57
Agent score
84%

What's inside fontaine

  1. Use Category-Aware Fallbacks in fontaine

    main

    When fallbacks is set to an empty object {}, fontaine automatically selects fallback fonts based on the font's category (serif, sans-serif, monospace, etc.). You can also customize these category presets using categoryFallbacks.

    Default Category Fallbacks

    • sans-serif: BlinkMacSystemFont, Segoe UI, Helvetica Neue, Arial, Noto Sans
    • serif: Times New Roman, Georgia, Noto Serif
    • monospace: Courier New, Roboto Mono, Noto Sans Mono
    • display & handwriting: Same as sans-serif

    Configuration Example

    const options = {
      // Enable automatic category-based fallbacks
      fallbacks: {},
    
      // Customize specific categories
      categoryFallbacks: {
        'serif': ['Georgia', 'Times New Roman'],
        'sans-serif': ['Arial', 'Helvetica'],
      }
    }
    const options = {
      fallbacks: {},
      categoryFallbacks: {
        'serif': ['Georgia', 'Times New Roman'],
        'sans-serif': ['Arial', 'Helvetica'],
      }
    }
  2. Understand fontaine fallback priority

    main

    fontaine determines which fallback fonts to use based on the following priority order:

    1. Array format: If fallbacks is an array (e.g., ['Arial']), it applies to all font families.
    2. Per-family override: If fallbacks is an object with specific keys (e.g., { Poppins: ['Arial'] }), those specific families use the provided fallback.
    3. Category-based: If no specific family is matched, fontaine uses the appropriate category preset (serif, sans-serif, etc.).
    4. Global default: If no category can be detected, it defaults to the sans-serif preset.
  3. How category-aware fallbacks work in fontless

    main

    Fontless uses category-aware fallback presets (shared with fontaine) to reduce Cumulative Layout Shift (CLS). When a font is loaded, fontless provides optimized system font stacks based on the generic font family used.

    Default presets include:

    • sans-serif: BlinkMacSystemFont, Segoe UI, Helvetica Neue, Arial, Noto Sans
    • serif: Times New Roman, Georgia, Noto Serif
    • monospace: Courier New, Roboto Mono, Noto Sans Mono
    • cursive: Handwriting category fallbacks
    • fantasy: Display category fallbacks
    • system-ui, ui-serif, ui-sans-serif, ui-monospace: Mapped to corresponding category presets

    You can override these by providing a custom mapping in defaults.fallbacks.

  4. How fontless works

    main

    fontless is a zero-runtime CSS solution that optimizes font loading through the following lifecycle:

    1. Scanning: It scans your CSS files for font-family declarations.
    2. Resolution: It resolves the requested fonts through configured providers (Google, Bunny, npm, etc.).
    3. Generation: It generates optimized @font-face declarations.
    4. Metric Optimization: It adds fallback fonts with correct metric overrides (using metrics from fontaine) to reduce Cumulative Layout Shift (CLS).
    5. Asset Management: It automatically downloads and manages the font assets.

    Because it operates during the build process (via Vite), there is no JavaScript overhead at runtime.

  5. Add fontless to Vite configuration

    main

    To use fontless, add the fontless() plugin to your vite.config.js or vite.config.ts file. Once configured, fontless will automatically scan your CSS for font-family declarations and optimize them.

    // vite.config.js / vite.config.ts
    import { defineConfig } from 'vite'
    import { fontless } from 'fontless'
    
    export default defineConfig({
      plugins: [
        // ... other plugins
        fontless()
      ],
    })
  6. Setup fontless in Vite

    main

    To use fontless, add it as a plugin to your vite.config.js or vite.config.ts file. Once configured, fontless will automatically scan your CSS for font-family declarations and optimize them.

    // vite.config.js / vite.config.ts
    import { defineConfig } from 'vite'
    import { fontless } from 'fontless'
    
    export default defineConfig({
      plugins: [
        // ... other plugins
        fontless()
      ],
    })