DEV Community

toolzip
toolzip

Posted on Originally published at toolzip.app

How to Load and Preview Custom Fonts in the Browser Without CSS

Loading a custom font file (TTF, OTF, WOFF, WOFF2) in the browser without a stylesheet sounds like it shouldn't work. But the FontFace API makes it possible — and it's surprisingly clean.

The FontFace API

Most developers know @font-face in CSS. Fewer know you can do the same thing entirely in JavaScript:

async function loadFontFromFile(file) {
  const fontName = `custom-${Date.now()}`;
  const arrayBuffer = await file.arrayBuffer();
  const font = new FontFace(fontName, arrayBuffer);
  await font.load();
  document.fonts.add(font);
  return fontName;
}
Enter fullscreen mode Exit fullscreen mode

Once added to document.fonts, you can use the font name anywhere in CSS or Canvas.

Supporting Multiple Formats

WOFF and WOFF2 files are compressed web fonts. TTF and OTF are the raw formats. The browser handles all of them through FontFace — you don't need to specify the format, unlike in CSS @font-face.

const SUPPORTED = ['ttf', 'otf', 'woff', 'woff2'];

function getExtension(file) {
  return file.name.split('.').pop().toLowerCase();
}

function isValidFont(file) {
  return SUPPORTED.includes(getExtension(file));
}
Enter fullscreen mode Exit fullscreen mode

Rendering Weight Variations

Not all fonts include all weights. When you set font-weight: 900 and the font only has regular, the browser synthesizes bold — which usually looks bad.

To show only what's actually available, I check which weights render differently:

async function detectAvailableWeights(fontName) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  const testChar = 'A';
  const available = [];

  for (const weight of [100, 200, 300, 400, 500, 600, 700, 800, 900]) {
    ctx.font = `${weight} 48px "${fontName}"`;
    const metrics = ctx.measureText(testChar);
    // Compare width — different weights render at different widths
    available.push({ weight, width: metrics.width });
  }
  return available;
}
Enter fullscreen mode Exit fullscreen mode

Letter Spacing and Line Height on Canvas

CSS letter-spacing and line-height don't apply to Canvas — you have to implement them manually.

For letter spacing, measure and reposition each character:

function drawTextWithSpacing(ctx, text, x, y, spacing) {
  let curX = x;
  for (const char of text) {
    ctx.fillText(char, curX, y);
    curX += ctx.measureText(char).width + spacing;
  }
}
Enter fullscreen mode Exit fullscreen mode

The Comparison View

The most useful feature turned out to be rendering all nine weights side by side. Users can instantly see which weights their font actually supports.


Try it at toolzip.app/tools/font-preview — drag in any TTF, OTF, WOFF, or WOFF2 file.

Top comments (0)