August 15, 2013

CSS generated content is cool. You can make those little triangles everyone seems to love, but its real purpose is to let you add presentational words that would otherwise be a pain to generate in markup for some situations.

a:before {
  content: 'Download item';
}

It can do other neat things like output the contents of another attribute on your element. This feature was originally created to allow print stylesheets to display URLs inline for printed documents:

a:after {
  content: ' (' attr(href) ')';
}

But what happens when you need to bring multilingual into the mix? We occasionally build multilingual sites, and typically there is translatable content at every level of the stack: Drupal nodes, template files, CSS, JS, you name it. When I was originally tasked with solving this it seemed like a big problem, but it turns out to be relatively simple.

My initial thought was to use the language attribute of html tag and make individual, static content properties, but that leads to code bloat as you accommodate each new language. Furthermore, in Drupal’s case, it leaves your strings stranded in CSS and inaccessible to translators which have an interface built into Drupal’s admin UI.

Solution: Dynamically generate attributes

We had a client who wanted the links to be big CTAs accompanied by the instructions “Download item.” So instead of hardcoding the English words into my stylesheet, I added a data-attribute into the DOM via JavaScript (you could also do this in Drupal by creating or modifying the appropriate field.tpl.php, but I did some other things with JS so it was simpler to keep it all in one file).

$('.my-field').attr('data-cta-msg', Drupal.t('Download item'));

Notice Drupal.t in there? t is for translate, and it is the standard mechanism for localizing JS-powered UI components in Drupal 6, Drupal 7, and Drupal 8. There’s a bit of background magic that happens, but in a nutshell once a page containing your new Drupal.t() string has been loaded, you can access it in the Translate interface in the Drupal admin UI:

Drupal 7 interface for translating non-content/UI strings

Now you can grab a translator, add the appropriate text, and your stylesheet will always supply the correct translation in your CSS generated content! Look at the minor modification to CSS content property (compare to the very first example in this article)

a:before {
  content: attr(data-cta-msg);
}

And here’s the result in English and Arabic respectively:

English download button with CSS generated content

Arabic download button with CSS generated content

Update: Down in the comments Dan Mouyard pointed out how any CSS generated content is less accessible than real markup. Just a heads up for general use of CSS content that is intended to be read aloud on the page, not just the multilingual method described in this article.

Chris Ruppel is a frontend developer who makes websites load fast and shrink on your phone. Although he's a native Texan, Chris currently lives in the beautiful town of Freiburg, Germany

Comments