A configurable standalone webfont type tester for displaying and manipulating sample text in the browser.

View on Github

Fontsampler takes care of, webfont (pre) loading, detecting woff(2) support and providing an interface to manipulate type tester.

Fontsampler aims to be a barebones solution for developers to customize, and you can use your own styles, eventlisteners and layouts to create a fully customized experience. This is what a full-feature Fontsampler looks like with (almost) no styling:

This is a Fontsampler! Type here to test this this webfont…



Fontsampler.js can be configured either through DOM nodes and attributes or entirely from Javascript.

For all setups include the fontsampler.js file from the dist folder:

<script src="node_modules/fontsampler-js/dist/fontsampler.js"></script>

You can configure Fontsamplers via an options object or by instantiating on a DOM node that already contains some of the controls. Even mixing the two approaches is possible.

Bare minimum configuration

Transform a DOM node into a simple typetester with one webfont…

…fonts passed in as object:

<div id="demo">Demo minimal</div> <script> var fonts = [ { name: "Font name", files: ["path/to/font-name.woff", "path/to/font-name.woff2"] } ] new Fontsampler(document.getElementById("demo"), fonts).init() </script>

…or fonts defined as data attributes; for a single-font Fontsampler you can use:

<div id="demo" data-name="Your Font name" data-woff="path/to/font-name.woff" data-woff2="path/to/font-name.woff2" >Demo minimal</div> <script> new Fontsampler(document.getElementById("demo")).init() </script>
Demo minimal — just load a font and transform this into an editable textarea

…or to load several fonts use a stringfied JSON structured like the above fonts object:

<div id="demo" data-fonts='[{"name": "Your font name", "files": ["…/font.woff", "…/font.woff2"], {…}]' >Demo minimal</div> <script> new Fontsampler(document.getElementById("demo")).init() </script>
Demo minimal — just load a font and transform this into an editable textarea

Demo JS configuration

To configure a Fontsampler via Javascript and supply several fonts, you can pass in a fonts Array and options Object:

