Ridding markup of textual decoration
On the Web it's not uncommon to see characters with no inherent meaning used for stylistic reasons. A good example is the Read more » link. Perhaps the directionality of the "»" is suggestive of travelling to another page, or perhaps the letterform is included solely for its aesthetic appeal. Whatever the case, one thing is certain: links do not require right-pointing double angle quotation marks in order to function.
The inclusion of such a character is therefore a design decision. It is decoration, not content. It belongs in a style sheet, not in a page's markup.
Adding decorative textual content via CSS
The content property is extremely powerful. It's used in conjunction
with the :before and :after pseudo-elements.
<a class="more" href="/meaningful-markup/">Read more</a>
.more:after {
content: " »";
}
There are many other situations in which :before/:after and content can
team up to great effect. Often sites have footer links separated by "pipes".
These pipes commonly appear in the site's markup. This is wrong! Last week
I was horrified to discover that Bitbucket is guilty of this. I've since
rectified the situation (although the change is yet to go live).
.footer-nav li { display: inline; list-type: none; } .footer-nav li+li:before { content: " | "; }
The second selector above may look strange unless you're familiar with this
approach. By using li+li we target every li inside .footer-nav except
the first.
Another case in which there's a temptation to mark up content in a certain way in order to achieve a certain visual appearance is the comma-separated list.
<p><strong>Tags:</strong> Apple, iOS, iPad</p>
This approach is inflexible. Displaying the tags as Twitter-style hashtags, for example, would require fiddling with the markup. Adding a tag icon beside each tag would require rewriting the markup completely.
A better approach would be to let the content dictate the markup used. Since we have a list of tags, we should use a list of some sort. Since the list is in non-arbitrary order (alphabetical), an ordered list is probably appropriate. "Tags" is a heading that relates to the list of tags.
<h4>Tags</h4> <ol> <li>Apple</li> <li>iOS</li> <li>iPad</li> </ol>
It takes a bit of work to display this markup as a simple comma-separated list, but it gives us the freedom to dramatically alter the list's appearance without touching the markup.
h4, ol, li { display: inline; } h4:after { content: ":"; } li:after { content: ","; } li:last-child:after { content: ""; }
Summary
When marking up content, one should use the elements which best describe
that content. Styling content is a separate (though not unrelated) issue.
With :before, :after, and content at our disposal, let us bid farewell
to <span class="pipe">|</span> and friends.
Possibly related posts
- Prototype image slider
- Captions over images
- Valid XHTML alternative to
<strike> - Sticky footers
- Changing the colour of list bullets using CSS
Comments
Great post!
It has to be asked, though: how good is the cross-browser support for all of these selectors?
Excellent point, Tim. Sometimes I need to be coaxed down from my ivory tower. A quick perusal of QuirksMode suggests that versions of Internet Explorer older than IE9 struggle with pretty much everything in this post. I have high hopes for IE9, though, so it should be safe to use this approach by 2018 or so.
The only problem I see with this, is that you can't select the text like it is displayed. (At least not in Chromium 7.)
The |, : and , get lost.
Interesting observation, Mike. Ultimately, when copying an ordered list I would like the markup's structural semantics to be preserved.
1. Apple 2. iOS 3. iPad
I'd rather have the above sent to my clipboard than "Apple, iOS, iPad", although I agree the latter is preferable to "Apple iOS iPad".
At the end of the day it's important to remember that web development is more art economics than science. Trade-offs abound, and we must use our experience to make considered, pragmatic decisions.