OUR Blog
Frontend developer
Robert Dodis
Frontend developer
FRONTEND
May 19 2017

Right-to-left development: Tips and Tricks

The Middle Eastern market is evolving at a rapid pace and its online presence is growing along with it. However, many software developers suffer from a lack of educational information when it comes to developing right-to-left (RTL) websites for the region and they are often forced to work by trial and error when creating RTL script projects.

Authoring RTL websites is an unconventional task, even for an experienced frontend developer. Since languages that are read from right to left, such as Arabic, Persian, Hebrew, Urdu, etc., involve making particular changes to the development process, there are a number of specific details that need to be taken into account by developers.

In this post, we’ll take a look at the peculiarities of creating RTL and bidirectional websites.

Developing an RTL website: Characteristics to take into account

1) In RTL language regions, people read and write from right to left. This means that most interface elements should be flipped in order to be displayed correctly.

2) Elements connected with media-content management, such as “Play” in a video player, don’t need to be mirrored.

3) The order of digits in numbers (such as phone numbers) doesn’t differ from left-to-right writing.

4) Overlining is usually used to highlight text in Arabic (instead of underlining, italics, or interspacing).

5) Capital letters are often omitted.

6) Although intellection and visual information perception have an identical direction of writing – RTL, most people are right-handed. Therefore, it’s better to not mirror some controls so that users can interact with them comfortably. Centering controls and creating a “liquid layout” can help avoid confusion and can better the user’s experience with the website.

7) When combining symbols that can be used in both RTL and LTR languages (such as periods, commas, or other punctuation marks), their displayed positions will depend on the direction of the text. This is because the data format starts from the beginning, but a browser is still processing an RTL word in the RTL direction and punctuation is converted towards the direction that has been specified.

This can be seen in the following example:

To avoid these results when combining RTL and LTR strings or text fragments, they should be converted into separate elements that specify their direction using the dir attribute or a css direction property.

<p dir=”rtl” class=”rtl-text”>?سوف أعطي مثالا على ذلك. لا تمانع</p>
<p dir=”ltr” class=”ltr-text”>I will give an example. Don't you mind?</p>

or another variant

 .rtl-text {
    direction: rtl;
}

.ltr-text {
    direction: ltr;
}

To prevent these problems, <bdi> tag can also be used. The given tag is supported only by Chrome (16) and Firefox (10).

8) When writing basic css styles, a separate file for RTL direction should be created where the horizontal properties are set (float, left/right, padding-left/padding-right, margin etc.) and redefined appropriately:

div.class {
    width: 150px;
    height: 100px;
    float: left;
    padding: 0 15px 0 10px;
}

rtl.css file:

html[dir=”rtl”] div.class {
    float: right;
    padding: 0 10px 0 15px;
}

In this case, the two files are appended at the markup stage and the finished product results in one common file that meets the relevant conditions.

To eliminate additional LTR-directed features, a separate ”rtl.css” can be attached if it’s necessary.

Another way to achieve this result is to create two complete style files for RTL and LTR. There are utility programs that can help automate the styles assembling.

One tool that can do this is css-flip, a utility created in the bowels of Twitter. It allows developers to compile a file with redefined properties for RTL from the source file.

input.css:

p {
    padding-left: 1em;
}

    output.rtl.css:

p {
    padding-right: 1em;
}

Replacements and exceptions based on directives in the source file may be used as well.

Example:

input.css:

p {
    /*@replace: -32px -32px*/ background-position: -32px 0; 
    /*@replace: ">"*/ content: "<"; 
    /*@noflip*/ float: left;
}

output.rtl.css:

p {
    background-position: -32px -32px;
    content: ">";
    float: left;
}

A similar tool is RTLCSS. It also supports replacements or exceptions and it allows developers to rename selectors, add local configurations of exception, and delete or add new properties.

Example:

input.css:

.example {
    transform: translateY(10px) /*rtl:append:scaleX(-1)*/;
    font-family: "Helvetica Neue", Arial/*rtl:prepend:"Arabic fonts", */;
    font-size:1.3em/*rtl:1.2em*/;
    /*rtl:remove*/
    text-decoration:underline;
    /*rtl:begin:ignore*/
    margin-left:15px;
    padding-left:20px;
    /*rtl:end:ignore*/
}