<div id="demo"></div> <script> var options = { initialText: "Hello Tester!", // This sets the UI element’s order and groupings order: ["tester", ["fontsize", "lineheight", "fontfamily"]], // This defines UI element options that differ from the defaults ui: { fontsize: { init: 36, step: 1, unit: "px", }, lineheight: { min: 60, max: 120, }, // Instead of defining the specifics of a ui element, // simply setting in to true will make it // get rendered in the UI with defaults fontfamily: true } } var fonts = [ { name: "Alegreya Regular", files: [ "./fonts/alegreya/alegreya-v12-latin-regular.woff", "./fonts/alegreya/alegreya-v12-latin-regular.woff2" ] }, … ] Fontsampler(document.getElementById("demo"), fonts, options).init() </script>
Demo JS configuration

Demo DOM configuration

It is also possible to initiate a Fontsampler on a DOM node that already has the controls in the required Fontsampler format. This allows you to implement more complex and customized layouts and still use the functionalities of Fontsampler.

To link Fontsampler to existing DOM nodes, the UI elements need to have specific data-fsjs attributes to be recognized. Missing attributes (such as min, max, step, data-unit on sliders) will be automatically added, but you can also use them to configure the Fontsampler.

To see all properties and the generated attributes it is advisable to check the DOM output of a javascript-instantiated Fontsampler, then use similar DOM nodes (but in any arbitrary order and additional markup) to create your fully customized layouts.

… For the type tester element: <div data-fsjs="tester">Type here to test</div> … For fontsize, linheight, letterspacing: <label for="fontsize">…<span class="fontsampler-label-value">12</span>px</label> <input data-fsjs="fontsize" min="8" max="96" step="1" data-init="14" data-unit="px"> … For the fontfamily dropdown <select data-fsjs="fontfamily"> <option value="My font name" data-fontname="My font name" data-woff="path/to/font-file.woff" data-woff2="path/to/font-file.woff2">My font name</option> … </select> …
Demo from DOM & no skin applied


Fontsampler is intended to provide a barebones functionality and UI. To use and customize Fontsampler to use a skin, include the fontsampler-skin.js javascript and fontsampler-skin.css stylesheet files.

<!-- barebones functionality --> <script src="../dist/fontsampler.js"></script> <!-- optional skin files --> <script src="../dist/fontsampler-skin.js"></script> <link rel="stylesheet" href="../dist/fontsampler-skin.css">

See the Skin demo page for more info.

By default you can use Fontsampler also without a skin and that will give you a completely unstyled UI for you to implement your own layout and visual styles.

Even when you use the included skin Javascript and Stylesheet Fontsampler tries to minimally interfere with existing page styles and inherits styling like font size, line height and colors from it’s surrounding containers:

This demo wrapper uses different font styling, and the Fontsampler inherits most of it:

The UI inherts styling from the page or container.


The webfonts to render in the Fontsampler can be passed in either as Array in the Fontsampler() method or via data-woff and data-woff2 attributes.

When both woff and woff2 files are supplied Fontsampler will test browser support and load the best supported option — it is recommended to supply both files, but at the very least the woff format.

Fonts as Array:

// Supply fonts, even a single font, as Objects in an Array // The order of the Array elements is the fonts’ order in the dropdown select var fonts = [ // Each font one Object inside the Array, even a single font! { // Provide a nice display name for the font name: "My font name", // Provide at the very least a woff file to render. When passing in // a woff and a woff2 file Fontsampler will determine the best font // to use // If you pass in more than one woff file or more than one woff2 file // only the first will be used files: [ "path/to/font-file.woff", "path/to/font-file.woff2" ] }, { … } ] new Fontsampler(document.getElementById("demo"), fonts).init()

Fonts on the root element:

<div id="demo" data-woff="path/to/font-name.woff" data-woff2="path/to/font-name.woff2" data-fontname="My font name"> Demo minimal </div> … new Fontsampler(document.getElementById("demo")).init()


You can pass in an options object that will overwrite the below defaults. If you omit some of the options, defaults will be used.

The order option can be used to define the UI elements’ structure. Use nested Arrays to group elements into the same wrapper element.

Here is a full list of all default options:

// Leave empty to set no text or inherit the DOM node’s current text initialText: "", // Set false to force single line input multiline: true, // Set true to preloaded all fonts in the Fontsampler in the background // instead of only loading them when activated lazyload: false, // Set true to generate any UI elements in the order attribute that are // not explicitly defined in the ui attribute or present in the DOM generate: false, classes: { // CSS classes for various elements and states // The root element on which Fontsampler was initiated rootClass: "fontsamplerjs", // Root element class after the Fontsampler has been initialized initClass: "fsjs-initialized", // Root element class while loading a webfont file loadingClass: "fsjs-loading", // Root element class while preloading (e.g. ´lazyload´ is true and // not all fonts have preloaded yet) preloadingClass: "fsjs-preloading", // Any Array wrapper in the ´order´ attribute will generate a wrapper // with this class wrapperClass: "fsjs-wrapper", // The wrapper of each UI element around label and UI // For each UI element this base also is used to create a class: // fsjs-block-element (e.g. elements are "fontsize", "lineheight", etc.) // For each UI element this base also is used to create a UI type class: // fsjs-block-type-type (e.g. types are "slider", "checkboxes", "buttongroup", "textarea") blockClass: "fsjs-block", // Every ´ui´ element receives this class elementClass: "fsjs-element", // Classes for the label of various UI elements labelClass: "fsjs-label", labelTextClass: "fsjs-label-text", labelValueClass: "fsjs-label-value", lableUnitClass: "fsjs-label-unit", // All multi-option buttons buttonClass: "fsjs-button", // The selected button’s class in a buttongroup buttonSelectedClass: "fsjs-button-selected", } // Define the order and presence of UI elements // Use nested Arrays to group elements into the same wrapper order: [ ["fontsize", "lineheight", "letterspacing"], ["fontfamily", "language"], ["alignment", "direction", "opentype"], "tester" ], // Definitions for each UI element // Any nested element can also be only partially defined, which will make it inherit // the rest of its configuration from the defaults ui: { // The actual input element for testing the webfonts tester: { // Set’s the contenteditable attribute editable: true, // The tester has it’s label disabled by default label: false }, // The font-size slider fontsize: { // Any CSS unit is valid (e.g. px, em, %, etc.) unit: "px", init: 18, min: 12, max: 96, step: 1, // The text label to render for the element, set to false to disabled // rendering a label label: "Size" }, // The line-height slider lineheight: { unit: "%", init: 100, min: 60, max: 120, step: 5, label: "Leading" }, // The letter-spacing slider letterspacing: { unit: "em", init: 0, min: -1, max: 1, step: 0.05, label: "Letterspacing" }, // The drop-down for picking fonts fontfamily: { label: "Font", // Supply the exact name of the Font (fontname, not file!) to be selected // and loaded first, by default the first font passed in init: "" }, // The set of buttons controlling alignment alignment: { // Choices can an Array of strings used both as value and display label // or the strings are separated by | to use as value|Display label choices: ["left|Left", "center|Centered", "right|Right"], // Has to be one of the above choices init: "left", label: "Alignment" }, // The script direction, options like alignment direction: { choices: ["ltr|Left to right", "rtl|Right to left"], init: "ltr", label: "Direction" }, // The language dropdown setting the html lang attribute, thus triggering // opentype locl features language: { choices: ["enGB|English", "deDe|Deutsch", "nlNL|Dutch"], init: "enGb", label: "Language" }, // A set of checkboxes; NOTE: No validation whatsoever if the font // supports these opentype features opentype: { choices: ["liga|Ligatures", "frac|Fractions"], init: ["liga"], label: "Opentype features" } }


You can use some default CSS classes to style Fontsampler or pass in custom classes to use instead.

<style type="text/css"> /* Fontsampler provides classes for when a font is loading (e.g. to display a spinner or fade out the text tester while the font is loading) */ .fontsamplerjs.loading {…} /* If you use the lazyload option you can use this class to change appearance while some fonts are still loading in the background */ .fontsamplerjs.preloading {…} /* The Fontsampler has initialized */ .fontsamplerjs.fontsampler-initiallized {…} /* When Fontsampler groups items together as per the definitions (nested arrays) in the options attribute, those wrappers will have this class */ .fsjs-wrapper {…} /* Any UI element (controls, tester input) */ .fsjs-block {…} /* All UI elements have their key as class */ .fsjs-block-fontsize, .fsjs-block-tester, … {…} /* All UI types have a class, e.g. slider, dropdown, buttongroup, checkboxes, textarea */ .fsjs-block-type-buttongroup {…} /* UI elements with labels have markup for the label and it’s content */ .fsjs-block-fontsize [data-fsjs-for=fontsize] {…} .fsjs-block-fontsize [data-fsjs-for=fontsize] .fsjs-label-text {…} .fsjs-block-fontsize [data-fsjs-for=fontsize] .fsjs-label-value {…} .fsjs-block-fontsize [data-fsjs-for=fontsize] .fsjs-label-unit {…} </style>

You can overwrite many classes by passing in an options object. Note that the default skin relies on many of the default classes.

<script> var options = { … classes: { rootClass: "fontsamplerjs", wrapperClass: "fsjs-wrapper", loadingClass: "fsjs-loading", preloadingClass: "fsjs-preloading", … } … } </script>


By default Fontsamplers only load the fonts on display as needed, always initiating with the first font. If a Fontsampler has more than one fonts, the other fonts are only loaded when a user selects them.


Setting the lazyload option to true Fontsampler will initiate with the first font and then preload any other fonts in the Fontsampler in the background. If the font is switched before all fonts have loaded the requested font will be the next to be loaded and displayed.

<script> var options = { lazyload: true } var fonts = { … } new Fontsampler(document.getElementById("demo"), fonts, options).init() </script>

See the lazyloading example page (use your browser network throttling and network tool to see what’s going on).

Variable font support

Fontsampler supports Variable Fonts and has a built in ui element for displaying any number of custom axes defined in the options.

See the variable font example page for examples.