Last active
February 24, 2016 15:35
-
-
Save chadsmith/413d9f04c31d4640fc63 to your computer and use it in GitHub Desktop.
IcoMoon in Favicons
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
var FavicoMoon = function(icon, color, bg) { | |
'use strict'; | |
var | |
container = document.createElement('div'), | |
span = document.createElement('span'), | |
body = document.body, | |
content, | |
canvas = document.createElement('canvas'), | |
getContext = function(w) { | |
canvas.width = canvas.height = w; | |
context = canvas.getContext('2d'); | |
context.font = 'normal normal normal 32px/' + w + 'px icomoon'; | |
context.textBaseline = 'middle'; | |
return context; | |
}, | |
context = getContext(32), | |
iconWidth, | |
link = document.createElement('link'); | |
if(!window.getComputedStyle || !canvas.toDataURL || !document.querySelectorAll) | |
return; | |
container.style.display = 'none'; | |
span.className = 'icon-' + icon.replace(/^icon-/, ''); | |
container.appendChild(span); | |
body.appendChild(container); | |
content = window.getComputedStyle(span, ':before').getPropertyValue('content').replace(/'/g, ''); | |
body.removeChild(container); | |
iconWidth = context.measureText(content).width; | |
if(iconWidth > canvas.width) | |
context = getContext(iconWidth); | |
if(bg) { | |
context.rect(0, 0, canvas.width, canvas.height); | |
context.fillStyle = bg; | |
context.fill(); | |
} | |
context.fillStyle = color; | |
context.fillText(content, (canvas.width - iconWidth) / 2, canvas.height / 2); | |
link.setAttribute('rel', 'icon'); | |
link.setAttribute('type', 'image/png'); | |
link.setAttribute('href', canvas.toDataURL('image/png')); | |
for(var icons = document.querySelectorAll('link[rel*=icon]'), i = 0, l = icons.length; i < l; i++) | |
icons[i].parentNode.removeChild(icons[i]); | |
document.getElementsByTagName('head')[0].appendChild(link); | |
}; | |
if(typeof define !== 'undefined' && define.amd) | |
define([], function() { | |
return FavicoMoon; | |
}); | |
else if(typeof module !== 'undefined' && module.exports) | |
module.exports = FavicoMoon; | |
else | |
this.FavicoMoon = FavicoMoon; | |
})(); |
I've found the best experience for introducing favicons into an app is to not put a LINK in the head. Based on what I've seen browsers will look for named files in the root of an app, cache and use those automatically without being told to do so in the HEAD. An interesting result of this behavior is that the HTML document does not force the client to download the icon with each page visit, saving an HTTP request on each page turn and also preventing the favicon from flickering when changing pages (mostly obvious in single-page apps, where page turns happen in milliseconds).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Requires IcoMoon.
Example:
FavicoMoon('icon-html5', '#000');
Also try FaviconAwesome.js and FavEmoji.js.