Keeping code clean with content

The CSS content property is one that has been around for a while. It’s not new, nor is it particularly ground-breaking. It is however, at least in my opinion, extremely useful and extremely underused. For those not in the know, content sets, well, the content of an element via CSS. That is to say it gets rendered in the page but doesn’t appear in the markup. Coupled with the :before or :after pseudo-elements you can prepend or append content to an element respectively:

/* Add a pilcrow before paragraphs */
p:before{
  content:"¶ ";
}
/* Add a bullet after the last paragraph */
p:last-of-type:after{
  content:" •";
}

The benefit of this is that things that are technically stylistic that could only really be placed in the markup in order to make an appearance can actually be ‘injected’ into the page through CSS. This keeps your code free from any stylistic markup that adds non-semantic value, and means that any markup-like elements are added through the stylesheet.

A particular example I have been using lately is simply:

<!-- Markup -->
<dl>
  <dt>Name</dt>
  <dd>Harry</dd>
  <dt>Age</dt>
  <dd>20</dd>
</dl>

/* CSS */
dt:after{
  content:":";
}

The great thing here, and this is extremely die-hard web standards and semantics, is that an item’s title is not technically ‘Name:’ or ‘Age:’, rather it is just ‘Name’ and ‘Age’. The colon is, if you are being very anal, just stylistic.

Also, another benefit is data-purity in a database. Imagine, for whatever reason, you’re populating that <dl> from a database, you might end up storing ‘Name:’ and ‘Age:’ in there as opposed to the more clean and accurate ‘Name’ and ‘Age’. Either that or your markup might look something like:

<dl>
  <dt><?=$userNameTitle; ?>:</dt>
  <dd><?=$userName; ?></dd>
  <dt><?=$userAgeTitle; ?>:</dt>
  <dd><?=$userAge; ?></dd>
</dl>

Notice the trailing colons on the <dt>s? This can be avoided simply by utilising the content property.

Encoding

One point I will make is that, for certain symbols, you might need to encode them in the CSS file. If you know the symbol’s numeric value (e.g. an em dash is &#151;) simply fire it into this converter and paste the result into your CSS:

h2:after{
  content:"\0097"; /* Add an em dash after headings */
}

By Harry Roberts on Monday, September 27th, 2010 in Web Development. | 10 Comments »

+

10 Responses to ‘Keeping code clean with content


  1. Francesco said on 27 September, 2010 at 9:41 pm

    I love it, and I’ve been using it for a long time, now.

    It must be noted that IE6 (and maybe even 7? Can’t remember) doesn’t support it… but who cares, as long as it’s stuff that’s not exactly essential like a colon or similar things?


  2. John said on 28 September, 2010 at 5:59 am

    This is surely one great method, but how does it stand when you talk about separation content from presentation?


  3. Ian Thomas said on 28 September, 2010 at 10:48 am

    John, I think it’s fine when talking about separating style and content as in the cases shown above the content added is purely there for styling.

    This is a nice little technique and is something I’ve been using for a while as well.


  4. Jacob Rask said on 28 September, 2010 at 1:46 pm

    I think it is great for Next/Prev link arrows as well, adding ” and “. That way, if you’d want to replace it with images or remove the arrows completely for a new design, that’s in the CSS as it should be.


  5. Andrew Male said on 29 September, 2010 at 6:28 pm

    Another underused yet highly effect CSS property. Great article I will definately be making much better use of this in the future.


  6. Gaurav m said on 30 September, 2010 at 5:09 am

    Thanks for sharing the converter link too : )


  7. webegg said on 5 October, 2010 at 8:31 am

    Love the idea, the only thing that stops me using this and other pure css techniques is simply the fact they don’t work in all browsers. For real world client work for clients who do notice these things, using a solution like this can often create problems later down the line where you might have to change every template on the site you’ve built.
    A server side solution using a global variable to set the character would be more of a real world solution, that way, if the client does change their mind, it is easier to reset it site wide.


  8. J. Hogue said on 12 October, 2010 at 5:05 pm

    Agree with webegg above… I’d love to use this more, but it is not a very backwards compatible declaration. According to Quirksmode (http://www.quirksmode.org/css/contents.html) IE 6, 7 and 8 ignore not only the :before and :after pseudo classes, but also the :first- and :last-of-type. When IE9 clobbers all other IE browsers, then these rules will be more universally acceptable by the mainstream. Older IE versions are holding CSS back big time.


  9. Nicolas Gallagher said on 29 November, 2010 at 8:02 pm

    @webegg: There is no need to produce an identical looking experience across all browsers. Not all browsers have the same capabilities and examples like this are minor enhancements that will not negatively impact IE<9 users. Rarely will someone visit the same website in multiple browsers; rarely will someone notice that their visual experience is not identical to that of users of more modern browsers. The benefit of handling this kind of thing in the style sheet (rather than coded in the HTML) is precisely to avoid the need to change every template if stylistic changes need to be made.

    As an aside, :before and :after are pseudo-elements (as opposed to pseudo-classes); hence the ability to declare content and treat them similarly to if an empty SPAN was present in the markup


  10. Stephen Sweetland said on 2 December, 2010 at 10:22 am

    I like your reasoning. I agree that not all users on all browsers need to experience the same site. That said, a developer should be conscientious enough to decide between graceful enhancement, or degredation.

    What I’m saying is that care should be taken that a developer doesn’t make the bare site unusable or inaccessible just because the user is using a less compliant browser. After all in some cases, users have no control over the browser they use (at work, for example).

    Still, great article.

    #constructivecommentbrigade


Leave a Reply

Respond to Keeping code clean with content

Hi there, I am Harry Roberts. I am a 21 year old web developer from the UK. I Tweet and write about web standards, typography, best practices and everything in between. You should browse and search my archives and follow me on Twitter, 7,791 people do.

via Ad Packs