RTL and LTR Support in OpenLMIS
- 1 Introduction
- 2 Overview
- 3 Documentation
- 3.1 Introduction
- 3.2 Mixins description
- 3.2.1 @mixin direction
- 3.2.2 @mixin translate-x($value)
- 3.2.3 @mixin translate-xy($valueX, $valueY)
- 3.2.4 @mixin padding-right($value)
- 3.2.5 @mixin padding-left($value)
- 3.2.6 @mixin padding-x($value)
- 3.2.7 @mixin padding($padding-top, $padding-right, $padding-bottom, $padding-left)
- 3.2.8 @mixin margin-right($value)
- 3.2.9 @mixin margin-left($value)
- 3.2.10 @mixin margin($margin-top, $margin-right, $margin-bottom, $margin-left)
- 3.2.11 @mixin border-right($value)
- 3.2.12 @mixin border-left($value)
- 3.2.13 @mixin border($border-top, $border-right, $border-bottom, $border-left)
- 3.2.14 @mixin float($float)
- 3.2.15 @mixin right($value)
- 3.2.16 @mixin left($value)
- 3.2.17 @mixin text-align($alignment)
- 3.2.18 @mixin background-position($position)
- 4 Guidelines
Introduction
What was the challenge?
Supporting multiple text directions, specifically RTL and LTR, presented a challenge because most modern web applications are designed with LTR layouts as the default. This creates a hurdle when expanding the user base to regions where languages like Arabic, Hebrew, and Urdu, which use RTL, are commonly spoken. Without proper support, the UX in these regions becomes inconsistent, not intuitive, and potentially unusable.
Why do we want to support multiple text directions?
The primary reason for supporting both RTL and LTR directions is to provide an inclusive and accessible user experience for all users, regardless of the language they speak or the region they are from. This ensures that the OpenLMIS App can cater to a global audience, improving usability for RTL language speakers. By offering a layout that automatically adjusts based on the language, we can provide a more intuitive, user-friendly interface, contributing to better adoption and engagement in international contexts.
Overview
What was the idea behind the RTL Support?
The goal behind implementing RTL support was to identify CSS properties that do not naturally adapt to Right-to-Left layouts and provide a solution to make them direction-aware. To achieve this, we either rewrote styles to ensure native RTL support or dynamically adjusted the direction based on the dir
attribute of the document. For this reason, we created a set of mixins that can be used in place of standard CSS properties. These mixins allow for seamless support of both LTR and RTL layouts, ensuring that the same styles can be applied consistently across different text directions without the need for duplicated code.
How does the App automatically adjust layouts based on language?
We have managed to implement automatic page orientation change, after the user switches to the RTL oriented language. It is very easy to configure for any OpenLMIS instance. You can do it just by adding the language to the “supportedRTLLanguages
" array in the config.json file.
In the example below Arabic language is set as the RTL supported. So if user will switch to this language page will change it’s direction automatically.
Documentation
Introduction
This documentation provides a detailed explanation of various SCSS mixins designed for padding, margin, border, direction handling, and more. Which are basically properties that do not support RTL.
These mixins help ensure consistency across both Left-to-Right (LTR) and Right-to-Left (RTL) layouts.
Mixins description
@mixin direction
This mixin handles text direction based on the dir
attribute. It applies ltr
(Left-to-Right) or rtl
(Right-to-Left) based on the document direction. It is applied to all elements in the application. Thanks to that for example the date picker component is changing it’s direction.
@mixin direction() {
[dir="ltr"] & {
direction: ltr;
}
[dir="rtl"] & {
direction: rtl;
}
}
@mixin translate-x($value)
Translates an element along the X-axis, respecting the dir
attribute. If in rtl
mode, the translation direction is reversed.
@mixin translate-x($value) {
[dir="ltr"] & {
transform: translateX($value);
}
[dir="rtl"] & {
transform: translateX(-$value);
}
}
@mixin translate-xy($valueX, $valueY)
Translates an element along both the X and Y axes, reversing the X-axis translation for RTL layouts.
@mixin translate-xy($valueX, $valueY) {
[dir="ltr"] & {
transform: translateX($valueX) translateY($valueY);
}
[dir="rtl"] & {
transform: translateX(-$valueX) translateY($valueY);
}
}
@mixin padding-right($value)
Applies padding to the right side in LTR layouts, and to the left side in RTL layouts.
@mixin padding-left($value)
Applies padding to the left side in LTR layouts, and to the right side in RTL layouts.
@mixin padding-x($value)
Applies equal padding on both left and right sides, irrespective of the layout direction.
@mixin padding($padding-top, $padding-right, $padding-bottom, $padding-left)
Sets padding for all four sides, automatically adjusting left/right padding based on the layout direction.
@mixin margin-right($value)
Applies margin to the right in LTR layouts and to the left in RTL layouts.
@mixin margin-left($value)
Applies margin to the left in LTR layouts and to the right in RTL layouts.
@mixin margin($margin-top, $margin-right, $margin-bottom, $margin-left)
Applies margin to all four sides, adjusting left/right margins based on the layout direction.
@mixin border-right($value)
Applies a border to the right in LTR layouts and to the left in RTL layouts.
@mixin border-left($value)
Applies a border to the left in LTR layouts and to the right in RTL layouts.
@mixin border($border-top, $border-right, $border-bottom, $border-left)
Sets borders on all four sides, adjusting left/right borders based on layout direction.
@mixin float($float)
Applies floating behavior, adjusting for rtl
by swapping left and right floats.
@mixin right($value)
Positions an element to the right in LTR layouts and to the left in RTL layouts.
@mixin left($value)
Positions an element to the left in LTR layouts and to the right in RTL layouts.
@mixin text-align($alignment)
Aligns text, swapping left and right for RTL layouts.
@mixin background-position($position)
Sets background position, swapping left and right for RTL layouts.
Guidelines
In this section, there will be information. How the css/scss should be written in order to make the whole app RTL friendly.
1. If possible use flex or grid layouts
Both of the have native support for the RTL direction. So it does not require any adjustments.
If you have for example layout like this:
In LTR environment first item will be on the left and last on the right. When dir will change to RTL.
Order of the items will switch automatically without touching the element styles.
Same thing applies to the grid layout.
2. Use Mixins Instead of Direct CSS Properties
To maintain RTL support, avoid using hard-coded values for properties that affect layout direction, such as margin
, padding
, border
, float
, etc. Instead, use the corresponding mixins provided in this documentation to ensure your styles adapt to both LTR and RTL layouts seamlessly.
For Example:
Instead of this:
Use this:
CSS Property | Use Instead |
---|
|
|
|
|
|
|
|
|
|
|
3. Be Cautious with Positioning
For properties like left
, right
, and transform
, it's crucial to use the appropriate mixins to ensure consistent behavior in RTL and LTR contexts.
Instead of this:
Use this:
Summary
To sum up, use grid and flex if possible. Otherwise instead of the fixed direction css properties use appropriate mixins described in the docs above.
OpenLMIS: the global initiative for powerful LMIS software