Fun with localization, pseudo-elements, CSS variables and the Umbraco backoffice

Last updated: 20 August 2021

Not everyone who uses the internet (and the products it houses) speaks English. Shocking, I know.

To that end, Umbraco ships with a suite of tools for localizing the backoffice - AngularJs directives and services, C# services, dictionaries and so on.

For this quick case study, I’m looking at how to make the backoffice play nice in a very particular scenario, which looks like this:

  • Plumber has features which are disabled on the trial license
  • These features are visible in the backoffice, but are obscured by a notification re requiring a license
  • This is achieved with a pseudo element, which includes the text in its content attribute
  • The pseudo element is shown based on a class on its parent element, which is applied via an AngularJs directive, which checks the current license type

The disabled properties look like so:


All good and dandy, assuming you understand English. If not, you’re looking at an otherwise fully localized backoffice, but with one weird blob of text obscuring a control.

Because the text is set in the CSS, it’s outside the scope of any of the Umbraco localization tools. At least, it might appear to be…

To localize the content string, I’ve done this:

First, in the aforementioned directive, get the localized string via the localizationService:


In the callback, I can write the localized string to a CSS variable:

.then(message =>'--plumberNoLicense', `'${message}'`);

Note the formatting on the property value - without the quotes, this doesn’t work.

Once the localized string is available as a variable, my CSS can use it in the pseudo element, and bingo, localized values in CSS:

.overlay::before {
  content: var(--plumberNoLicense);
  // other stuff to display the overlay

With all the pieces in place, I can ship the CSS which knows nothing about the value it will eventually display, other than the variable name.

Umbraco can localized the string as normal, then it’s written out to the document’s stylesheet as a variable, and Bob’s your mother’s brother.

This might seem trivial, but if you’re building a product with a global userbase it’s critical to provide an equitable experience for all those users - localizing your UI is just one piece of the puzzle.

Note: if you’re thinking this sounds like an incredibly naive way to protect licensed features, don’t fret. This is a bit of UI chrome - the restricted features are all validated client and server side when saving changes. The intent here is purely to make ‘em look pretty in any language.

Note note: Backoffice? backoffice? Back Office? BackOffice?