Skip to content

Instantly share code, notes, and snippets.

@cferdinandi
Last active September 16, 2017 10:39
Show Gist options
  • Save cferdinandi/6269067 to your computer and use it in GitHub Desktop.
Save cferdinandi/6269067 to your computer and use it in GitHub Desktop.
A simple feature test to detect @font-face support. Include the file in your <head> element. Adds a `.font-face` class to the <html> element when `@font-face` and the `:before` psuedo selector are supported. Via Paul Irish, Diego Perini, and Mat “Wilto” Marquis.
/**
* Test for @font-face support
* @author Filament Group
* @link https://github.com/filamentgroup/face-off
* @param {Element} win
* @param {Null} undefined
* @return {Boolean}
*/
var isFontFaceSupported = (function( win, undefined ) {
'use strict';
var doc = document,
head = doc.head || doc.getElementsByTagName( "head" )[ 0 ] || doc.documentElement,
style = doc.createElement( "style" ),
rule = "@font-face { font-family: 'webfont'; src: 'https://'; }",
supportFontFace = false,
blacklist = (function() {
var ua = win.navigator.userAgent.toLowerCase(),
wkvers = ua.match( /applewebkit\/([0-9]+)/gi ) && parseFloat( RegExp.$1 ),
webos = ua.match( /w(eb)?osbrowser/gi ),
wppre8 = ua.indexOf( "windows phone" ) > -1 && win.navigator.userAgent.match( /IEMobile\/([0-9])+/ ) && parseFloat( RegExp.$1 ) >= 9,
oldandroid = wkvers < 533 && ua.indexOf( "Android 2.1" ) > -1;
return webos || oldandroid || wppre8;
}()),
sheet;
style.type = "text/css";
head.insertBefore( style, head.firstChild );
sheet = style.sheet || style.styleSheet;
if ( !!sheet && !blacklist ) {
try {
sheet.insertRule( rule, 0 );
supportFontFace = sheet.cssRules[ 0 ].cssText && ( /webfont/i ).test( sheet.cssRules[ 0 ].cssText );
sheet.deleteRule( sheet.cssRules.length - 1 );
} catch( e ) { }
}
return supportFontFace;
}( this ));
/**
* Test for pseudo-selector support
* @author Paul Irish
* @link https://gist.github.com/paulirish/441842
* @param {String} selector Pseudo-selector to test
* @return {Boolean}
*/
var selectorSupported = function (selector) {
'use strict';
var support, link, sheet, doc = document,
root = doc.documentElement,
head = root.getElementsByTagName('head')[0],
impl = doc.implementation || {
hasFeature: function() {
return false;
}
},
link = doc.createElement("style");
link.type = 'text/css';
(head || root).insertBefore(link, (head || root).firstChild);
sheet = link.sheet || link.styleSheet;
if (!(sheet && selector)) return false;
support = impl.hasFeature('CSS2', '') ?
function(selector) {
try {
sheet.insertRule(selector + '{ }', 0);
sheet.deleteRule(sheet.cssRules.length - 1);
} catch (e) {
return false;
}
return true;
} : function(selector) {
sheet.cssText = selector + ' { }';
return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) && sheet.cssText.indexOf(selector) === 0;
};
return support(selector);
};
// If @font-face and pseudo selectors are supported, add '.font-face' class to <html> element
if (isFontFaceSupported && selectorSupported(':before')) {
document.documentElement.className += (document.documentElement.className ? ' ' : '') + 'font-face';
}
@wisniewskit
Copy link

Note that for Firefox for Android support, you'll probably want to change this line to do a null check as well:

oldandroid = wkvers !== null && wkvers < 533 && ua.indexOf( "Android 2.1" ) > -1;

(This was recently discovered on webcompat.com).

@karlcow
Copy link

karlcow commented Mar 7, 2017

@wisniewskit
Copy link

Also note that Moderinzr has a new version of the blacklisting function which they don't seem to have rolled out yet (thanks for pointing that out, karlcow!).

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