Icon Fonts and how to Create a Pixelfree Audio-Player
I’ve been looking for an excuse to use web-font based icons for some time now, since I’m not a prolific Photoshop user I’d been sneaking them into apps I’d been making for a while. I found out that by combining font icons with Bootstrap style gradient filled buttons I didn’t have to touch a graphics package at all. I instantly felt a little better about my work-flow.
The principle behind creating web-font based icons (or glyphs) is to select or — better — create a font of your choice and use this instead of gifs or a pngs as icons for your web site or app. This affords you various advantages, not least of which is the fabled device independence.
Device independence had been a fairly hot-topic for a while now but really reached melting point with the release of range of devices sporting retina screens. Suddenly there was a rush to address the perceived ugliness of non-retina designed sites on these new fancy screens and the web echoed with the aesthetically sensistive screaming “Blind my eyes – I can see the pixels!”
People rushed to address the issue without actually have to blind themselves but the method that stood out in it’s simplicity was to use icon fonts.
Of course there are drawbacks to using icon fonts. Although the idea is simple there is some work to do to make sure they work properly and you should also take account of the fact that they are effectively mono-chromatic and that changing an icon can involve regenerating the whole font, you should also be careful to work-around semantic incorrectness and accessibility issues.
But the advantages of this technique are very tangible – it boils down to flexibility:
- You can change colours and size easily, suddenly these elements are really part of your markup and can be controlled by CSS
- They can be used in almost any HTML element including form fields
- As fonts are effectively vectors they will scale to any size and so any device beautifully and forever
So let’s run through a classic application of icon fonts – an audio-player’s interface.
On the average player we have a play/pause button and let’s throw in a mute button as an example of a more detailed icon.
You can create your own fonts but let’s grab one that’s already been made.
To do this you can head on over to fontello.com and select a suitable font and select suitable play, pause, mute and unmute icons. I used the Entypo font and chose the following:
Download and Fontello gives you just the fonts you need and some hand example HTML and CSS. So let’s look at the CSS:
@charset "UTF-8";
@font-face {
font-family: 'entypo';
src: url("font/entypo.eot");
src: url("font/entypo.eot?#iefix") format('embedded-opentype'),
url("font/entypo.woff") format('woff'),
url("font/entypo.ttf") format('truetype'),
url("font/entypo.svg#entypo") format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"]:before,
[class*=" icon-"]:before {
font-family: 'entypo';
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: 0.2em;
text-align: center;
opacity: 0.7;
/* Uncomment for 3D effect */
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
/* fix buttons height */
line-height: 1em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
}
.icon-pause:before { content: '\2389'; } /* '⎉' */
.icon-play:before { content: '\25b6'; } /* '▶' */
.icon-volume-off:before { content: '🔇'; } /* '\1f507' */
.icon-volume-up:before { content: '🔊'; } /* '\1f50a' */
Marked up a simple player interface may look like this:
<div class="player"> <a href="#" id="btn-play" class="icon-play"></a> <a style="display:none" href="#" id="btn-pause" class="icon-pause"></a> <a href="#" id="btn-mute" class="icon-mute"></a> <a style="display:none" href="#" id="btn-unmute" class="icon-unmute"></a> </div>
and if you’ve linked to everyting properly you should see something like this:
You can add this bit of CSS to tweak sizes and colours.
a.icon-play,
a.icon-pause {
font-size: 3em;
}
a.icon-mute,
a.icon-unmute {
font-size: 1.2em;
/* to move things closer together */
/* probably not required if with a font with less white space */
margin-left: -20px;
}
.player a {
color: #000;
text-decoration: none;
}
Now try zooming in using ctrl + or cmd + on your browser to simulate a higher pixel density.
I also created a version that uses images (pngs) and you can see the difference.
While it’s true that you could create two different images and serve up the correct image depending on pixel density. I like this solution better because as vectors, even zoomed the buttons look good and with pixel densities set to increase you never quite know how many you need to make.
File size is comparable but wait there’s something not quite right. Try clearing your cache and you should see a slight delay as the font is loaded for the first time. This may or may not be acceptable to you – if it isn’t there’s a workaround.
The trick to making your fonts load instantly is to base64 encode your fonts and embed them in a CSS file. Be aware that base64 encoding can add between 10% and 20% to file size but again I consider this a worthwhile trade off. In the case of the woff it goes from 4.7kB to 6.2kB.
So now you can get rid of your font directories if so required and change the lines in the CSS so that for example
url("font/entypo.woff") format('woff')
becomes something like
url("data:font/woff;base64,d09GRgABAAAAABIwABAAAAAAHBwAAQAAAAAAAA ....
<lots more chars here> ... WwBI2xBQBEAAAA") format('woff');
and so on for all your other font formats.
Which is pretty ugly, but if you put the font stuff in a separate CSS file you shouldn’t have to look it again, once you have defined it.
So not only have a device independent user interface we have a snappy one.
Since we’ve got this far we may aswell hook up the controls to an audio element. It’s actually quite straightforward.
First let’s use good old HTML to define the player and its sources.
<audio id="my-audio"> <source src="http://jPlayer.org/audio/mp3/Miaow-07-Bubble.mp3"> <source src="http://jPlayer.org/audio/ogg/Miaow-07-Bubble.ogg"> </audio>
Defining two sources will give you maximum browser coverage without having to resort to Flash.
Then all we need to do is hook our buttons up to the audio tag.
In your JS:
var myAudio = document.getElementById('my-audio'),
playBtn = document.getElementById('btn-play'),
pauseBtn = document.getElementById('btn-pause'),
muteBtn = document.getElementById('btn-mute'),
unmuteBtn = document.getElementById('btn-unmute');
playBtn.onclick = function() {
this.style.display = "none";
pauseBtn.style.display = "inline";
myAudio.play();
return false;
};
pauseBtn.onclick = function() {
this.style.display = "none";
playBtn.style.display = "inline";
myAudio.pause();
return false;
};
muteBtn.onclick = function() {
this.style.display = "none";
unmuteBtn.style.display = "inline";
myAudio.volume = 0;
return false;
};
unmuteBtn.onclick = function() {
this.style.display = "none";
muteBtn.style.display = "inline";
myAudio.volume = 1;
return false;
}
And you should have a nice fast screen-independent pixel-free audio player.
You can find the demo and source code here.
Reblogged this on Sutoprise Avenue, A SutoCom Source.
Pingback: Photoshop is Dead, Long Live the Web « AppsFuel Blog