Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike: Explore better font compilation #149

Closed
jonathanbobel opened this issue Apr 22, 2024 · 1 comment · Fixed by #184
Closed

Spike: Explore better font compilation #149

jonathanbobel opened this issue Apr 22, 2024 · 1 comment · Fixed by #184
Assignees
Labels
research Research, typically UX or a spike

Comments

@jonathanbobel
Copy link
Contributor

jonathanbobel commented Apr 22, 2024

Reach out to @ethangardner and discuss other ways to include Poppins to avoid the flash of unstyled font (FOUF)

@jonadecker jonadecker added the research Research, typically UX or a spike label Jun 13, 2024
@natashapl natashapl linked a pull request Jun 25, 2024 that will close this issue
@natashapl
Copy link
Contributor

After doing some research and reaching out to @ethangardner, below are my findings on ways to deal with the flash of unstyled font and which option I chose.

Articles and Resources

Best practices for fonts
CSS size-adjust for @font-face

Methods to Handle Flash of Unstyled Fonts (FOUF) for Self-Hosted Fonts

Method 1 - Using only HTML and CSS

  • This method is adopted from here.
  • At the top of your HTML in the section before declaring a stylesheet, add:
<style>html{visibility: hidden;opacity:0;}</style>

At the end of your last .css file, add:

html {
    visibility: visible;
    opacity: 1;
}

Method 2: Font Face Observer

  • A JavaScript library that monitors the loading status of fonts.
  • It allows you to apply styles only when the custom font is fully loaded.
  • Usage involves including the library in your project and writing a script to check font loading status.

Example:

Javascript:

var font = new FontFaceObserver('CustomFont');
font.load().then(function () {
    document.documentElement.classList.add('custom-font-loaded');
});

CSS:

.custom-font-loaded body {
    font-family: 'CustomFont', sans-serif;
}

Method 3: CSS Font Loading API

  • A native JavaScript API for detecting font load status.
  • Provides more control over font loading without additional libraries.

Example:

Javascript:

document.fonts.load('1em CustomFont').then(function () {
    document.documentElement.classList.add('custom-font-loaded');
});

Method 4: FOUT with a Class (FOUC)

  • Using a CSS class to apply the custom font only when it is loaded.
  • Initially, the page loads with a fallback font, and once the custom font is loaded, a class is added to switch fonts.

Example:

HTML:

<body class="font-loading">

CSS:

body {
    font-family: 'FallbackFont', sans-serif;
}

.font-loaded body {
    font-family: 'CustomFont', sans-serif;
}

Javascript:

var font = new FontFaceObserver('CustomFont');
font.load().then(function () {
    document.body.classList.remove('font-loading');
    document.body.classList.add('font-loaded');
});

Method 5: Font Display Property

  • A CSS property to control the behavior of font rendering during the loading period.
  • Provides options like auto, block, swap, fallback, and optional.

Example:

CSS:

@font-face {
    font-family: 'CustomFont';
    src: url('path/to/font.woff2') format('woff2');
    font-display: swap; /* Ensures text is immediately rendered in a fallback font until the custom font loads */
}

Method 6: Preloading Fonts

  • Preload the font to ensure it is prioritized by the browser.
  • Reduces the time fonts take to load, thus minimizing FOUF.

Example:

HTML:

<link rel="preload" href="path/to/font.woff2" as="font" type="font/woff2" crossorigin="anonymous">

Method 7: Critical CSS and Inlining

  • Inline critical CSS, including font-face declarations, directly into the HTML to reduce the render-blocking period.
  • Ensures the font-face rule is available immediately.

Example:

HTML:

<style>
@font-face {
    font-family: 'CustomFont';
    src: url('path/to/font.woff2') format('woff2');
    font-display: swap;
}
body {
    font-family: 'CustomFont', sans-serif;
}
</style>

Conclusion

Each of the methods listed above can be effective, but I chose to use method 1 due to its simplicity and lack of reliance on JavaScript or APIs. Additionally, it avoids overloading browser resources, a risk associated with excessive preloading, and it doesn't require overriding the USWDS font-face styles. Should method 1 prove inadequate in the future, there are six alternative methods available for testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
research Research, typically UX or a spike
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants