4

Before I begin, I read this very useful question which lays out what's the pros and cons of using <img>'s and background-images. When to use IMG vs CSS

After reading that, however I've been thinking about what's the most efficient & semantic way of displaying an icon. The other question contended that if there's semantic meaning to it such as a warning icon, then it should be displayed as an <img> which I think makes sense in most cases. However, what about the other times?

Here's the only other ways I've seen icons presented:

  • Having extra padding on an element (e.g., 20px left padding on an anchor)
  • As a separate element (Facebook uses the <i> tag, Google uses the <span> tag)

Using the extra padding method seems to work alright in some cases, but you might run into the problem of exposing other icons in your sprite map if the dimensions of the element don't match up with your icon.

I'm guessing the separate element icon method is probably the most fail-safe way of doing it, but I'm not 100% certain if it's always the best way to do it and what element to use (i, span, other?)

What's your thoughts?

Community
  • 1
  • 1
NerdCowboy
  • 293
  • 2
  • 9

4 Answers4

3

It depends on the circumstance, if the icon is actually designed to give emphasis to some text, then you'd include it in the tag, i.e.

<em>Warning!</em>

And you would add CSS styles to display the icon as the background-image. Technically speaking, you should only be using the <img> tag for items which are semantically images, such as a photograph or diagram. Otherwise for things like headings or icons, stick with changing the background-image.

Randy the Dev
  • 25,810
  • 6
  • 43
  • 54
  • Your example makes sense, but what I was referring to was the example given in my reference where their message was "Your postal code is not correct" and they used the icon to literally replace the word, "Warning". So I agree that it generally makes sense to use a background-image, but should one use a separate element (eg, a span within the em) for the icon as opposed to using the background-image/padding method as you just suggested? – NerdCowboy Oct 01 '10 at 23:19
  • 1
    I'd use image replacement techniques to replace `Warning` with your icon, because the icon semantically represents "Warning" not "I am a picture of an exclamation mark". – Randy the Dev Oct 01 '10 at 23:21
  • Exactly. To capture the 'semantic' meaning, imagine your user is browsing your site in a *terminal emulator*, he or she can't even see what your layout is, but layout is not a semantic – SingleNegationElimination Oct 01 '10 at 23:51
  • So I think you guys have successfully re-hashed the other question I referenced on when to use an image vs a background-image. Now to my main question: Google display icons like `` and Facebook displays it like `` as opposed to just doing a background image on the wrapping element. Are these both semantically acceptable ways to display icons? Facebook's way with an italic tag seems wrong to me, but I'm thinking it could be for a nominal efficiency gain? (less markup) – NerdCowboy Oct 02 '10 at 00:45
  • Yep that sounds more like an efficiency thing to me, both sites move huge amounts of web traffic, and especially with facebook using PHP over a compiled language, it's desperately important for them to minimize server load as much as possible. – Randy the Dev Oct 02 '10 at 00:47
2

This article addresses well the issue. This is an adapted summary.

When using sprites and fonts for icon representation (vs img or other inline imagery insertion techniques), there are two possible scenarios:

  1. When the icon is meant to enhance the text
  2. When the icon is meant to stand alone and be functional or informational

Case (1) solution:

Accomplishes its goal by showing the icon on most cases, not using the i tag for the wrong purpose (semantic) and being unobtrusive for screen readers. And you can use class instead of the data- attribute if you prefer.

/* HTML */
<h2 id="stats">
  <span aria-hidden="true" data-icon="&#x21dd;"></span>
  Stats
</h2>

/* CSS */
[data-icon]:before {
  font-family: icons; /* or use background-image instead */
  content: attr(data-icon);
  speak: none;
}

Case (2) solution:

Similar approach as before, but here the icon would have a fallback solution for screen readers.

/* HTML */
<a href="#rss" class="icon-alone">
  <span aria-hidden="true" data-icon="&#x25a8;"></span>
  <span class="screen-reader-text">RSS</span>
</a>

/* CSS */
.icon-alone {
  display: inline-block;
}
.screen-reader-text { /* Reusable */
  position: absolute;
  top: -9999px;
  left: -9999px;
}

Summary:

  • Semantically correct
  • Accessibility friendly
  • Future proof (you could always select uniquely down the line even if you change the character)
Oriol
  • 11,660
  • 5
  • 35
  • 37
1

I like keeping most of my icons as background images and padding the text off from the left to adjust. When there's something that needs attention (such as a warning), you pretty much need a text-based method to convey that information for accessibility's sake, even if you find ways to hide it in the CSS.

I'm against using spans or other elements because it's just not semantic and they aren't necessary.

When I'm building sprites, I always make sure to keep all the icons on the right edge of the sprite so they never have the opportunity to expose rogue sprites (and for variable height issues, you either have to give them plenty of space to grow or put them bottom-right).

Marcus
  • 460
  • 7
  • 17
  • This is generally the method I've used, but dealing with having to move icons around and giving extra spacing in the sprite just seem to make maintainability harder than it should be. And correct me if I'm wrong, but you can make the span icon method semantic by actually having text within the span, but using text indent to hide it. I've personally found using spans adds some extra HTML markup, but has reduced my CSS markup. And it seems to be a pretty popular method among larger sites like Google, Amazon, and even the Stack Exchange sites; so that might add some credence to it's efficiency. – NerdCowboy Oct 03 '10 at 22:15
0

The way I would pursue this issue would be by, saving your entire icon set in one image sprite and than call each image on a per-need basis.

For example:

Stackoverlow does something similar by saving all their icons in one sprite like so:

http://sstatic.net/stackoverflow/img/sprites.png

And then it's a simple matter of defining classes for each image with the appropriate background-position that way you can also semantically set appripriate padding and sizing for each individual icon.

All this also ensures a quicker loading of icons.

Russell Dias
  • 70,980
  • 5
  • 54
  • 71