RTL management HTML & CSS 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 &lt;body&gt; 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 &lt;span&gt; and &lt;div&gt; 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 a transform 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?

Helpful links

https://alfy.me/2014/07/26/lets-talk-about-rtl.html
I found a case where the solution #3 doesn't work : when you're dealing with scroll bars.

In your example, if you put a container smaller than the content, the scrollbar behave strangely in RTL, scrolling right when you press the left arrow and vice versa.

The same thing happen when you press the mouse's middle click and move to any horizontal direction.