Generating a rtl.css files is something I don’t enjoy doing. I think it’s really important that they are created since a large proportion of the world uses rtl (right to left) languages. But they are a bit of a pain to create and maintain. In fact I tend to create the file for the theme release, and then not update it (mostly because I forget). As such I have been looking for a way to automate the process for quite some time.
I now have a method that works and I am happily using it in 6 themes, and plan to add more of them as I go.
The biggest benefit of using this Gulp system is that my themes will stay up to date. I can update/ improve the theme styles and then the build process makes sure the rtl.css stays up to date.
The Problem
Gulp has a number of plugin that flip css styles – however what this does is generate a css file that contains all of the css rules your site uses, with right switched to left (and vice versa). But that’s not what WordPress uses.
A WordPress rtl.css file should just be the flipped rules – not all of the rules. WordPress includes the rtl.css in addition to the style.css file – so you want it to be small and efficient. So my problem was that I wanted to replicate the WordPress behaviour.
Warning: It’s Messy
Looking at the code now – I can say that this probably isn’t efficient – and it’s definitely not pretty! But it works for me so I don’t care.
One thing I noticed (that I had forgotten about) when writing this article is that I am using CSSComb, CSSNano, and Autoprefixer. They do very similar things and there’s probably some crossover. In fact I could potentially refactor the code to remove at least one of these plugins. But since it all works, I’ll save that for another day.
The Codes
Gulp plugins
First we need to install some Gulp plugins. I am using: Gulp (naturally), Gulp Util, Gulp CSS Flipper, Gulp Change, Gulp CSSComb, Gulp CSSNano, Gulp Autoprefixer, and Gulp Rename.
The following commands will make sure they are all installed in your project (using npm – more on that here):
npm install --save-dev gulp
npm install gulp-util --save-dev
npm install gulp-css-flipper --save-dev
npm install gulp-change--save-dev
npm install gulp-csscomb--save-dev
npm install gulp-cssnano--save-dev
npm install --save-dev gulp-autoprefixer
npm install gulp-rename --save-dev
The Gulp Task
So let’s start with the Gulp task, and run through the difference commands being executed.
We start with getting the selected theme from the command line parameter. I explained this in the previous article about creating a Text Domain checker.
We then set start the task proper.
- First select the themes style.css file as the task source.
- Next we flip it using CSS Flipper. This is a wrapper based on Twitters CSS Flip library. On it’s own it flips the style.css file so that everything is mirrored.
- Next we use the change plugin to tidy the css. This just adds some line breaks to make things easier to manipulate in the next function. (BTW – I think the change plugin is awesome – I use it a lot).
- The change plugin again – this time executing the custom rtl function. I’ll go through this in the minute but basically it strips out any css that doesn’t change between languages.
- Next we autoprefix. The rtl function we just used doesn’t support browser prefixes so this adds them back.
- CSSNano now to minify the css. The important part of CSSNano is that it deletes empty selectors – something the custom rtl function will have created.
- CSSComb to reduce and tidy the css used. I could potentially use CSSNano for this but I don’t like how it prettifies the CSS. Note that you will need a CSSComb settings file to ensure the css is output as you like – I used this.
- Rename the output file to rtl.css – otherwise the style.css file would be overwritten.
- Then set the destination location (the theme directory).
cssRTL
This is the function that does the most complex bits. It took me a while to work out how it would work. At times I was considering finding some sort of CSS parsing library, or something else I could reuse to save me time. Eventually I hit upon the idea of using the ‘change’ plugin, and simply dropping any css properties that are not appropriate.
So, I grabbed the list of css properties from the CSS Flip docs and turned it into a javascript list. I then split the transformed rtl file into an array (based upon line endings), and looped through all the lines. I then create a new array storing only the css selectors, and the properties that have changed. This does end up with some empty selectors being left – but that’s what I use CSSNano to clean up.
You’ll notice at the end there are a few string replacements done. This is to get rid of properties like text-align: center;
that don’t need to be mirrored whilst keeping text-align: left;
and text-align: right;
.
Things to Keep in Mind
This whole thing is working really well for me, but there are a few things I need to keep in mind when developing.
The biggest thing is how I structure css. I have to make sure that any time I use margin-left I include margin-right, or I use a full margin declaration. The reason for this is that the CSS flipper will flip margin-left to margin-right (what we want) but since rtl.css is added on top of style.css the original rule will still exist. So we have to declare both rules, even if they are inherited from the defaults, so that the opposite value is reset accordingly.
In addition – you will find times when you don’t want to flip a rule, or when you want to replace a rule with something else (for instance arrow images in a slider that should change direction). CSS Flip has you covered here– simply add a special comment before the rule you want to change (or not change) and CSS Flip will make the relevant changes when flipping.
Finally – for testing, I use the RTL Tester plugin to make sure everything is flipped as expected.
Conclusion
In my experience using this, and the Gulp Task above, I can get a new RTL file working in a half an hour or so per theme. And, as I mentioned before, once I’ve done it once it will continue updating. So as I tweak and improve the CSS in the LTR version of the theme, the updated RTL files remain up to date.
Was it good/ useful/ a load of old rubbish? Let me know on Mastodon, or BlueSky (or Twitter X if you must).
Link to this page
Thanks for reading. I'd really appreciate it if you'd link to this page if you mention it in your newsletter or on your blog.