GithubHelp home page GithubHelp logo

zachleat / fontfaceonload Goto Github PK

View Code? Open in Web Editor NEW
372.0 11.0 37.0 1.57 MB

A simple utility to execute a callback when a webfont loads.

License: MIT License

JavaScript 92.76% HTML 7.24%
font web-fonts css javascript

fontfaceonload's Introduction

fontfaceonload

⚠️⚠️⚠️ This project is archived. Use the CSS Font Loading API directly instead! Check out web-font-loading-recipes for examples.

Usage

Use with any existing @font-face declaration.

@font-face {
    font-family: My Custom Font Family;
    /* src and other properties as normal */
}

Include the library. Call the JavaScript.

FontFaceOnload("My Custom Font Family", {
    success: function() {},
    error: function() {},
    timeout: 5000 // in ms. Optional, default is 10 seconds
});

Use with Content Fonts

To allow the fallback font to be visible while the @font-face is loading, simply use FontFaceOnload like so:

FontFaceOnload("My Custom Font Family", {
    success: function() {
        document.documentElement.className += " my-custom-font-family";
    }
});

and then use the class to scope your usage of the custom font:

body {
    font-family: sans-serif;
}
.my-custom-font-family body {
    font-family: My Custom Font Family, sans-serif;
}

An alternative approach that will also eliminate the FOIT as well as not require you to change your CSS is to use the loadCSS library to load the @font-face with a Data URI source block dynamically. loadCSS is smaller than fontfaceonload. The limitations to this approach include requiring you to manage which format to load (WOFF, WOFF2, TTF) and it will not work as well with icon fonts (since you need to a CSS class to style other sibling elements, like the descriptive text).

Use with Icon Fonts

To hide the fallback font so that weird fallback characters are not visible while the icon font is loading, use FontFaceOnload with the glyphs option like so:

FontFaceOnload("My Custom Font Icon", {
    success: function() {
        document.documentElement.className += " my-custom-font-icon";
    },
    glyphs: "\uE600\uE601\uE602\uE605" // Optional, default is "". Useful for icon fonts: a few code points from your custom font icon.
});

and then use the class to scope your usage of the custom font:

.icon {
    display: none;
}
.my-custom-font-family .icon {
    display: inline-block;
    font-family: My Custom Font Icon, sans-serif;
}

How it Works

This uses the CSS Font Loading Module when available (currently in Chrome 35+ and Opera 22+). When that isn’t available, it uses a very similar approach to the one used in the TypeKit Web Font Loader (which is currently 7.1KB GZIP).

Basically, it creates an element with a font stack including the web font and a default serif/sans-serif typeface. It then uses a test string and measures the dimensions of the element at a certain interval. When the dimensions are different than the default fallback fonts, the font is considered to have loaded successfully.

If you’d like a full polyfill for the CSS Font Loading Module, follow along with Bram Stein’s Font Loader. I believe the specification has changed since he launched this polyfill, but he’s working on an updated version.

Building the project

Run these commands:

  • npm install
  • bower install
  • grunt init
  • grunt as normal.

Configuring Grunt

Rather than one giant Gruntfile.js, this project is using a modular Grunt setup. Each individual grunt configuration option key has its own file located in grunt/config-lib/ (readonly upstream configs, do not modify these directly) or grunt/config/ (project specific configs). You may use the same key in both directories, the objects are smartly combined using Lo-Dash merge.

For concatenation in the previous Gruntfile setup, you’d add another key to the giant object passed into grunt.initConfig like this: grunt.initConfig({ concat: { /* YOUR CONFIG */ } });. In the new configuration, you’ll create a grunt/config/concat.js with module.exports = { /* YOUR CONFIG */ };.

License

MIT License

Alternatives

fontfaceonload's People

Contributors

greenkeeperio-bot avatar xhmikosr avatar zachleat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fontfaceonload's Issues

Allow checking for multiple fonts in parallel

it would be nice if you could optionally pass an array of font names.

the success callback would run when they've all loaded, or the error callback would run as soon as one of them fails.

I will do a PR for this

Loading fails on Firefox if no glyphs option is passed

Happens on latest Firefox and Developer Edition too (Mac OS X) - no issues on Chrome/Safari.
I also have these errors in the CSS:

