Easier internationalization (Part 1 of 3)
2024-07-06
A really important part of making a site or app accessible is to support more languages.
There are many tools to handle internationalization (or i18n
- that means:
an "i" followed by 18 letters followed by an "n"): Rails has the I18n
class,
Phoenix uses gettext
,
for Heroic we use
the i18next
package
and the Intl
module,
and other frameworks have other solutions.
This article is not going to focus on those tools though... All of them provide methods and functions for translation and localization, but there's a lot more than translating words when dealing with multiple languages.
During this series, I'll use examples of Heroic's code but most of these ideas can be applied anywhere.
Text direction
Not all languages are written from left to right (like this blog), there are languages like Hebrew, Arabic, or Persian, that are written in the opposite direction. There's also languages like Traditional Chinese, Traditional Japanese, or Korena that are written vertically!
But wait! there's more! There are some ancient scripts that used the Boustrophedon writing style: it switched back and forth with one line written from left to right, the next from right to left (with mirrored characters), then again from left to right, and so on.
But don't worry! Don't freak out! The chances of an Etruscan using your app is probably zero.
CSS's direction
Property
The initial value of
this property
is ltr
so we usually don't think about it when building a site in English, but it also supports the
rtl
value that impacts how some elements are rendered by the browser.
p
elements will align the text to the right-
elements with
display: grid
anddisplay: flex
will automatically render the children starting from the right in "reverse" order, while elements withdisplay: block
are not affected! - the
label
element will also reverse the order of its children
by Ariel Juod (@arieljuod) on CodePen.
See the Pen LTR vs RTL direction
The list could go on and on, but what's important to know is that most HTML elements already know how to render the content with the correct direction so we should always set this (we could do that in the
body
element for example, and the children will inherit it).
What I like to do is:
-
If the rendered language is a RTL language, add an
isRTL
class to thebody
element (or any wrapper element like#root
in a React app) -
Add a this CSS:
body.isRTL { direction: rtl; }
And that's it! a lot of your content will be way more user-friendly (though still far from perfect).
This also gives you a simple selector to tweak the CSS when the direction or position is not handled automatically.
Check these examples in Heroic's source code:
-
setting the
isRTL
class in the App component link -
the CSS link. Note that in Heroic we are not setting this property only in the body or
#root
element, we can just add theisRTL
class to any element where we need extra tweak
HTML's dir
Attribute
The
dir
property
is similar to the direction
CSS property with using the ltr
or rtl
value (it's not the same though, there are more details in the MDN docs for both properties).
But there's a third possible value: auto
. It tells the browser to infer the direction based on the content of the element! So, if the content has (for example) one Arabic character, the browser will consider that the element should be rendered from right to left.
What About "Top to Bottom"?
I don't have experience handling this, but guess what? CSS can do that too!
There's another property called
writing-mode
that can handle different combinations.
When dealing with these languages, the layout of the pages tend to change A LOT compared to horizontal ones. In these cases you'll probably need to do more changes than just CSS properties.
If you really need to support this, I recommend this article that explains most of the challenges.
What's next?
For RTL languages, the expectation is not only for the text to start from the right, the layout has to be mirrored too! For example: Heroic has a sidebar menu on the left side of the app, but, when a RTL language is selected, we render it on the right side of the screen instead.
In the text article I'll talk about how to manage the layout changes and about using logical CSS properties.