Advertisement
HTML/CSS

The What, Why and How of Data URIs in Web Design

by

Let's look at improving your site's performance by reducing the number of HTTP requests it makes. We're going to take advantage of a technique known as the data URI scheme; encoding both images and fonts into pure data strings that can be directly integrated into your markup and stylesheets.

Thumbnail: The Broccolidryiconsaniconsetitisfullof…icons by Visual Idiot (we'll be using these icons in a minute..)


As Internet connections became quicker and computers more powerful, website performance used to be an often overlooked best practice. Today, ensuring that your website is performing well is absolutely vital for keeping both your users and the search engines happy; especially when the site is being accessed using mobile data and under-powered phones and other devices.


The What, Why and How of Data URIs

We've already looked at CSS Sprite Sheets: Best Practices, Tools and Helpful Applications before on Webdesigntuts+, demonstrating how you can improve performance by reducing HTTP requests and reducing overall image file size. But did you know that you can represent an image (actually any binary data) in your HTML or CSS using only an ASCII text string?

This technique is known as the Data URI scheme, and is in fact not new. Although Data URIs have been floating around for more than ten years, they have only been gaining popularity fairly recently with widespread browser compatibility and a focus on improving site performance.

What Are the Benefits of Using Data URIs?

The primary benefit of using data URIs is performance enhancement. Any resources that are used in your site are fetched by your browser using an HTTP request. This includes everything from stylesheets, to JavaScript files, to images. Regardless of the speed of the internet connection, almost all browsers limit the maximum amount of concurrent HTTP requests to two at a time, effectively resulting in a bottleneck of data. The more HTTP requests that need to be made, the poorer the overall performance of the site will be.

Combining image data into the HTML or CSS of the site instantly removes the need for the browser to fetch additional resources. Although raw Base64 encoded data is generally considered to be around 33% larger than its optimized counterpart (for example an image), after gzipping and CSS file optimization the difference in file size is generally negligible.

What do Data URIs Look Like?

A Data URI is essentially binary data encoded into a Base64 format, along with some additional information for the browser including a MIME type, a Charset and the encoding format (Base64).

The data URI (in its simplest form) looks like this:

data:[][;charset=][;base64],

To use a data URI as an inline HTML image, the format looks like this:

<img src="data:image/png;base64,<base64 data goes here>" alt="My Image" width="32" height="32" />

To use a data URI as a repeating background image in CSS, the format is as follows:

body {
    background-image:url('data:image/png;base64,');
    background-repeat: repeat;
}

Alternatively, combine the background elements with CSS shorthand:

div.logo {
    background:url('data:image/png;base64,')
    no-repeat
    top left;
    margin:20px 10px 0 10px;
}

While we've used images to illustrate the usage of Data URIs, almost any media can be used, including multimedia files, fonts (as we'll see shortly) and much more.

How to Use Data URIs

OK, let's get practical with a couple of examples. Let's take the following image (a repeating tile that I downloaded from Subtle Patterns), convert it into a Data URI and use CSS to create a repeating background for a site or interface.

Repeating Background Tile

Although Data URIs may look pretty funky, the process to create one is very simple.

First, head over to the Web Semantics Data URI Converter and upload the image by selecting the file location of the image and clicking the 'Convert Image' tool:

Web Semantics Data URI conversion tool

Once processed, if you scroll down the page, you'll see what this image looks like base64 encoded:

Web Semantics Data URI conversion tool

Since we need a repeating background for our project, we'll need to modify the CSS given to us by the tool.

For a repeating background, copy and paste the following CSS:

div.logo {
background-repeat: repeat;
background-image: url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjlCNDA1N0EyRkNEQzExRTE5NEEyOEY1NEFFMzlEMzVFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjlCNDA1N0EzRkNEQzExRTE5NEEyOEY1NEFFMzlEMzVFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OUI0MDU3QTBGQ0RDMTFFMTk0QTI4RjU0QUUzOUQzNUUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OUI0MDU3QTFGQ0RDMTFFMTk0QTI4RjU0QUUzOUQzNUUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAABAQEBAQEBAQEBAQEBAQEBAQEB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);
}

Let's take an even easier example, converting the following image to a Data URI and slotting it into our markup as an inline image:

Repeating Background Tile

Just follow the steps above to convert the image into a base64 encoded image and copy the HTML markup generated by the tool (from the 'As An Image' panel) and paste it directly into your HTML markup in the same way that you would for inserting a regular inline image.

