In 2002, Mark Newhouse published an article “
Taming Lists ”, a rather interesting part of which he devoted to explaining how to create your own lists decorated with pseudo-elements. Almost ten years later, Nicolas Gallagher invented a technique that
uses pseudo-elements from sprites to create background images.
Today, based on the experience of the giants, we will try to develop this theme. We will discuss how to decorate elements without additional markup, using only the
technique of CSS sprites . The result will also work in Internet Explorer 6 and 7 versions.

Let's start with special characters
There are
many characters that we can use as images to create different markers. What can happen:

Example
These tokens (,,,) in the list above are created as follows:
HTML:<ul class="glyphs"> <li class="one">performance</li> <li class="two">usability</li> <li class="three red">maintenance </li> <li class="four red">accessibility</li> </ul>
CSS: .glyphs { list-style-type: none; } .glyphs li:before, .glyphs b { display: inline-block; width: 1.5em; font-size: 1.5em; text-align: center; } .one, .one:before { content: "\2660"; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<b>♠</b>'+this.innerHTML); } .two, .two:before { content: "\2663"; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<b>♣</b>'+this.innerHTML); } .three, .three:before { content: "\2665"; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<b>♥</b>'+this.innerHTML); } .four, .four:before { content: "\2666"; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<b>♦</b>'+this.innerHTML); } .red b, .red:before { color: red; }
How it works
- The value of the content property should point to a Unicode character in hexadecimal format (for IE, we use HTML entities ).
- Internet Explorer 6 and 7 versions do not support either :: before , nor : before , so we include characters through CSS expressions.
- Internet Explorer 8 does not support :: before , but supports single-colon entry.
- Note that ignoring compatibility with different browsers " there is no difference between both : before and :: before , and between : after and :: after . The syntax with one colon (i.e .: before or : after-child ) is used to describe both pseudo-classes and pseudo-selectors in all versions of CSS prior to CSS3. With the introduction of CSS3, to distinguish pseudo-classes from pseudo-elements, the first are written using a single colon, the latter using a double colon. "
- In Internet Explorer, the characters are wrapped in <b> elements, so we have the opportunity to somehow point at them and style them (you probably want to use classes for these purposes).
Notice that the CSS expressions we use here are no worse than those
we use to simulate min-width and the like . It is calculated once, which should subsequently lead to a slight increase in performance.
')
Display images through pseudo-elements
The main advantage of using a pseudo-element to display images is that it allows you to use sprites. In fact, this is nothing new, and many sites already use additional (so-called “garbage”) markup to achieve this goal. For example, Yahoo! Search uses the empty
<s> tag , and Facebook uses the
<i> tag . By following this path, you can create compact CSS sprites, without any blank areas.
The following two examples do not use additional markup based on the same sprite:

Both images below - the second icon in the sprite - are created using two methods, respectively.
Nicholas Gallohera Method
Styling a pseudo-element using a background image: #first:before { content: ""; float: left; width: 15px; height: 15px; margin: 4px 5px 0 0; background: url(sprite.png) -15px 0; }
New method using url () / clip
Use the content property to insert the sprite, which is then cut into the clip: #second { position: relative; padding-left: 20px; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = '<img alt="" src="sprite.png">'+this.innerHTML); } #second:before, #second img { content: url(sprite.png); position: absolute; top: 3px; clip: rect(0 30px 15px 15px); left: -15px; _left: -35px; }
If you are suddenly wondering why I use
position-absolute above, I explain: because the
clip property applies only to elements that are absolutely positioned.
New way: how does it all work?
- Instead of decorating the pseudo-element with any background, we use it to insert an image (through the content property)
- Using the clip property, we “cut out” only the part we want to display from the image. This means that there is no need to add empty space to the image in order to avoid displaying other parts of it (usually used as a background image for the larger elements).
- We compensate for clip values using the left and / or top properties.
If it is not necessary to crop the images, the images in the sprite should be aligned to the right or left edge for placement, satisfying the RTL / LTR context (
background-position: [left] [right] [vertical value] ). Another limitation will be the creation of sprites with images following each other (other parts of the image can also be displayed). In the process of
"cutting" the sprite, these nuances play no role, therefore, the pictures can be joined with each other.
See example below:

The advantages of this method over other
The style that is used when printingUnlike background images, these images are printed with the document (they are sent to the printer).
Style that is affordableUnlike background images, these images do not disappear in
high contrast mode in Windows or in
high contrast style sheets .
A style that works in Internet Explorer 8This method also works in Internet Explorer versions 6 and 7.
Note that an extra HTTP request can use
the data: URI scheme . Internet Explorer does not support data: URI schemes, but we can use
MHTML for Internet Explorer 6/7 , which will allow older browsers to understand them.
We decorate links with pseudo-elements
Nicholas Gallagher shows a
lot of interesting pieces that can be made using pseudo-elements. The only thing I added here is the use of
:: after in link styles, as in the example below:
CSS: .more, .more:after { white-space: nowrap; content: " \00BB"; background-image: expression(this.runtimeStyle.backgroundImage="none",this.innerHTML = this.innerHTML+' »'); }
A couple of words about usability.
You will have to accept the fact that all
content is displayed on the screen , and since there is no mechanism for assigning alternative text to images that are added through the content property, you should make sure that these images are used purely for decorative purposes. Otherwise, users simply will not have access to this information.
Additional material
You may want to visit the following resources:
FatCow Web Hosting Icons
ps Notes on the translation and greetings :) are received in PM.
pps In a couple of places I replaced the text with a picture, you can see a live example in the original.