--- title: Automatically creating RTL CSS date: 2016-06-04 tags: [code, css, a11y] description: Most western scripts are read from left to right (LTR), so this is what many web developers think about when writing CSS. But some scripts, such as Arabic or Hebrew, are read from right to left (RTL). --- ## What is it and why does it concern me? Most western scripts are read from left to right (LTR), so this is what many web developers think about when writing CSS. But some scripts, such as Arabic or Hebrew, are read from right to left (RTL). But it is not only about the text direction. The complete layout should also be mirrored to match it. So say you want to write CSS that can be used with both text directions. What do you have to think about? ## The problem HTML and CSS have advanced support for different text directions. You can use the [`dir` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) to specify text direction and the [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi) and [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo) elements allow for fine-grained control. The only issue is that `left` and `right` are actually physical directions and will not change with text direction, so any `float: left` or `margin-right: 1em` will not adapt with the text direction. ## The solution Just as relative units such as `em` or `%` are better than absolute `px`, relative directions like `start` and `end` are preferable to `left` and `right`. Unfortunately, they are not (yet) available. But the W3C is working on it and `start` / `end` are already available for the [`text-align` property](https://developer.mozilla.org/en-US/docs/Web/CSS/text-align) in many browsers. ## The workaround As long as the proper solution is not available, here is a simple way to convert a LTR stylesheet to RTL. I am not exactly sure that this is the complete list, but it should be sufficient: - Replacing all occurrences of the string `left` by `right` and vice versa: ```sh sed 's/left/TMP/g;s/right/left/g;s/TMP/right/g' ltr.css > rtl.css ``` Just include this as a final build step, even after minification. - Avoid 4-value shorthands such as `margin: 0 1em 0 2em`. Instead, do something like this: ```css margin: 0; margin-right: 1em; margin-left: 2em; ``` 3-value shorthands are fine, as they use the same value for left and right. - Do not try to have only a single CSS file and write custom code based on descendant selectors. That will just make everything extremely complicated. - Do not try to have a LTR stylesheet and a second, smaller RTL stylesheet that only contains the necessary overwrites. The only case where this has any performance benefit is when users switch from one layout to the other. In all other cases this is actually worse, apart from being hard to maintain. ## Outlook: vertical text CSS3 will take the support for non-latin scripts even further and add support for vertical (e.g. top-to-bottom) text. Note however that most vertical scripts also have horizontal variants, so it is not completely necessary to support this feature anytime soon. One important thing to remember is that many new keywords from these specs use abbreviations such as `vertical-rl` for "vertical-right-left". But you probably should not mix that workaround with these new properties anyway. ## Further reading - - - - -