The final code for this example looks like this:

<img width="110" height="58" title="" alt="" src="data:image/jpeg;base64,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" />

When to Use Data URIs (and When to Avoid Them)

There aren't really any hard and fast rules about when to use data URIs to replace site assets, but there are a number of drawbacks and peculiarities to consider when choosing whether or not to use Data URIs.

  • If you plan to support
  • Data URIs are not cached by the browser, so they will need to be downloaded on every page, even if they've already been rendered by the browser.
  • Data URIs are most suited to small resources, but they can be used for larger resources (e.g. photographs) without incurring any major performance penalties (after gzipping they are around 2-3% larger than the original file). Be aware, however, that the site user will not see anything until the entire asset is downloaded, which could be undesirable for users on mobile or with slow Internet connection.
  • Data URIs make your CSS and HTML documents look very messy. For large sites and widespread Data URI utilization, stylesheets and markup become more difficult to read, navigate and maintain.
  • Every time that you make a change to an asset (for example a spritesheet), you'll need to re-encode the image file, adding more steps to your workflow.

Base64 Encoded Icon Fonts

Do you remember me saying that any binary data can be used in the data URI scheme? Now that we've looked at base64 encoded images, let's now take a look at turning an icon font into a data URI and implementing it in a project.

In fact, data URIs are a perfect match for icon fonts, especially if you're only planning to use a few symbols with a small filesize.

We're going to be using the online web app IcoMoon to generate a custom font set, output the data URI and generate the final CSS code.

First, head over to the IcoMoon site and click the 'Start Using The App' link:

IcoMoon Custom Font App

Next, either browse the font sets to select your custom icon fonts, or alternatively use the search field to the top left of the page to find fonts that match the tags 'Comment', 'Heart', 'Eye' and 'Search'.

I've used the Broccolidry font set from Visual Idiot in this example.

Select Your Custom Font Set

Next, move to the download settings page by clicking the 'Font' button at the bottom of the screen:

Move the Font Download Settings Page

On the download settings page, change the Baseline to 10%, click the settings icon to bring up the advanced options and select the 'Base64 Encode & Embed in CSS' checkbox. Click the 'Save' icon to download your font.

Download Settings

Once you've downloaded and extracted the custom font, you can open up the 'index.html' file to view your font and their unicode pairings:

Index.html allows you to view your font pairings

Using Your Custom Icon Font

Now that we've created our custom icon font set, let's see how we can use it in a project.

First, open up the stylesheet provided in the IcoMoon download and locate the following CSS. Since the name of the game is about reducing HTTP requests, we're going to be copying and pasting all of the provided CSS into our own main style sheet.

