css generated content pt1/blending the boundaries

published on:
April 23, 2008 / 13:03
comments

One of the things that had me bothered for a while were visual separators. Whenever I got a design, there were always some silly pipes or > signs that were added to visually separate elements in a horizontal list. I'll try to explain why I think they are so bothersome, and what options we (are supposed to) have to implement them as good as possible.

generating electricity

why it bothered me

The problem with these separators is that they are in fact simple characters, but they don't belong in the source of the document because they function as visual separators. When you put items in a list, those items are already separated by the li tags. So when you decide to add visual separators, they should be defined in css. That's where all design elements belong after all. On the other hand, cutting 1px pipes in PhotoShop is not really fun either.

My blog made the problem even bigger. Not only did I have to cut the characters into images, I had to make them three times (for each section a different color). And whenever I should choose to change one of my base colors, it means redoing a whole lot of images.

And so the challenge was to find a way to define those separators in css without cutting them as images.

finding the tools: the content property

{content:"|";}

First off, I needed a way to insert characters into the design through css. This might sound like a contradiction, as css was built to do exactly the opposite (separate content from design). Point is that these characters are not content and shouldn't be considered as content. These characters have a single design purpose, and generating them from css as actual content gives us the advantage that they can be styled.

You might already know the content property from elsewhere. It's used in the notorious clearfix class, which was the first time I came across this property. I never quite understood why they should want to insert content through css, but this is probably a very good reason to do so.

Now that we know how to insert our content, we still need a place to insert this content into. So on to the next bit.

finding the tools: the pseudo-elements

li:before {content:"|";} li:first-child:before {content:"";}

Our content property will only work with pseudo-elements. Which is no big deal, as this is exactly what we need. If you consider the code above, you'll see that this is all the code you need to provide a horizontal list with separators between each element. A very simple and elegant solution.

The biggest gain is that we can now simply style the pipe characters in css. We can change font and text properties to style it the way we want it, keeping all the styling power in the css file.

As for my blog, it meant writing two lines of css code and three lines to differentiate between the colors for each section. A whole lot easier than cutting from PhotoShop files, and a lot easier to maintain too.

You can check out the testpage if you wish to see it in action.

the bad and the ugly

You might be wondering why this technique isn't more widely spread, but I'm sure you can already guess the answer. IE does not support both pseudo-elements, so there's no way to apply the content through css. You can still use this method for Firefox, Safari and Opera and apply the images through the IE-only stylesheet (which is what I've done). But in the end this means even more work and even more trouble maintaining everything, so it has little real-life use I'm afraid. Yet.

the good

Still, I think this is an important technique worth knowing about. IE dominance is slowly fading, IE8 will support pseudo-elements and by the time the other versions have faded completely you should have no trouble switching to the better technique.

Working like this gives you some serious benefits and flexibility, so let's hope we can start using this technique as quickly as possible.

Comments

Jonas Drieghe

comment number
date
April 23, 2008 15:10

It's funny how almost every blogpost has the same structure:

  • i got a problem
  • i got a solution
  • this is why the solution rocks
  • it doesn't work in IE
  • IE .... please die :)

Niels Matthijs

comment number
date
April 24, 2008 13:42

Well, that's true for the articles where I try to describe modern css techniques. IE has been behind the times for quite a while when it comes to css. IE8 should hopefully fix this.

On the other hand, IE bugs are never critical as they can always be fixed in separate files. FF/Opera/Safari bugs on the other hand ...

But yeah, it would be nice if IE6 died. Quickly.

Nik

comment number
date
May 01, 2008 02:25

Well I think if there's enough padding between each list item, then it doesn't matter so much if the pipe / pseudo-elements don't display in IE. It's only a minor design element, which would be an extra nice touch only for people who use decent browsers. I mean, I wouldn't create an extra IE-only stylesheet just for that.

I will definitely consider using this technique next time.

Really interesting topic, thanks.

Michelangelo

comment number
date
May 01, 2008 17:16

Wouldn't it be simpler to use borders?

John Faulds

comment number
date
May 02, 2008 04:46

Wouldn't it be simpler to use borders?

That's what I usually do.

But to come back to the question of whether these separators are content or not, I think you could make a case for saying they are. If you look at the path to a folder /folder/subfolder/subsubfolder/ the separators are more than just visual decoration, they're part of the content to indicate that you're stepping down a level. So in the case where you're styling a breadcrumb trail, I think you could argue that the separators were part of the content.

Niels Matthijs

comment number
date
May 02, 2008 08:52

Using a border is a possibility, although you have little to no control over the height of the border (which is why I never use it). Also, I dunno if single borders render alright in all browsers when you increase the border-width.

Apart from that, the pipe is not the only character we use for visual indications. For example, signs like '>', and '<' are often used to indicate back/forward links.

But to come back to the question of whether these separators are content or not, I think you could make a case for saying they are.

There is indeed a grey area where you could argue whether a sign is content or not. I usually ask myself whether a user of a screen reader would benefit from the sign. And of course, it also depends on the mark-up used.

I believe that whenever a breadcrumb is created with ul/li's the separators become obsolete. If a breadcrumb is simply written inside a p tag or something, the separators become valuable characters.

Michelangelo

comment number
date
May 02, 2008 15:03

One thing to consider when using a character as link separator is: what does it sound like when voiced by a screen reader? See discussion on Standards Schmandards and elsewhere. I don't have a screen reader handy at the moment; judging from FANGS output it appears that the CSS-generated character is not pronounced, but I could be wrong. Can anyone comment?