downloadable font: DSIG: table overruns end of file (<file.otf>)
downloadable font: rejected by sanitizer (<file.otf>)

Loading of a custom font was throwing an error, turns out it's from this line.

I just passed the glyphs from the example, glyphs: "\uE600\uE601\uE602\uE605" and it works.

Seems like unexpected behavior but maybe there's a reason behind this?

IE11 failure

One of my users is on Windows 8.1 using IE11. FontFaceOnload in her browser consistently times out, triggering FontFaceOnload's error() callback.

I haven't been able to reproduce this on my own, but it's reliably happening on her particular machine. Chrome on that machine works for her though.

Problems with load fonts in Firefox

Hi Zach, Thank you for this great plugin.

I've been having an issue with Firefox and it's that I can't manage to load any fonts. I thought it was something on my end but I'm having the same problem using your examples. Is there any way to do this?

Thanks in advance!

Doesn't check loading of several fonts with same name but different font-weights

The demo head demo loads two fonts with the same name but different font-weights.

http://fonts.googleapis.com/css?family=Raleway:600,400 gives this:

@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-weight: 400;
  src: local('Raleway'), url(http://fonts.gstatic.com/s/raleway/v9/cIFypx4yrWPDz3zOxk7hIQLUuEpTyoUstqEm5AMlJo4.woff) format('woff');
}
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-weight: 600;
  src: local('Raleway SemiBold'), local('Raleway-SemiBold'), url(http://fonts.gstatic.com/s/raleway/v9/xkvoNo9fC8O2RDydKj12b73hpw3pgy2gAi-Ip7WPMi0.woff) format('woff');
}

The script doesn't check if both are loaded, confirmed by @zachleat in this tweet.

Fail load detection when url from google includes several weights

I'm trying to apply these scenario from @bevacqua performance workshop:
https://github.com/bevacqua/perfschool/tree/master/exercises/using_a_font_loader

That solution works like a charm... if the url has the defaults weights. I'm trying without success apply the same logic when working with a subset of fonts like these: https://fonts.googleapis.com/css?family=Lato:700,900|Bitter:400italic.

With this script:

  var ffol = global.FontFaceOnload;
  var html = document.documentElement;

  function watch (family) {
    function loaded () {
      html.className += ' ok-' + family.toLowerCase();
    }

    function notLoaded() {
      console.error("Error loading " + family + " font.");
    }

    ffol(family, {
      timeout: 10000,
      success: loaded,
      error: notLoaded 
    });
  }

  watch('Lato');
  watch('Bitter');

the fail callback is always thrown. Am I missing something?

Font-Face Load Detection not Working in Firefox

Font-Face Load Detection is not working in Firefox (tested in 41.0.1 and 41.0.2), i.e. always ending up in the error function (fontfaceonload version 0.1.6). The same test works on Chrome and IE. I used the following to test:

HTML

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-eqiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="font-face.css">
  <title>Font Face Test</title>
</head>
<body>
  <p>Normal Text</p>
  <div class="load-font">
    <p>Impact Text</p>
  </div>
<script src="fontfaceonload.js"></script>
<script src="font-face-test.js"></script>
</body>

font-face.css

@font-face {
  font-family: 'impactreg';
  font-style: normal;
  font-weight: 400;
  src:  url('/font/impactreg.eot'); /* IE9 Compat Modes */
  src:  local('impactreg'),
        url('/font/impactreg.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
        url('/font/impactreg.woff') format('woff'),
        url('/font/impactreg.ttf') format('truetype');
}

.load-font {
  font-family: 'impactreg', sans-serif;
}

font-face-test.js

FontFaceOnload('impactreg', {
  success: function() {
    alert('Success!');
  },
  error: function() {
    alert('Error!');
  }
});

The font used in the example can be found here: http://fontsforweb.com/font/generatezip/?id=7349

Load multiple fonts simultaneously

What is the best way to implement fontfaceonload for more than one font?

Using for example google font:

    WebFontConfig = {google: { families: [ 'Jura','Open+Sans' ] }};
    (function() {
        var wf = document.createElement('script');
        wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
          '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
    })();

Breaks in SSR

The library breaks when used in a server-side rendered app. The build breaks with ReferenceError: window is not defined error, and a check typeof window === 'undefined' && ... unfortunately doesn't help.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.