I've been working around a solution to easily manage LTR and RTL on the same interface.
The different solutions I knew at first:
- Override CSS according to direction.
- Use a program to transform your CSS in LTR to a new RTL file.
- Start from a
body { transform: rotateY(180deg) }
.
1. Override CSS according to direction
This solution is painful for developers. You have to think of overriding ever CSS that will not flip properly.
Such as:
.title {
float: left;
margin-left: 10px;
}
body[dir="rtl"] .title {
float: right;
margin-left: 0;
margin-right: 10px;
}
Note: Adding an attribute dir="rtl"
on the <body>
flips the whole interface, but you'll still need to override margins, floats, etc.
2. Use a program to transform your CSS in LTR to a new RTL file
This implies using an external program you didn't control to run on all your style files and then you have to make sure to send the LTR or RTL version accordingly to the client.
To me it felt quite unsafe to rely on this. I can't be sure it works 100% fine and it can be quite complex (from my point of view, I didn't dive into it).
3. Start from a body { transform: rotateY(180deg) }
This is the option I went for.
It felt a lot more pleasant. Almost everything is already working fine (in my test cases). I only need to work on text elements.
Here is what I came up with so far:
#app[x-dir="rtl"] {
transform: rotateY(180deg);
}
#app[x-dir="rtl"] input,
#app[x-dir="rtl"] textarea,
#app[x-dir="rtl"] img,
#app[x-dir="rtl"] video,
#app[x-dir="rtl"] iframe,
#app[x-dir="rtl"] h1,
#app[x-dir="rtl"] h2,
#app[x-dir="rtl"] h3,
#app[x-dir="rtl"] h4,
#app[x-dir="rtl"] h5,
#app[x-dir="rtl"] h6,
#app[x-dir="rtl"] p,
#app[x-dir="rtl"] label {
display: inline-block;
transform: rotateY(180deg);
direction: rtl;
}
#app[x-dir="rtl"] label input {
transform: rotateY(0);
}
#app[x-dir="rtl"] .rtl {
display: inline-block;
transform: rotateY(180deg);
direction: rtl;
}
Explanation
The only thing missing after flipping the whole interface is:
- I have to flip texts back, because they are wrong(flipped with the page).
- Add a
direction: rtl;
on each tag containing content that needs to be display as RTL.
What I'm doing:
- Generalizing as much as possible tags that for sure need to have RTL behavior and flipped back.
- Give the developer access to a class
.rtl
, for edge cases (eg: I can't guess if<span>
and<div>
contain text or not).
Note: I use an attribute x-dir=""
, because dir=""
flips the interface. I want full control.
Drawbacks:
- The only one I can think of: You can't add
.rtl
to an element that already has atransform
because it'd override. It is not additive.
Feel free to test around: DEMO
Questions
Can you think of any edge case I haven't thought of?
Is it a good way to go?
Any optimization?