Thanks to visit codestin.com
Credit goes to github.com

Skip to content

RoelN/FontJit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 

Repository files navigation

FontJit

A little helper for just-in-time font loading! Load fonts when they enter the viewport, or when they almost enter the viewport, or immediately.

It's tiny, just 743 bytes minified and Brotli zipped!

Quick Start

1. Set up FontJit in JavaScript

Load FontJit, and call it. By default it'll automatically find all FontJit elements on the page, but you can also pass a CSS selector string, a DOM element, or a Nodelist to target specific elements. By default fonts will be loaded when they're in the viewport on pageload, and when they enter the viewport when the user scrolls.

<script type="module">
	import { fontJit } from './fontjit.js'
	fontJit() // Or target specific elements: fontJit('.boing')
</script>

2. Prepare your HTML elements

Add data attributes with the font URL and font name to the element.

<div class="boing" data-fontjit-url="boing.woff2" data-fontjit-name="Boing">
	This is the Boing font!
</div>

ℹ️ Make sure you sanitize the font name to avoid icky browser bugs. Remove spaces, quotes, plus signs etc. Read more about this issue in this Mastodon post.

3. Apply the font

The font will now be loaded when this element enters the viewport. Remember, fontJit only takes care of loading the font—you'll have to actually apply it yourself.

<style>
	.boing {
		font-family: Boing;
	}
</style>

Loading Options

By default, fontJit lazy-loads fonts when they enter the viewport. You can also have them load when they almost enter the viewport by passing an IntersectionObserver config, or load them immediately:

// Load font for elements with class "boing" when they're in the viewport
fontJit('.boing')

// Load font for elements with class "boing" when they're almost in the viewport
fontJit('.boing', { rootMargin: '400px 0px' })

// Load font for elements with class "boing" immediately, regardless
// of whether they are (almost) in the viewport
fontJit('.boing', { immediate: true })

Loading States

While loading, the data-fontjit-status attribute will be added and updated. This lets you keep track of the four loading states:

unloaded = not yet started
loading = font is loading
loaded = font successfully loaded
error = loading failed

You can use these in CSS, for example to hide the text until the font has been loaded, or show an error when the font fails to load.

/* Apply the font and hide it until it has loaded */
.boing {
	font-family: Boing;
	opacity: 0;
}

/* Font has loaded, show the element */
.boing[data-fontjit-status='loaded'] {
	opacity: 1;
}

/* Font couldn't load, show error state */
.boing[data-fontjit-status='error'] {
	opacity: 1;
	outline: 10px solid red;
}

Using JavaScript

You can also interact with FontJit in JavaScript by using promises:

import { fontJit, LoadingState } from './fontjit.js'

// Using async/await
await fontJit('.boing')
console.log('All fonts loaded!')

// Using .then()
fontJit('.boing').then(() => {
	console.log('All fonts loaded!')
}).catch((error) => {
	console.error('Some fonts failed to load:', error)
})

// Load multiple fonts and wait for all
await Promise.all([
	fontJit('.boing'),
	fontJit('.prose'),
	fontJit('.code-example')
])

// Alternartively, check loading state using constants
const element = document.querySelector('.boing')
if (element.getAttribute('data-fontjit-status') === LoadingState.LOADED) {
	// Do something with the loaded font!
}

The promise works with both immediate and lazy loading modes. For lazy loading, the promise resolves as fonts enter the viewport and complete loading.

Font Descriptors

You can pass optional FontFace descriptors using the data-fontjit-descriptors attribute with a JSON string:

<div
	class="boing"
	data-fontjit-url="boing.woff2"
	data-fontjit-name="Boing"
	data-fontjit-descriptors='{"weight":"100 900","stretch":"75% 125%"}'
>
	Hello World
</div>

Performance Tips

You can load fonts in the initial viewport immediately, and preload nearby fonts after page has fully loaded:

// Load fonts in viewport...
fontJit('.boing')

// ...and after page loads, preload fonts just below the fold
window.addEventListener('load', () => {
	fontJit('.boing', { rootMargin: '400px 0px' })
})

Gotchas

If you update an element after its font has been loaded, for example by updating its data-fontjit-url, you'll need to manually reset the data-fontjit-status attribute before calling fontJit() again. This might be automated soon.

Credits

Computered by Roel Nieskens!