CSS attr, content, and L10N
I have the privilege of working for Mozilla on the Mozilla Developer Network (MDN). As with any Mozilla-made website, localization is paramount to MDN, so we must be mindful of that when we put text anywhere on the site. I was recently working on a feature which made use of CSS content: a visual notice on an element's pseudo-element which are experimental and only available to beta testers. The obvious problem in doing so is that hardcoding the generated content message in the stylesheet means I can't localize it; a definite localization taboo. The solution was simple: use the attr
expression to pull the localization message from an element's custom data-
attribute.
The HTML
Start by outputting the localized text to a data-
attribute:
<div class="beta-feature" data-message="{{ _('This feature is only seen by beta testers') }}"> <!-- some content here --> </div>
With the text available in an attribute, the CSS attr
expression and content
will be used to display the text in a pseudo-element:
.beta-feature:after { content: attr(data-message); /* formatting here */ }
The formatting is up to the developer but the main point is that we get to use the attribute value to display the variable text.
This post isn't groundbreaking and it's not meant to be; I just want to reinforce how awesome and useful CSS content
paired with attr
can be. I love that this strategy prevents the need to preprocess CSS files with the localized text, and love that...it's just so easy!
Hi, that’s really nice feature. It’s interesting for me, is there any other usage, different from the one that you showed. I’m asking because for me it looks like it’s just better to put the text inside the tag instead of adding it to the data-liked attribute.
I`m also curious, how is this preferable to putting it in the div normally? Using css to dictate content seems it violates the separation of concerns that CSS was meant to fix.
Realize that the message goes into a *pseudo-element*, not inside the beta element itself. The goal is for the message to be applicable to *any* element, so the pseudo element just allows me to hang text above the element itself.
Nicely flexible content/attribute set-up. Very handy way to create either a single message, or multiple, element specific messages and have them displayed, or not, per preference.
Another option is to use
data-*
attribute with a message key. With:lang
selector it’s possible to localize string for different languages. Also in this case you have message value inside of a css file that can be cached. Check out there: https://github.com/chemerisuk/formvalidation.js#internationalizationA good use for this is also to make a styled title (tool tip), using the
data-title
attribute, and content before to style it.Do the brackets in your message {{ _(‘This feature is only seen by beta testers’) }} have a special meaning? Or is it just your style of messages?
It’s django’s template code to localize the message into the user’s requested locale.
This is very useful for designers and frontend devs working on data-driven websites.
We’re always having to balance how much content to show or hide in a page. So far the best compromise is to show the essential information, then allow users to “expand” the object to view more details.
Most of us store that extra information in divs or spans or title attributes, which always seemed like a hack-y way to me. I always felt like the extra information should be a property of the element, and not an extra span or div nested and initially hidden inside the element.
I’m glad we can now harness the power of data-attributes with CSS!
Hey David, in case you need a good tool to manage software localization, I suggest the l10n platform https://poeditor.com/ for collaborative strings translation. I think it’s really nice.