CSS: How to Host Right-to-Left Styling
Published on September 30, 2010 (⻠February 5, 2024), filed under Development (RSS feed for all categories).
This and many other posts are also available as a pretty, well-behaved ebook: On Web Development.
This post is partially outdated.
For international projects, donât use separate style sheets for right-to-left (RTL) styling: use natural (@dir
) or artificial (@id
, @class
) hooks instead. The only exception are unbearable performance issues due to hundreds of RTL rules.
I recommended this earlier when sharing a few RTL tips but do only here explain in a bit more detail. A side note, the focus of the post lies on projects with a global audience whose majority reads from left to right. If you are working on a site solely and forever available in, say, Hebrew, Arabic, and Danish, you may want to base defaults on RTL and customize styling for LTR. You get the idea.
The reasons why you donât want custom RTL style sheets are maintainability and ease of use. I donât get tired saying that: From a maintenance standpoint you want to includeânote: you can still use moreâone style sheet in your documents, and that style sheet should use a reasonable name. The point is that you want to reduce the probability of updating CSS references, and that everybody on your team knows and remembers what style sheet to use.
So whatâs the deal with RTL styling?
<!DOCTYPE html>
<html lang="en">
<title>Test</title>
<link rel="stylesheet" href="default.css">
<p>This is only a test.
Letâs say you have a left padding on the paragraph.
p {
padding: 0 0 0 1em;
}
So whatâs the best way now to deal with your Arabic version of this page? (Machine translation to the rescue.)
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<title>ۧ۟ŰȘۚۧ۱</title>
<link rel="stylesheet" href="default.css">
<p>Ù۰ۧ ÙÙŰł ŰłÙÙ Ű§ŰźŰȘۚۧ۱.
The bit of padding youâre setting on your p
elements should appear on the right.
Now, the simplest solution is this:
p {
padding: 0 0 0 1em;
}
html[dir='rtl'] p {
padding: 0 1em 0 0;
}
The markup itself remains the same, the style sheet stays the same, no need for special documentation, no need for anyone to remember anything (except for, which kind of enforces itself, setting @dir
).
Unfortunately, some older user agents may not recognize the html[dir='rtl']
selector. If that is a problem for you youâll need an alternative hook, like
<!DOCTYPE html>
<html lang="ar" dir="rtl" id=ârtlâ>
<title>ۧ۟ŰȘۚۧ۱</title>
<link rel=âstylesheetâ href=âdefault.cssâ>
<p>Ù۰ۧ ÙÙŰł ŰłÙÙ Ű§ŰźŰȘۚۧ۱.
Not every flavor of HTML permits an ID on the html
start tag. HTML 5 does.
In order to cater for RTL, default.css would then simply say (until @dir
can be used instead)
p {
padding: 0 0 0 1em;
}
#rtl p {
padding: 0 1em 0 0;
}
As you will have noticed, complexity slightly increased: People working on these pages will need to remember to set the id="rtl"
hook in order to achieve proper styling. The modification is still simple and easy to remember, and weâre talking about a temporary markup modification, not a permanent one as custom RTL style sheets introduce them (an unfortunate practice âframeworksâ like 960 Grid System prefer).
In the case of separate RTL style sheets you will need to remember to use a different style sheet,
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<title>ۧ۟ŰȘۚۧ۱</title>
<link rel="stylesheet" href="default.rtl.cssâ>
<p>Ù۰ۧ ÙÙŰł ŰłÙÙ Ű§ŰźŰȘۚۧ۱.
and you will also need to maintain that extra style sheet. Iâll spare you examples for that, like what youâd need to do when changing the sample padding to 2em
.
In complex projects the impact of either practice is obviously bigger. You will also see practices emerge that exaggerate pain points. For example, Iâve worked on one large project in the past where an internal framework offered RTL functionality via a separate style sheet. Now that particular framework took care of basic styling and was not touched when developing custom sites, i.e. such sites included the particular framework plus an additional style sheet for the site itself. What I could observe was that some developers included the RTL version of the framework, but for additional styling they did not create an RTL version of the additional, custom style sheet, but set up RTL class names like .rtl_foo
for the RTL version of .foo
.
In other words,
- framework.css for the LTR framework
- framework.rtl.css for the RTL equivalent
- custom.css for both LTR and RTL customizations, with
.foo
for LTR.rtl_foo
for RTL
Imagine how such RTL documents looked like, and think about how messy it became to understand what was done, how, and where.
(The recommendation applied to this last case means a framework.css and a custom.css, and custom.css to use html[dir='rtl'] .foo
for RTL deviations.)
Donât use separate style sheets for RTL styling.
Update (November 11, 2018)
A late note, the situation improves with CSS Logical Properties; these avoid directionality inherent on the CSS side and with that make it possible to write style sheets that work with both LTR and RTL without modifications. (Logical properties are not necessary in unidirectional projects and therefore most useful in bi-directional projects.)
Update (July 27, 2021)
Interesting and relevant, too, is the :dir()
pseudo-class. Barely supported at the moment, it will likewise make work on bi-directional projects significantly easier.
About Me
Iâm Jens (long: Jens Oliver Meiert), and Iâm a frontend engineering leader and tech author/publisher. Iâve worked as a technical lead for companies like Google and as an engineering manager for companies like Miro, Iâm a contributor to several web standards, and I write and review books for OâReilly and Frontend Dogma.
I love trying things, not only in web development (and engineering management), but also in other areas like philosophy. Here on meiert.com I share some of my experiences and views. (Please be critical, interpret charitably, and give feedback.)
Comments (Closed)
-
On September 30, 2010, 17:08 CEST, David said:
Brilliant as always Jens! Very well explained and points well illustrated. Would be curious to know how UX is effected by simply flip flopping the layout, etc. Do RTL users follow a mirror copy of page scanning habits as LTR users? Future post perhaps?
-
On September 30, 2010, 17:33 CEST, Vladimir Carrer said:
Interesting concept, thank you for sharing.
-
On September 30, 2010, 19:03 CEST, Gabri said:
lately i was working on a Project that includes LTR & RTL styling and i used the same exact method you mentioned here using html[dir=ârtlâ] selector and it was very easy to use and to maintain.
-
On October 1, 2010, 5:32 CEST, Ali Sattari said:
As someone who deals with RTL on a daily basis, I would prefer to have an extra style sheet which contains only rules and properties that are affecting direction and simply override them.
That would be usually less than 5% of whole style sheet.
This way main style sheet is LTR, no need to use attribute selectors or extra ids or classes in markup and you get to load the extra style sheet just when it is needed. -
On October 1, 2010, 21:51 CEST, Jens Oliver Meiert said:
David, thanksâthe short story is, yes, you can pretty much flip the layout. However there are indeed a few more things to write about and you make me consider doing so đ
Ali, I see your point and I generally understand the logic to be tempting. I think the 5% you mention are realisticâmileage may vary, up to 15% Iâd sayâ, however that is something I see exactly as a plus when it comes to making an LTR style sheet RTL-ready. Focus on how much simpler it is to work with one style sheet, too (if you had only one before, youâd otherwise, in a way, double complexity). Not only does that one style sheet come with a few maintenance advantages but itâs also just easier to use. I guess Iâm about to repeat what I wrote before.
-
On October 5, 2010, 14:34 CEST, Hassan said:
I use WordPress, and it automatically link the rtl.css file if itâs present. I think itâs the simplest way. Most of the time it doesnât get larger than 20 or 30 lines.
Read More
Maybe of interest to you, too:
- Next: The Secret of Web Development
- Previous: On Solutions
- More under Development
- More from 2010
- Most popular posts
Looking for a way to comment? Comments have been disabled, unfortunately.
Get a good look at web development? Try WebGlossary.infoâand The Web Development Glossary 3K. With explanations and definitions for thousands of terms of web development, web design, and related fields, building on Wikipedia as well as MDN Web Docs. Available at Apple Books, Kobo, Google Play Books, and Leanpub.