Cloud Four Blog

Technical notes, War stories and anecdotes

The Power of Responsive Design Sprints

In 2008, I sat gobsmacked in Web 2.0 Expo session. The topic of M. Jackson Wilkinson‘s presentation was “Design and User Experience in the Agile Process“, and I literally couldn’t imagine designing that way.

Fast forward seven years, add responsive design to the mix, and I can no longer imagine designing any other way. Responsive Design Sprints are key to our process.

Why agile for design?

Our path to agile for design started with moving to agile for development. Lyza and Megan spearheaded a move to agile development a few years ago and that change influenced the way we looked at projects.

Because of our success using agile for development, we were primed to try it when responsive design broke our existing design process.

We’ve found that agile design is ideally suited for designing responsive patterns. It allows us to focus on small pieces of a design and iterate on them quickly.

What is a Responsive Design Sprint?

Most of the time when people talk about design sprints, they’re referring to product design sprints. This is the process that Google Ventures, our friends at Fresh Tilled Soil and others have developed and promoted as a way to quickly validate product design and direction.

Thoughtbot's Product Design Sprints diagramThoughtbot’s Product Design Sprint Phases

Product design sprints are an exceptionally useful tool. The phases in our sprints have some similar characteristics—you’ll see parallels to the Understand, Diverge and Prototype phases in particular.

However, Responsive Design Sprints are decidedly different in what they’re trying to accomplish and diverge from Product Design Sprints in some specific ways.

Pre-sprint planning

Our first step when planning a project is to break the site down into the patterns—from the lowest level to higher-level components—that we need to design.

patterns-into-sprints

This is our starting position for each sprint, but because we’re working in an agile fashion, we’re flexible and can change what patterns are being worked on. We can also spend more time on patterns or bring patterns in from later sprints if we’re ahead of our plan.

Before each two-week sprint, we collaborate with our clients to figure out what patterns will be covered in the upcoming sprint. This not only allows us to confirm that our priorities are correct, but it also gives our clients a heads up on what they need to prepare for the sprint kickoff.

Sprint Day 1 — Client briefing and small screen sketching

Client briefing

Each sprint starts with a briefing on the patterns for that sprint. This briefing is led by the client team.

During the briefing, the client team provides everything they know about the patterns including:

  • How the patterns are used.
  • Any edge cases for the patterns.
  • Analytics information on the patterns.
  • User testing that has been done.
  • Support or user feedback on patterns.

If we’re dealing with foundational patterns like typography and buttons, the briefing could simply be going over any existing brand and style guidelines.

However, when we start working on more complex patterns—for example a shopping cart interface—there is often quite a bit of information about the pattern to convey.

Small screen sketching

After the briefing, we start group sketching sessions. Ideally, we do this with our client, but often we work with teams in other parts of the world so we only get to sketch together a couple of times during a project.

Everyone participates in the sketching irrespective of roles. Sketching small screen designs helps people start thinking more tangibly about the constraints of small screens. It is one of the reasons why we include clients in sketching exercises whenever we can.

We pick the portions of the patterns that we think are going to be the most difficult to fit on small screens and sketch those. This often means that we’re not sketching the entire interface or even the entire pattern that we’re looking at, but instead just a small portion of the pattern that looks particularly troublesome.

Sketches on sticky notes

We sketch on small sticky notes using Sharpies. Every sketching session is time-boxed. The constraints on time, size and low fidelity markers prevent people from getting too detailed in their drawings.

And we use Sharpie brand markers because Tyler is a marker snob.

(Tyler here: The store-brand ones bleed too much!!)

Each person posts their sketches on the board and talks about what they saw and how they were trying to solve the problems. The conversation around the sketches is just as important as the sketching itself.

Photo of me presenting some of my terrible sketches

The goal of the sketching session is to give the designers some ideas on how they might solve the problems that the patterns represent. We do multiple sketching sessions until people feel they have enough material to explore.

Focus on small screens first

For most of the sprint, we focus on small screens. We’re often asked how things will work on wider screens early in a sprint, but we try to resist thinking about that yet.