<pre>@font-face {
    font-family: 'customFont';
    src: url(data:font/svg;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiID4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8bWV0YWRhdGE+ClRoaXMgaXMgYSBjdXN0b20gU1ZHIGZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uCjEKPC9tZXRhZGF0YT4KPGRlZnM+Cjxmb250IGlkPSJjdXN0b21Gb250IiBob3Jpei1hZHYteD0iNTEyIiA+Cjxmb250LWZhY2UgdW5pdHMtcGVyLWVtPSI1MTIiIGFzY2VudD0iNDYxIiBkZXNjZW50PSItNTEiIC8+CjxtaXNzaW5nLWdseXBoIGhvcml6LWFkdi14PSI1MTIiIC8+CjxnbHlwaCB1bmljb2RlPSImI3gyMTsiIGQ9Ik0gNTA3LjQ0LTIuMjQ4YyA2LjA5Ni02LjA5NiwgNi4wOTYtMTUuOTg0LDAuMDAtMjIuMDk2bC0yMi4wOTYtMjIuMDk2CgljLTYuMTEyLTYuMDk2LTE2LjAwLTYuMDk2LTIyLjA5NiwwLjAwbC0xNTQuNjg4LDE1NC42ODhjLTEuNjgsMS42OC0yLjgwLDMuNjY0LTMuNTUyLDUuNzc2QyAyNzMuMjgsOTAuODQsIDIzNC4zMiw3Ny4wMCwgMTkyLjAwLDc3LjAwCglDIDg1Ljk2OCw3Ny4wMCwwLjAwLDE2Mi45NjgsMC4wMCwyNjkuMDBDMC4wMCwzNzUuMDMyLCA4NS45NjgsNDYxLjAwLCAxOTIuMDAsNDYxLjAwYyAxMDYuMDMyLDAuMDAsIDE5Mi4wMC04NS45NjgsIDE5Mi4wMC0xOTIuMDBjMC4wMC00Mi4zMi0xMy44NC04MS4yOC0zNy4wMjQtMTEzLjAwOAoJYyAyLjExMi0wLjc1MiwgNC4wOTYtMS44NTYsIDUuNzc2LTMuNTUyTCA1MDcuNDQtMi4yNDh6IE0gMTkyLjAwLDM5Ny4wMGMtNzAuNjg4LDAuMDAtMTI4LjAwLTU3LjMxMi0xMjguMDAtMTI4LjAwYzAuMDAtNzAuNjg4LCA1Ny4zMTItMTI4LjAwLCAxMjguMDAtMTI4LjAwcyAxMjguMDAsNTcuMzEyLCAxMjguMDAsMTI4LjAwCglDIDMyMC4wMCwzMzkuNjg4LCAyNjIuNjg4LDM5Ny4wMCwgMTkyLjAwLDM5Ny4wMHoiIC8+CjxnbHlwaCB1bmljb2RlPSImI3gyMjsiIGQ9Ik0gMjU2LjAwLDEzLjQ5NmMtMTAuMzg0LDAuMDAtMjUuNTg0LDExLjY4LTM1LjY2NCwxMi43NTJjLTI4Ljc1Mi0yNC4xMTItNTguNzA0LTUzLjEzNi05OS40MjQtNjguMjI0CgljLTE3Ljc3Ni03LjUzNi0zMy4wNC0xMS45MDQtMzcuMDA4LTcuMTUyYy01LjMyOCw2LjE5Mi0xMy4zNzYsMTQuNzg0LTE0LjgwLDE3LjA4OGMgMC4wOCwzLjQyNCwgNC4yMjQsMC43MiwgOC43MzYsNS41ODQKCWMgMjQuNTc2LDEwLjMzNiwgNDAuNDQ4LDM3LjAwOCwgNTEuMTIsNjkuNjE2QyA1MS45ODQsODEuNzM2LDAuMDAsMTU0LjEwNCwwLjAwLDIzNy4yMDhDMC4wMCwzNjAuNzQ0LCAxMTQuNjI0LDQ2MC45MDQsIDI1Ni4wMCw0NjAuOTA0cyAyNTYuMDAtMTAwLjE0NCwgMjU2LjAwLTIyMy42OTYKCVMgMzk3LjM3NiwxMy40OTYsIDI1Ni4wMCwxMy40OTZ6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4MjM7IiBkPSJNIDM2OC4wMCw0MjkuMDBjLTM4LjQ2NCwwLjAwLTY5LjI5Ni0xMy44MDgtOTYuNDgtNDEuMDA4Yy0wLjAxNi0wLjAxNi0wLjAzMi0wLjAzMi0wLjA0OC0wLjA0OAoJbC0wLjAxNiwwLjAwTCAyNTYuMDAsMzY4LjQ3MkwgMjQwLjU0NCwzODYuNzZjLTAuMDE2LDAuMDE2LTAuMDMyLDAuMDMyLTAuMDQ4LDAuMDQ4TCAyNDAuNDgsMzg2LjgwOCBsMC4wMCwwLjAwQyAyMTMuMjgsNDE0LjAyNCwgMTgyLjQ2NCw0MjkuMDAsIDE0NC4wMCw0MjkuMDBTIDY5LjM3Niw0MTQuMDI0LCA0Mi4xNzYsMzg2LjgyNAoJQyAxNC45OTIsMzU5LjYyNCwwLjAwLDMyMy40NjQsMC4wMCwyODUuMDBjMC4wMC0zOC40MzIsIDE0Ljk2LTc0LjU5MiwgNDIuMTI4LTEwMS43NzZMIDIzMy4yOC05LjUyOEMgMjM5LjI4LTE1LjU5MiwgMjQ3LjQ3Mi0xOS4wMCwgMjU2LjAwLTE5LjAwcyAxNi43MiwzLjQwOCwgMjIuNzIsOS40NzIKCWwgMTkxLjEzNiwxOTIuNzUyQyA0OTcuMDI0LDIxMC40MDgsIDUxMi4wMCwyNDYuNTUyLCA1MTIuMDAsMjg1LjAwYzAuMDAsMzguNDY0LTE0Ljk5Miw3NC42MjQtNDIuMTc2LDEwMS44MjRDIDQ0Mi42MjQsNDE0LjAyNCwgNDA2LjQ2NCw0MjkuMDAsIDM2OC4wMCw0MjkuMDBMIDM2OC4wMCw0MjkuMDB6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4MjQ7IiBkPSJNIDI1Ni4wMCwzNjUuMDBDIDExNC42MDgsMzY1LjAwLDAuMDAsMjA1LjAwLDAuMDAsMjA1LjAwcyAxMTQuNjA4LTE2MC4wMCwgMjU2LjAwLTE2MC4wMHMgMjU2LjAwLDE2MC4wMCwgMjU2LjAwLDE2MC4wMFMgMzk3LjM5MiwzNjUuMDAsIDI1Ni4wMCwzNjUuMDB6IE0gMjU2LjAwLDEwOS4wMAoJCQljLTUzLjAwOCwwLjAwLTk2LjAwLDQyLjk5Mi05Ni4wMCw5Ni4wMHMgNDIuOTkyLDk2LjAwLCA5Ni4wMCw5Ni4wMHMgOTYuMDAtNDIuOTkyLCA5Ni4wMC05Ni4wMFMgMzA5LjAwOCwxMDkuMDAsIDI1Ni4wMCwxMDkuMDB6IE0gMjU2LjAwLDI2OS4wMGMtMzUuMzQ0LDAuMDAtNjQuMDAtMjguNjU2LTY0LjAwLTY0LjAwcyAyOC42NTYtNjQuMDAsIDY0LjAwLTY0LjAwcyA2NC4wMCwyOC42NTYsIDY0LjAwLDY0LjAwCgkJCVMgMjkxLjM0NCwyNjkuMDAsIDI1Ni4wMCwyNjkuMDB6IiAvPjwvZm9udD48L2RlZnM+PC9zdmc+) format('svg'),
         url(data:font/ttf;charset=utf-8;base64,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) format('truetype');
    font-weight: normal;
    font-style: normal;
}

