Automating RTL CSS

When a site needs right-to-left (RTL) support for languages such as Arabic, Urdu or Hebrew, the general rule is all styles should be “mirrored”, so the page flow matches the experience in left-to-right (LTR).

At first this can seem like a daunting task, since all CSS specific to left or right needs to be swapped, along with the entire layout of the page.

The best place to start is by adding dir="rtl" to the opening <html> tag at the top of your markup. This indicates to the browser that the text flow should be presented the opposite way.

Automation

Enter CSSJanus, an npm package based on a project originally made by google, designed to automate the conversion of LTR CSS to RTL.

CSSJanus is a CSS parser utility designed to aid the conversion of a website’s layout from LTR to RTL. […] CSSJanus will change most of the obvious CSS property names and their values as well as some not-so-obvious ones.

Google Code Archive - CSSJanus

In order to make use of the package, I put together a simple node script and hooked it into my npm scripts workflow.

In my npm scripts compiler post, I covered the basic idea of using minimal single-use scripts in sequence to automate stuff. To get this script in place, it was just a case of adding the custom script to the end of the main build script.

For reference, here’s the node script I made for the job:

// Dependencies.
const fs = require('fs');
const path = require('path');
const cssjanus = require('./node_modules/cssjanus');

// Source the ltr stylesheet.
const ltrCss = fs.readFileSync(path.resolve(__dirname, './style.css'), 'utf8')

// Run CSSJanus.
const rtlCss = cssjanus.transform( ltrCss );

// Output rtl css file.
fs.writeFile("./rtl.css", rtlCss, function(err) {
	if(err) {
		return console.log(err);
	}
	console.log("RTL CSS generated.");
});

Manual tweaks

I found CSSJanus did the trick for most styles, however in some situations a default opposite was needed, so when cssjanus did it’s thing that style could be swapped.

For example, if something is being set with absolute positioning left: 10px, then setting right: auto in the same selector allows for the styles to be swapped automagically.

If the styles are in plain css, the built in /* @noflip */ flag can be used to have a style ignored by CSSJanus. This is detailed on the npm package readme.

In some cases, an extra little hack can be used by making use of dir property. It’s specificity will be higher, making it easy to override other styles.

[dir='rtl'] {
	float: left;
}

Further reading

CSS Janus web tool
Mozilla MDN web docs - direction property
w3.org Structural markup and right-to-left text in HTML