If you’ve managed to organize your life to fit inside a New York City apartment, you’re not going to have any trouble adjusting to a big house in the suburbs. The same is true of responsive designs.

If you nail the small screen design, the larger sizes will be easy by comparison.

Sprint daily activity — Quick design iterations

We move immediately from sketches to testing our ideas in the browser. We create quick prototypes of the designs that we then share with the client team in Slack.

The video above shows collaboration happening on day 2 of a new project. We’re showing simple small screen designs in the browser and getting feedback both from our co-workers and the client team.

Often, we will have members of the client team working on patterns as well. They may be sharing mockups, photographing sketches, or even coding prototypes.

What matters most is that we’re sharing ideas quickly and iterating towards better solutions.

LICECap, the worst named, best tool ever

One of the advantages of designing in the browser is that we’re able to demonstrate how things should interact. But when we’re working with distributed teams, we need a tool to show the interaction.

That’s where LICECap comes in. LICECap makes it easy to capture screen video and save it as an animated gif.

So instead of saying to a client, “imagine we hide all of the controls behind a single button until someone clicks on it” and hoping that the client understands, we simply post an animated gif in Slack.

Animated gif showing add to cart interaction

The animated gif eliminates confusion and facilitates quick feedback.

Mid-sprint review meetings

The amount and frequency of review meetings in a sprint change from project to project, but generally we’ll have one review meeting late in the first week of the sprint to make sure we’re on the right track.

We share our screens and show any in-progress work. Those who have been active in our shared Slack channel will have seen most of the work already, but the meeting ensures that all stakeholders are looking at the patterns early in the sprint.

Depending on the complexity of the pattern, by the second review meeting we’ll have examples of how the pattern will adapt as the screen size increases.

Sample two-week sprint schedule

End of sprint review

At the end of the two week period, we have one final meeting to review the progress on the patterns tackled during the sprint. Nothing in this meeting should be a surprise because we’ve been sharing our work throughout the sprint.

After we’ve reviewed the patterns, we talk about what worked well during that sprint and what we could improve on for the next sprint. We’re not only iterating on the designs, but on the process itself.

This isn’t rocket science, but it feels new just the same

Nothing I’ve described here is new.

Agile processes have been around for years. Many people have talked about how responsive design makes pattern libraries more important than ever.

But the combination of responsive design, patterns libraries, sprints, gifs, and constant communication via Slack creates a radically different design process. Even if the pieces that comprise them aren’t new, Responsive Design Sprints certainly are.

Most importantly, Responsive Design Sprints work exceptionally well.

They helped us convert complex interfaces that seemed insurmountable. When we were asked to convert an e-commerce design to responsive in only three months, it was Responsive Design Sprints that helped us move quickly and finish the project a week ahead of schedule.

I can only imagine how stunned 2008 me would be to see what our design process looks like now.

Case Study: Our SVG Icon Process

When I wrote about why you shouldn’t use icon fonts in your next web project, I had no idea it would spark so much heated debate and intense discussion. One recurring question stood out to me: How might one actually implement an SVG icon system?

It’s a surprisingly difficult question to answer. Should you use <img>, <svg>, <object> or pure CSS? Will you combine your icons into a single sprite or keep them separate? If you do combine them, do you use an old-school technique or embrace SVG’s built-in features? Can JavaScript factor in somehow?

Though this variety of options might feel overwhelming, it’s ultimately a good thing. SVG’s versatility empowers us to craft the most appropriate solution for our audience and use-case.

So as much as I’d like to, I can’t say exactly how you should implement SVG icons in your next project. There’s no substitution for research and trying stuff out when it comes to finding the best fit for your project.

Instead, I’m going to show how we tend to assemble and implement SVG icons, and why we do it that way.

What We Do

The icon process we’ve adopted here at Cloud Four is a byproduct of the types of projects we take on, which tend to be large responsive redesigns or brand-new responsive interfaces. Our most common deliverables are in-browser mockups and pattern libraries. We often work with existing in-house teams, designing or extending icon systems based on their brand guidelines.

The front-end problems we solve tend to be those that are too complex or idiosyncratic to tackle with a framework or a simple content reflow. Our most common use of icons is to reinforce the meaning or relative importance of interface controls (a plus next to the word “Add,” a checkmark next to the word “Okay,” etc.).