These few lines of CSS will now have your custom Icon Font ready to work on all modern browsers. If you want to support IE9 compatibility mode and old versions of IE, you'll need to add in an additional rule (note that this will fetch additional resources, but only when the User Agent requests them).

@font-face {
  font-family: 'customFont';
<!-- IE9 Compatibility Mode -->
  src: url('../fonts/customFont.eot');
<!-- Old IE Fix -->
    src: url('../fonts/customFont.eot?#iefix') format('embedded-opentype');
  font-weight: normal;
  font-style: normal;

Curious about these IE fixes? Paul Irish has a great blog post on a bulletproof @font-face syntax.

Now that our rules have been created, there are two ways that we can include the custom font in our design, both of which use Unicode entitites to reference the relevant icon. The great thing about the IcoMoon app is that all of the CSS has already been generated for us, ready to be copied into our main stylesheet, depending on what approach we decide to use (or both).

Using Your Icon Font: Data Icon Approach

The first technique for using your icon font is the data-icon approach, which keeps our markup nice and clean and is screen-reader friendly.

Let's say that we want to include a comment icon (in this case with the unicode value of &amp;#x22;) inside a span element on our page.

Our HTML:

<span data-icon="&#x22;" aria-hidden="true"></span>
<!-- the aria-hidden attribute prevents screenreaders from trying to read the unicode -->

The relevant CSS (taken directly from the downloaded IcoMoon stylesheet) is as follows (comments are mine).

/* A :before pseudo element is created for any HTML element with the data-icon attribute */
[data-icon]:before {

/* Font family is set the name set in our @font-face rule */
font-family: 'customFont';

/* The content for the pseudo element is fetched from the HTML data-icon (e.g. &#x22;) */
content: attr(data-icon);

/* Additional instructions to screen readers (not universally recognised) */
speak: none;

/* Univeral font styling */
font-weight: normal;
-webkit-font-smoothing: antialiased;
}

span {
/* Specific font-styling */
font-size: 2em;
color: #A2A2A2;
padding:2px 5px 2px 5px;
margin-right:5px;
}

While this approach is nice and streamlined and avoids additional class bloat in your markup, it may not be the best choice for maintainable code. Unless your memory of Unicode characters is both encyclopedic and photographic, this approach does not contain any information within the HTML that tips you off to what icon will be displayed.

Using Your Icon Font: Additional Class Approach

As an alternative approach, you may choose to use additional CSS classes in your HTML to display the icon. This has the benefit of inputting semantic, descriptive information directly into your markup, enhancing the readability of your code.

To use this approach, add an element in your HTML with a class name as provided by the IcoMoon stylesheet:

<span class="icon-comment"></span>

Our CSS will look like this (comments are mine).

/* The rule will be applied to any HTML element with a class of 'icon-*l and sets a pseudo-element to the element */
[class^="icon-"]:before, [class*=" icon-"]:before {

/* Font family is set the name set in our @font-face rule */
font-family: 'custom';
font-style: normal;
speak: none;
font-weight: normal;
-webkit-font-smoothing: antialiased;
}

.icon-comment:before {

/* The content for the pseudo element is set in escaped unicode (i.e. &#x22; becomes '/22' ) */
content: "\22";
}

Now, with a little additional styling, you can easily implement great looking icon fonts into your next project -- without bogging your asset tree down with additional resources.


Conclusion

Thanks for taking the time to explore some of the ways that you can get the most out of Data URIs for your next project.

It's important to remember that Data URIs are not always the best solution. While the use of CSS3, SVG and Icon Fonts have some very compelling benefits over the use of images (especially in the realm of responsive design), the benefits of encoding your images in base64 are more nuanced. When considering whether or not to use data URIs in your next project, weigh up loading times and reduced HTTP requests with code maintainability — just consider Data URIs as another tool in your toolbox!

Did you enjoy this tutorial and are now itching to get started using these techniques in a more practical way? Keep your eye out for new premium content soon where we will be using data URIs extensively to create a light-weight user interface design. Watch this space!

How have you used icon fonts and data URIs in your projects? Subscribe and leave a comment!


Additional Resources

Related Posts
  • Code
    Theme Development
    The Beginner's Guide to Icon Fonts in WordPressIcon fonts
    I like social icons, I'll admit it. I have literally dozens of social icon sets I've collected over the last few years, and have even created a few sets of my own to try to achieve that perfect fit for a particular project. But lately, I've discovered icon fonts, and I haven't been using those old image icons in a while.Read More…
  • Web Design
    HTML/CSS
    Unicode: A Beginner's PrimerUnicode retina 400x400
    Believe it or not, there's an image format which is built right into your browser. It allows images to be downloaded even before you need them, renders them perfectly on Retina screens, and allows them to have CSS colours and effects applied to them. Ok, I'm not being entirely truthful there. It's not an image format as such – but the rest still applies. Using Unicode you can create icons that are resolution independent, have virtually no download time and can also be styled with CSS.Read More…
  • Web Design
    UX
    Walk Users Through Your Website With Bootstrap TourTour retina
    When you have a web application which requires some getting used to from your users, a walkthrough of the interface is in order. Creating a walkthrough directly on top of the interface makes things very clear, so that's what we're going to build, using Bootstrap Tour.Read More…
  • Design & Illustration
    Web Design
    SVG Files: From Illustrator to the WebSvg thumb retina
    Scalable Vector Graphics (SVG) is a vector image format which began life back in 1998. It was always developed with the web in mind, but only now has the web actually started to catch up. There's no denying its relevance today, so let's have a look at the basics of taking SVG from Illustrator to the web browser.Read More…
  • Code
    Theme Development
    Creating a WordPress Theme From Static HTML: Preparing the MarkupCreating wordpress theme from html 400
    Last year I did a small (and admittedly very un-scientific) survey among other WordPress developers. What I wanted to know was this: When they built their first WordPress theme, how did they do it? Did they hack an existing theme or did they start with their own static HTML and turn it into a theme? The majority of people I spoke to used the second approach - they were all experienced frontend developers who had built sites using HTML and CSS, and found it easiest to take their existing HTML files and convert them to a theme. Two of the people I spoke to were lecturers or teachers, and told me that this is the approach they use with students. So in this series I'm going to show you how to do just that.Read More…
  • Code
    Articles
    Web Assets - Tips for Better Organization and PerformanceWeb assets retina preview
    Remember back to when we had to spend a lot of time optimizing our project's assets (images, CSS, etc..)? Well today, users have a much faster Internet connection and it appears that we can afford to use bigger images or bigger flash files with a lot of video and pictures inside. However, with the rise of mobile development, we are again back in that same situation. It is extremely important to create well optimized sites, so that we have faster applications, which download less content and respond immediately. Read More…