Niels Matthijs

comment number
date
May 02, 2008 18:11

I actually wrote a little bit about that in the second part of this article. Also, I contacted someone who might be able to shed some light at that, so more about that after the weekend (hopefully).

Chris

comment number
date
May 03, 2008 12:51

For a horizontal list of links in a ul/li structure that requires the "pipe" character to seperate the links I just do this:

ul li { border-right: 1px solid colour; margin-right: 0.30em; display: inline; } ul li a {padding-right: 0.30em;}

Been using this technique for ages and works fine. If you're concerned about the height of the seperators then you can play with the css line-height property.

Yes IE6 needs to die! Horrible horrible thing!

Jordan Clark

comment number
date
May 11, 2008 22:10

I personally can't wait until IE supports generated content; it is a very useful part of CSS and I use it quite a lot.

One thing I'd like to know is how screen readers handle generated content - do they read it out or not? There is not a lot of information available on this matter; in fact, at the time of writing, a Google search for the keywords screen readers css generated content returns this article as the top result (with part two a close second).

Seth

comment number
date
June 08, 2008 21:10

"The problem with these separators is that they are in fact simple characters, but they don't belong in the source of the document because they function as visual separators"

This I do have to disagree with, the vertical pipe character is, contrary to popular belief, is NOT just a visual separator, the purpose of these and other physical character dividers is to prevent adjacent hyperlinks from having nothing more than a whitespace separator as this comes out poorly for screen readers and other assistive technologies, separation of your adjacent hyperlinks is also one of the points for W3C WAI WCAG, the vertical pipe is the recommended seperating character but it doesn't have to be the separator used.

Creating a pseudo effect using borders as one poster has done above in reality is really no better than just not separating links at all, although in this case it literally becames merely a visual aid only, since the border is a CSS property it is not a physical character to separate the links from each other, therefore screen readers will have the same problems with the border technique as they do with links without any "separation".

In terms of generated content behaviour in screen readers, I don't think you can reasonably get a definitive answer on that or not as there are numerous assistive technologies and just like visual use agents they will each have their own pros and cons. To be honest I would continue to use the vertical pipe and not rely on generated content, if Microsoft couldn't be arsed to add support for it it's a relatively safe bet to assume that some if not all of them probably don't support generated content, at least not without limitations so I wouldn't rely on it for this purpose, plus also thanks to IE being the useless piece of crap that it is, the generated content provides no separators for the IE users.

Unfortunately as much as we'd all like to give Microsoft the finger and just deny access to IE with a message of "Since Microsoft refuse to support the web standards, we now refuse to support Microsoft. Get Firefox - The browser IE pathetically attempts to live up to", unfortunately we can't just cut off 50% of internet users, which is why the vertical pipe character is used.

Niels Matthijs

comment number
date
June 09, 2008 12:17

the purpose of these and other physical character dividers is to prevent adjacent hyperlinks from having nothing more than a whitespace separator

You are right if you're not using a list or other structural ways to separate these links. But if you are (like I did in my example, and which I always do when I have a list of links) the pipe character really is nothing more that a visual separation, in which case it doesn't belong in the source.

salsanat.net

comment number
date
July 21, 2008 16:14

is it possible to add links like <a href='xxxx.com'></a> with content property into page?? I am trying to manage this but it seems it only creates text content and not possible to open html tags..

Niels Matthijs

comment number
date
July 22, 2008 10:45

Nopes, there is no html support whatsoever. It wouldn't be very feasible either I guess, inserting html through css, as its intended purpose was quite limited from the start.

Is there a reason why you would do this ?

salsanat.net

comment number
date
September 16, 2008 11:02

@Niels Matthijs yes there is a good reason, but it is very sneaky =]

paul

comment number
date
December 22, 2008 00:24

To Chris in comment #9:

Your solution with the ul/li and border instead of pipe solution is really nice but the problem is at the very last li menu item the border on the right gets added even if there are no more menu items... How to avoid this and just get the border (pipe) between the menu items ?

Niels Matthijs

comment number
date
December 22, 2008 07:58

Paul: you can fix that by applying an extra class to the last (or first, depending on whether you have a left or right border) li item. Then you can just say:

ul li.last {border:none}

If you want to do it through css alone (but with shakey IE support), you can write:

ul li:last-child {border:none}

Jethro Larson

comment number
date
December 30, 2009 19:28

I really like the the content property. I think it can add a lot of value through stylistic content. I've used it extensively on my portfolio, http://jethro-larson.appspot.com (under construction), to add css-like styles to the content without making the actual content retarded.

I've used the content property with stylish to mark external links:

a[target="_blank"]:after{
  padding:1px;
  margin-left:.2em;
  content: "\2750";}

I only recently figured out how to add special characters in the content property so I've only begun to play with it.

I know I can't yet rely on this technique in professional applications, but for mock-ups, personal applications, or simply cosmetic stuff I think it's a really cool option.

@Jonas lol, yes IE please die!

Niels Matthijs

comment number
date
December 31, 2009 09:21

Hey Jethro,

nice implementation of the css content attribute. The characters would indeed look out of place in the html and using images would be a much bigger hassle. It's nice to see this kind of experimentation :)

Jethro Larson

comment number
date
January 16, 2009 21:58

Heh. I went through a stage of hating my portfolio and removed most of the generated content.

My portfolio should at least look similar in IE :)

* required fields

Leave your data
Leave a comment