Our Requirements

With this context in mind, we can assemble a list of requirements:

  • Accessibility: Because our icons represent or reinforce content, they should exist in markup.
  • Design: Our icons will most often coexist with text. They should inherit the text color and flow with the text by default.
  • Performance: Icons should be consolidated into a single, external sprite to avoid multiple requests and maximize caching.
  • Workflow: Whatever icon prep we can automate should be baked into our existing development tools (Node.js and Gulp).
  • Browsers: Our projects tend to be optimized for IE9+, Android 3+ and the usual array of less finicky modern browsers.

With requirements in hand, it’s time to build an SVG icon system!

1. Exporting Icons

Though our team digs Sketch for UI explorations, we still feel like Illustrator is a bit more intuitive for the design of icons and other illustrative elements.

We maintain a master icons.ai file in a shared spot (usually Dropbox), with each icon in the library residing in its own named artboard. We can see every icon in the context of its siblings, make any final tweaks for consistency, and simplify or combine any overlapping or unnecessary paths.

Screenshots of Illustrator artboards with icons

During this process, we purposely avoid preparing different rotations of the same icon. Traditionally, icon sets have exported separate assets for “left arrow,” “right arrow,” etc., but with SVG this repetition is redundant and unnecessary. Later on, we’ll walk through how to create simple rotational variations of the same icon.

Once everything’s looking good and feeling clean, we use Illustrator CC’s recently-improved exporting to generate SVGs from our artboards. After removing anything Illustrator over-enthusiastically prepended to our filenames, we’re ready to smoosh all of our icons into a single sprite.

2. Creating Our Sprite

As mentioned earlier, our team likes using Gulp for our local environment. If you’ve never used Gulp before, here’s a great article covering the basics. We’re going to write a Gulp task called icons this will compile a folder of separate, unoptimized SVG icons into a single, optimized sprite we can reference from our HTML.

Of the handful of plugins we’ve tried for accomplishing this sort of thing, our favorite is currently gulp-svg-sprite. It boasts a wealth of output modes and configuration options, making it the perfect choice for control freaks like yours truly.

For our icons task, we’ll be using the plugin’s symbol “mode.” This will transform each of our SVG files into a <symbol> element, which we’ll be able to reference by ID later.

Here’s what our SVG task might look like:

var gulp = require('gulp');
var svgSprite = require('gulp-svg-sprite');
 
var svgSpriteConfig = {
  mode: {
    symbol: {
      dest: '',
      sprite: 'icons.svg'
    }
  }
};
 
gulp.task('icons', function () {
  return gulp.src('./src/icons/**/*.svg')
    .pipe(svgSprite(svgSpriteConfig))
    .pipe(gulp.dest('dist'));
});

This task will:

  1. Find every SVG file in the src/icons directory.
  2. Pass those files to the gulp-svg-sprite plugin, which combines them into a single icons.svg file using the symbol output mode.
  3. Output the result to the dist directory.

Now if we run gulp icons, we should find a shiny new icons.svg file in our dist directory, ready to be referenced from our markup.

3. Including Icons in Our Markup

Now that we have our SVG sprite, we can reference it from our markup using <svg> and the <use> element:

<svg>
  <use xlink:href="icons.svg#back"/>
</svg>

This markup tells the browser “use the symbol with ID back from the file icons.svg.” This means our external file is nice and cacheable, and we can reference the same icon asset multiple times from the same file! Hooray!

Except, it looks like garbage:

Unstyled SVG icon in document

We haven’t told the browser how we want our icons to be sized, filled or aligned based on their surroundings. To do that, we need some CSS.

4. Styling Icons

We don’t want to style every svg because SVG can be used for a lot more than icons. Instead, we’re going to create a class. Our team likes using SUIT CSS naming conventions, so we’ll name our class Icon:

.Icon {
  /* Flow with text content */
  display: inline-block;
  /* Inherit the parent text color */
  fill: currentColor;
  /* Use the parent font-size for width and height */
  height: 1em;
  width: 1em;
  /* Vertically align icon with adjacent text */
  vertical-align: middle;
  /* Align more nicely with capital letters */
  position: relative;
  top: -0.0625em;
}

