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.
- pelements will align the text to the right
- 
    elements with display: gridanddisplay: flexwill automatically render the children starting from the right in "reverse" order, while elements withdisplay: blockare not affected!
- the labelelement 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 isRTLclass to thebodyelement (or any wrapper element like#rootin 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 isRTLclass in the App component link
- 
    the CSS link. Note that in Heroic we are not setting this property only in the body or
    #rootelement, we can just add theisRTLclass 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.