output.rtl.css:

.example {
    transform: translateY(10px) scaleX(-1);
    font-family: "Arabic fonts","Helvetica Neue", Arial;
    font-size:1.2em;
    margin-left:15px;
    padding-left:20px;
}

Configurations for renaming selectors can also be done.

input.css:

/*rtl:begin:options: {
    "autoRename": true,
     "stringMap":[ {
        "name" : "prev-next",
        "search" : ["prev", "previous"],
        "replace" : ["next", "next"],
        "options" : {"ignoreCase":false}
    } ]
} */
.slide-prev, .card-previous {
    content: '<';
}
/*rtl:end:options*/

output.rtl.css:

.slide-prev, .card-previous {
    content: '>';
}

9) Calendar display is another important aspect to take into account because calendar years also vary between LTR and RTL regions.

For example, the Islamic calendar (Hijri) is a purely lunar calendar. It contains 12 months that are based on the moon's phases, which means that the Islamic calendar year works out to be shorter than the non-Islamic calendar year: 12 x 29.53 = 354.36 days. The Gregorian calendar, which is most commonly used in LTR, is calculated according to the Earth’s rotation around the Sun, meaning that a Gregorian year is longer than a non-Gregorian year. That’s why Hijri always has to shift according to the Gregorian calendar.

Due to these variations, it can be difficult to find a high-quality tool for working with both Gregorian calendars in LTR script and so-called non-Gregorian calendars in RTL script simultaneously.

Fullcalendar is a very popular jQuery calendar that completely relies on moment.js in time calculation. However, this tool isn’t capable of accomplishing conversions between different kinds of calendars. It only makes it possible to display RTL content and localize dates.

Dojo Toolkit, on the contrary, has the ability to display non-Gregorian calendars. However, the range of tasks that it can carry out is limited.

10) Although many languages allow for the abbreviation of the names of days of the week to save space, this approach is not useable in Arabic where the names of all the days begin with the same letter.

11) Internationalization API support covers a wide spectrum of languages and their derivatives. The Intl object is the namespace for the ECMAScript Internationalization API. This API provides a language-sensitive string comparison, as well as relevant number, date, and time formatting. It supports not only Arabic, but also Arabic-Arabic, Arabic-Tunisian, and a wide range of other variants.

The use of Eastern Arabic numerals instead of Western numerals can also vary. In some varieties of this language, Eastern Arabic numerals (123) are used instead of Western (١٢٣). The API can help indicate when to show ١٢٣ and when to show 123.

Examples:

Formatting of Arabic-Egyptian numerals:

var sampleNumber = new Intl.NumberFormat('ar-EG').format(12345);

console.log(sampleNumber); // => ١٢٬٣٤٥

For instance, Tunisia features Eastern Arabic numerals:

var sampleNumber = new Intl.NumberFormat('ar-TN').format(12345);

console.log(sampleNumber); // => 12345

DateTimeFormat constructor is an irreplaceable property of the Intl object. It allows for passing additional options in the argument string to specify formatting for date and time.

As an example, this is how to convert a date from the Gregorian calendar into the Islamic calendar:

var sampleDate = new Intl.DateTimeFormat("ru-RU-u-ca-islamicc").format(new Date()); // => “26.03.2017"
console.log(sampleDate); // => “27.06.1438 AH”

Additional resources for RTL development

They say that “forewarned is forearmed”. We hope this post has been useful in highlighting the peculiarities and specifics of working on RTL projects. These recommendations should help developers choose an appropriate strategy to avoid mistakes and get down to development quickly and effectively.

For additional resources and more information about RTL development, please check out these useful links:

  1. Authoring HTML: Handling Right-to-left Scripts
  2. Intl API
  3. 3 Different Ways to RTL your CSS
  4. Working with bidirectional (bidi) text and RTL languages on the web
WHAT CLIENTS SAY ABOUT STEELKIWI
SIMILAR POSTS
Feb 22 2017
In this article you will find a list of 11 Top HTML & CSS mistakes which can spoil a developer's life.
Dec 22 2016
Everything you should know about validation and errors in AngularJS apps: good and bad practices, build-in and third-party tools, some pieces of advice on how to build convenient and maintainable error handling core.
Nov 09 2016
Missed some news in Meteor world? Don't worry and check our digest!