(Props to Chris Coyier and Jonathan Snook!)

Here’s the result after adding class="Icon" to our SVG element:

Styled SVG icon in document

Success! Our icons are successfully inheriting their size and color, and aligning nicely with adjacent type.

This accomplishes most of what we set out to do, but we haven’t taken advantage of what makes SVG special just yet. Let’s fix that.

5. Adding DRY Variations

Back when we were exporting icons, we only exported a single arrow asset (back.svg), the contents of which looked something like this:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="M22,10H6.83l3.59-3.59A2,2,0,0,0,7.59,3.59l-7,7a2,2,0,0,0,0,2.83l7,7a2,2,0,0,0,2.83-2.83L6.83,14H22A2,2,0,0,0,22,10Z"/>
</svg>

Let’s pop open our favorite code editor, and create a new forward.svg file to compliment it:

<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" 
  viewBox="0 0 24 24">
  <use xlink:href="#back" transform="rotate(180 12 12)"/>
</svg>

Here’s what’s going on:

  1. Our <svg> element is identical to back.svg, except we’ve added an xmlns:xlink attribute. This helps avoid errors during optimization by letting the plugin know that this SVG will reference other elements.
  2. Instead of including the forward icon’s path data, we reference our existing #back icon from a <use> element (similar to how we reference icons from our markup).
  3. The transform attribute rotates the icon 180 degrees from the center of our viewBox.

If we recompile our sprite, we should now be able to reference both icons from our markup:

Original arrow icon and derivative icon in document

Any changes made to back.svg will cascade to forward.svg (or any future variations). Plus, we save a small amount of file-size in the compiled sprite. Win/win!

6. Enforcing Mandatory Colors

Sometimes there are icons that really shouldn’t inherit everything about the parent. A common concern we hear from design teams is that the meaning of certain icons (in particular those representing “error” or “warning”) can be diluted over time if they are applied inconsistently.

In these cases, it’s helpful to remember that SVG elements are subject to the same style cascade as everything else. By specifying mandatory colors via attributes on the elements themselves (fill, style, etc.), we can overrule some or all color inheritance.

As an example, this error.svg file has fill attributes on the elements themselves:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path fill="#ff4136" d="M13.74,3l9,15.7A2.21,2.21,0,0,1,20.9,22H3.1a2.21,2.21,0,0,1-1.8-3.34l9-15.7A2,2,0,0,1,13.74,3Z"/>
  <path fill="#fff" d="M10.59,17.82a1.41,1.41,0,1,1,1.4,1.4A1.42,1.42,0,0,1,10.59,17.82Zm2.77-9.63a32.3,32.3,0,0,1-.61,4.5l-0.34,2.11H11.6l-0.34-2.11a32.77,32.77,0,0,1-.61-4.5A1.24,1.24,0,0,1,12,6.78,1.24,1.24,0,0,1,13.36,8.18Z"/>
</svg>

Even with our .Icon class applied, these colors will not be overruled:

Error icon that will not inherit its fill color from document

7. Improving Accessibility

Arguably the best reason to adopt SVG is to take advantage of its accessibility features. Thanks to Léonie Watson’s Tips for Creating Accessible SVG, we know to add the following elements and attributes to our icons:

<svg
  xmlns="http://www.w3.org/2000/svg" 
  viewBox="0 0 24 24"
  aria-labelledby="title desc">
  <title id="title">Back</title>
  <desc id="desc">A leftward arrow</desc>
  <path d="M22,10H6.83l3.59-3.59A2,2,0,0,0,7.59,3.59l-7,7a2,2,0,0,0,0,2.83l7,7a2,2,0,0,0,2.83-2.83L6.83,14H22A2,2,0,0,0,22,10Z"/>
</svg>

This insures that our icons have human readable fallbacks for blind and partially sighted people in a variety of user agents.

But there’s a problem with this approach. IDs must be unique, and we’ll be combining multiple files into a single SVG document. Our accessibility efforts will be thwarted if two <title> or <desc> elements attempt to use the same ID within the same document.

We could just be really diligent about choosing unique IDs, but that’s kind of a pain. If only we could manage these titles and descriptions in a central location, relying on our Gulp task to assign unique identifiers…

Luckily, we can! All we need to do is provide all our titles and descriptions in a separate YAML file:

back:
  title: Back
  description: A leftward arrow

error:
  title: Error
  description: A red sign with a white exclamation mark

forward:
  title: Forward
  description: A rightward arrow

search:
  title: Search
  description: A magnifying glass

Then update the Gulp task with the location of that file:

var svgSpriteConfig = {
  mode: { /* ... */ },
  shape: {
    // Titles and descriptions
    meta: './src/icons/icons.yaml'
  }
};

When we run gulp icons again, gulp-svg-sprite will add <title> and <desc> elements with unique, namespaced IDs and update the aria-labelledby attribute accordingly.

(It’s important to note that while we’ve specified <title> and <desc> elements within our sprite, you should still take care to use accessibility attributes in the page itself when the icon’s meaning is not re-enforced by its surrounding content.)

8. Supporting More Browsers

Time to address the elephant in the room…

Our icon sprite is a separate file, which is great for caching. But referencing symbols in an external file doesn’t work in Internet Explorer (though it does in Edge).

Icons not displaying in IE10

To address that, we’re going to use a polyfill called svgxuse. The script works by detecting failed external references, loading the referenced file via AJAX, injecting the sprite into the page itself, and updating the xlink:href attributes to point to the in-page resource. We like svgxuse because it minimizes the duplicated path data while retaining the ability for icons to reference each other.

The polyfill will work as-is, but we should make a couple of changes one small change to our task config to avoid any collisions with in-page content:

var config = {
  mode: { /* ... */ },
  shape: {
    // Titles and descriptions
    meta: SRC + '/icons/icons.yaml',
    // Add suffix to IDs
    id: {
      generator: '%s-icon'
    }
  }
};

Now we won’t have to worry about the SVG sprite being visible in Internet Explorer, and the IDs for our icons are far less susceptible to collisions once they coexist in the same document. Once we update our icon references to include the -icon suffix, we should have our target browsers covered:

Icons displaying in IE10 with svgxuse

Update: An earlier version of this post included specific configuration options for hiding the injected SVG sprite, but svgxuse handles that automatically now. Open source is awesome!

Putting It All Together

We made it! Here’s what we accomplished:

  • Our Gulp task will compile a folder of icons into a single, cacheable SVG sprite.
  • Individual icons can be referenced one or more times from anywhere in our HTML document.
  • By default, icons will base their position, size and color on their parent elements and surrounding text.
  • Icons may defy the default styles where appropriate.
  • To avoid repetition, some icons can be simple variations of others.
  • We can specify conflict-free accessibility details within icons.yaml.
  • When external references fail, the asset will be injected into the page itself.

You can see a live demo of the end result or browse the code.

Our completed SVG icon demo

Before we pat ourselves on the back too vigorously, it’s important to remember that that there is no one, true SVG icon process. Your ideal setup might involve the picture element, grunt-svgstore, SVGInjector or even an existing library. It can and should change based on the needs of your project. We modify ours all the time.

So consider this just one potential starting point for your own SVG icon system. I hope you’ll share what you come up with!

Listen to WalmartLabs on the RWD Podcast

WalmartLabs LogoWe had the great fortune to help WalmartLabs convert their sites to responsive design, and it is always nice to see our clients get recognized for their hard work.

Mini Kurhan and Olawale Oladunni, two designers at WalmartLabs, were recently interviewed by Ethan Marcotte and Karen McGrane for the Responsive Web Design Podcast.

I highly recommend giving the interview a listen. There is also a transcript of the interview if you prefer.

It was great hearing Mini and Ola talking about the challenges Walmart faced and how they overcame them. It was a massive effort to convert the sites to responsive design and the Walmart team did a fantastic job. We had a blast working with them.

If you want to learn more about the Walmart redesign, particularly when it comes to responsive images, check out Mini and Ola’s presentation from Responsive Field Day.

Responsive Image Breakpoints Generator

