Skip to content

Instantly share code, notes, and snippets.

Last active January 15, 2022 17:39
Show Gist options
  • Save letorbi/5177771 to your computer and use it in GitHub Desktop.
Save letorbi/5177771 to your computer and use it in GitHub Desktop.
This code enforces font-smothing for web fonts even if it's not enabled in the system settings. More info:
// Font Smoothie copyright 2013,14,15 Torben Haase <>
// Source-URL <>
// Font Smoothie is free software: you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any
// later version.
// Font Smoothie is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details. You should have received a copy of the GNU Lesser General Public
// License along with Font Smoothie. If not, see <>.
(function() { 'use strict';
function apply() {
// NOTE Circles through all CSS rules of a sheet and fix them if
// necassary.
function traverseSheet(sheet) {
if (sheet.cssRules === null)
return console.warn("Fontsmoothie warning: Browser blocks access to CSS rules in "+sheet.href);
var href = sheet.href||location.href;
href = new RegExp(href.substring(0, href.lastIndexOf("/"))
.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "g");
for (var rule, j = 0; rule = sheet.cssRules[j]; j++) {
// NOTE Only affect rules that have a src value (AFAIK
// this is only true for CSSFontFaceRule objects).
if ( && {
// NOTE Create a new rule where SVG is the preferred
// source format and delete the old rule. =, ".")
.replace(/([^;]*?),\s*(url\(\S*? format\(["']?svg["']?\))([\s,]*[^;]+|)/, '$2, $1$3');
// NOTE Opera needs the rule to be deleted and inserted again
// (in that order) to apply it to the document.
if (window.opera) {
var text = rule.cssText;
sheet.insertRule(text, j);
rule.styleSheet && traverseSheet(rule.styleSheet);
try {
// NOTE Safari needs the canvas to be part of the DOM tree to
// return correct alpha values.
var head = document.getElementsByTagName('HEAD')[0];
var canvas = head.appendChild(document.createElement('CANVAS'));
var context = canvas.getContext('2d');
context.textBaseline = 'top';
context.font = '32px Arial';
context.fillText('O', 0, 0);
// NOTE We won't check the alpha values of all canvas pixels,
// but only the one at position (5,8). If font-smoothing is
// off we loop through all CSS rules and fix them.
for (var sheet, i = 0; (context.getImageData(5, 8, 1, 1).data[3] == 255) && (sheet = document.styleSheets[i]); i++)
sheet && traverseSheet(sheet);
catch (e) {
// NOTE Ignore any errors that might occur.
throw e; // DEBUG
// NOTE Run Font Smoothie only if the system is Windows XP
if (navigator.userAgent.toLowerCase().indexOf('windows nt 5.1') > -1) {
if (document.readyState == 'complete') {
else {
var f = window.onload;
window.onload = window.onload ? function(evt){f(evt);apply();} : apply;
// Font Smoothie copyright 2013,14,15 Torben Haase <>
// Source-URL <>
(function(){function a(){function e(a){if(null===a.cssRules)return console.warn("Fontsmoothie warning: Browser blocks access to CSS rules in "+a.href);for(var b=a.href||location.href,b=new RegExp(b.substring(0,b.lastIndexOf("/")).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),"g"),c,f=0;c=a.cssRules[f];f++){if(,".").replace(/([^;]*?),\s*(url\(\S*? format\(["']?svg["']?\))([\s,]*[^;]+|)/,"$2, $1$3"),window.opera)){var d=c.cssText;a.deleteRule(f); a.insertRule(d,f)}c.styleSheet&&e(c.styleSheet)}}try{var a=document.getElementsByTagName("HEAD")[0],h=a.appendChild(document.createElement("CANVAS")),b=h.getContext("2d");b.textBaseline="top";b.font="32px Arial";b.fillText("O",0,0);for(var d,k=0;255==b.getImageData(5,8,1,1).data[3]&&(d=document.styleSheets[k]);k++)d&&e(d);a.removeChild(h)}catch(g){throw g;}}if(-1<navigator.userAgent.toLowerCase().indexOf("windows nt 5.1"))if("complete"==document.readyState)a();else{var g=window.onload;window.onload= window.onload?function(e){g(e);a()}:a}})();
Copy link

IE8 gives a Javascript error: 'document.head' is null or not an object.

Copy link

skill83 commented Jan 20, 2015

u can use document.getElementsByTagName('head')[0]

Copy link

fab1an commented Nov 20, 2015

Can you upload the script to CDNs like

Copy link

las3r commented Sep 11, 2016

I'd love a bower version for this as well if you'd like to do the honours... ;)

Copy link

Yes, a bower or npm version would be awesome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment