When creating a multilingual web page you might need to handle languages written from right to left. This comes with some design issues.
First, you must add the dir
attribute to your root (<html>
) element. But the dir
attribute alone cannot tackle everything. Sometimes you might have an image next to a paragraph, and a margin-left
spacing them out. When you switch to the rtl language, you end up with a paragraph with a left margin, and an image stuck on the right side of it.
I will show you two ways that I have used to solve this problem.
Using CSS variables
The first way I thought was using CSS variables and some calculations to play with the left margin.
html[dir="ltr"] {
--ltr: 1;
--rtl: 0;
}
html[dir="rtl"] {
--ltr: 0;
--rtl: 1;
}
p {
margin-left: calc(var(--ltr) * 20px);
margin-right: calc(var(--rtl) * 20px);
}
What I do here is assign a number (0, 1) to the "boolean" variables --ltr
and --rtl
, declaring which direction is enabled. When the dir
changes, the variables swap values. Then I calculate the left and right margins by multiplying the variables with the desired pixel value. So in ltr the left margin will be 1 × 20px = 20px
, and the right margin will be 0 × 20px = 0
. When we change to rtl the margins will swap values.
Using modern CSS
This is a clever way of setting the margins based on a boolean enabled/disabled variable. But, there is a better way by using modern CSS.
p {
margin-inline-start: 20px;
}
And that's it. Way less code, and more elegant. It actually instructs the browser to add a 20px margin at the "start" of the x-axis. The start of the x-axis is relative to the direction set by the dir
attribute. So in this case the browser will set a 20px left margin on ltr direction, and a 20px right margin on rtl direction.