Responsive image breakpoints have vexed me for nearly four years. They have been my personal koan—my unsolvable problem—until today.

Logo for ResponsiveBreakpoints.comSee a couple of years ago, I had a crazy idea to pick image breakpoints using performance budgets. John got excited by this idea and built a rough prototype of how this might work.

I used the script John wrote to create a demo page showing how a performance budget could be used to select image breakpoints. But the script was never intended to be a production tool.

Still, the idea had legs. And it was clearly something other people could use:

Unfortunately, building such a tool was beyond my skill level. The job called for someone who understood image processing and compression much better than I do.

That’s why I’m thrilled to share that Cloudinary took up the challenge and built the Responsive Image Breakpoints Generator.

responsive-images-generator-800

The Responsive Image Breakpoints Generator works better than I could have imagined. From an end user standpoint, you simply:

  1. Select the smallest and largest size your image will be used at.
  2. Set your performance budget.
  3. Upload your image.

That’s it! The tool does the rest. The generator will:

  • Determine the optimal number of images you need.
  • Provide you with sample code for those images.
  • Offer a zip file for download that contains all of the images and code you need.

And the kind folks at Cloudinary have made the tool free to use and open sourced the front-end code.

They’ve also integrated this capability into their platform and API so if you want to use the tool in an automated fashion, you can do so. They even have a free tier of their service that includes 7,500 monthly image transformations which is more than enough for small sites.

Nadav Soferman, a co-founder of Cloudinary, has written in more detail about the tool and why it is important at Smashing Magazine.

Simply giddy

I can’t begin to tell you how excited and honored I was to find out that Cloudinary was working on building my crazy idea. It has been all I could do to keep it secret for the last couple of months while they put the finishing touches on the site.

Thanks to Nadav, Tal and the whole team at Cloudinary for making this tool a reality and giving it away to the web community!

Seriously, Don’t Use Icon Fonts

Icons are everywhere. These “little miracle workers” (as John Hicks described them) help us reinforce meaning in the interfaces we design and build. Their popularity in web design has never been greater; the conciseness and versatility of pictograms in particular make them a lovely fit for displays large and small.

But icons on the web have had their fair share of challenges. They were time-consuming to prepare for every intended display size and color. When high-resolution displays hit the market, icons looked particularly low-res and blocky compared to the text they often accompanied.

So it’s really no wonder that icon fonts became such a hit. Icons displayed via @font-face were resolution-independent and customizable in all the ways we expected text to be. Sure, delivering icons as a typeface was definitely a hack, but it was also useful, versatile, and maybe even a little fun.

But now we need to stop. It’s time to let icon fonts pass on to Hack Heaven, where they can frolic with table-based layouts, Bullet-Proof Rounded Corners and Scalable Inman Flash Replacements. Here’s why…

Screen Readers Actually Read That Stuff

Most assistive devices will read aloud text inserted via CSS, and many of the Unicode characters icon fonts depend on are no exception. Best-case scenario, your “favorite” icon gets read aloud as “black favorite star.” Worse-case scenario, it’s read as “unpronounceable” or skipped entirely.

They’re a Nightmare if You’re Dyslexic

Screenshot of icon issue after replacing fonts on GitHub

Many dyslexic people find it helpful to swap out a website’s typeface for something like OpenDyslexic. But icon fonts get replaced as well, which makes for a frustratingly broken experience.

They Encroach on Emoji Turf

Most of the time, we rely on automated tools to choose which Unicode characters are assigned to which icon. But Unicode’s also where our beloved emoji live. If you aren’t careful, they can overlap in confusing (albeit hilarious) ways. My favorite example: Etsy’s “four stars and a horse” bug. More recently, our own Jason Grigsby encountered random fist-bumps on ESPN’s site.

They Fail Poorly and Often

Microsoft's example missing glyph characters

When your icon font fails, the browser treats it like any other font and replaces it with a fallback. Best-case scenario, you’ve chosen your fallback characters carefully and something weird-looking but communicative still loads. Worse-case scenario (and far more often), the user sees something completely incongruous, usually the dreaded “missing character” glyph.

Custom fonts shouldn’t be mission-critical assets. They fail all the time. One look at Bootstrap’s icon-related issues and it’s no wonder why they’re removing them entirely from the next version.

Worse still, many users will never see those fonts. Opera Mini, which frequently rivals iOS Safari in global usage statistics with hundreds of millions of users worldwide, does not support @font-face at all.

They Never Looked Right

Detail of Stackicons' octocat in IE11

The way browsers hint fonts to optimize legibility was never a good fit for our custom iconography, and support for tweaking that behavior is all over the place.

Multicolor icons are even worse. The technique of overlaying multiple glyphs to achieve the effect is impressively resourceful, but the results often look like their printing registration is misaligned.

You’re Probably Doing It Wrong

“But Tyler,” I hear you say. “You’ve completely ignored Filament Group’s Bulletproof Icon Fonts, complete with feature tests and sensible, content-driven fallback solutions.”

And you’re right. Those techniques are great! If you’re using an icon font, you should definitely follow their recommendations to the letter.

But you probably won’t.

What you’ll probably do is adopt whatever your framework of choice has bundled, or drop in some massive free icon font you can use right away. You won’t modify how they work out of the box because that’s really hard to prioritize, especially when they look great on your monitor with virtually no effort at all.

Or maybe you will do the work, designing and curating a custom icon font, choosing your Unicode characters carefully, documenting and evangelizing the importance of implementing your icons in an accessible way with appropriate fallbacks. Then one day, Dave forgets to add a fallback image to that iconographic button he added (which looks great, by the way), which Roberta reuses for her related Pull Request, and before you know it, your app has devolved into a fragile, hack-littered wasteland once more.

These examples are not hypothetical (though names have been changed to protect the innocent). I’ve seen them happen to multiple organizations, all of them starting with the best possible intentions.

There’s Already a Better Way

SVG is awesome for icons! It’s a vector image format with optional support for CSS, JavaScript, reusability, accessibility and a bunch more. It was made for this sort of thing.

But I hear a lot of excuses for why teams avoid using it, even for brand-new projects. Here are a few…

“SVGs can’t be combined into sprites.”

They totally can. There are even really great tools like svg-sprite and IcoMoon that can help automate that process.

“SVGs are larger in file size.”

Usually when I hear this, the team’s comparing a single binary icon font to multiple, uncompressed SVG files. The gap narrows dramatically when you optimize your SVGs, combine reusable ones into sprites, and deliver those with active Gzip compression or embedded in-page.

Occasionally I’ve heard the gap is still too wide when hundreds of icons are included. This begs the question: Why are you including hundreds of icons on every page?

“The icon markup is too verbose by comparison.”

Let’s compare:

<!-- Typical @font-face icon: -->
<span class="icon icon-search" aria-hidden="true"></span>
 
<!-- Typical SVG icon: -->
<svg class="icon">
  <use xlink:href="path/to/icons.svg#search"/>
</svg>

The SVG markup is barely more verbose, and way more descriptive and semantic than some empty, ARIA-hidden <span> element.

“Browser support for SVG is worse.”

As of this writing, global support for SVG is up to 96%… 4% higher than the same stat for @font-face. Plus, SVGs are way more accessible and their fallbacks are much more straightforward.

“The framework we chose already has an icon font.”

If your framework told you to jump off a bridge, would you?

Don’t Be “Table Guy”

I was in school when the Web Standards movement hit critical mass. While the majority of my instructors saw the merits of semantic markup and embraced it wholeheartedly, one passionately held out. “Table Guy” argued that no layout tool could usurp <table>, that it was inherently better-suited for crafting grid-based designs. He boasted of how quickly and easily he could achieve the “Holy Grail” layout with his trusty table cells. He cited the wealth of cross-browser inconsistencies that continued to plague CSS.

Table Guy and I kept in touch. Today, he freely admits he was wrong about CSS. He feels embarrassed to have been so married to a technique that was so clearly misappropriated in hindsight.

If you won’t stop using icon fonts for people with screen readers, people with dyslexia, people with browsers that don’t support @font-face, people who randomly didn’t load the icon font once for some reason, or designers who just want their icons to look right on-screen…

Then do it for yourself. Don’t be Table Guy.