Ionic and RTL

This is a guest post from community member, Amit Moryossef. Amit has been working on adding RTL support into Ionic.
Ionic has always been an awesome framework for creating apps that use left-to-right (LTR) languages, because it was designed this way from the beginning. For most people, this works great. The vast majority of languages are LTR, and their users may not know of any other possibility.
However, there are some languages used by millions throughout the world which are read right-to-left (RTL), such as Hebrew and Arabic. Ionic’s latest release includes additional support for RTL languages enabling developers to easily create a natural reading experience.
Supporting RTL is a challenge because this “feature” is not a first class citizen everywhere (Apple didn’t even support RTL in iOS until version 9). CSS was also never originally designed for multidirectional support, but this is starting to change as more people request it.
What Are We Doing About It?
The goal is simple. We are committed to supporting RTL applications, or multi-directional applications, as soon as possible, while continuing to support LTR in Ionic.
To reach this goal, small adjustments are being merged in every release to the current major version of Ionic (3.x.x). With this cadence, the next major version release of Ionic will have complete RTL support.
The Journey
The Ionic team has been supportive in adding RTL to the framework. Since Ionic is an open source project, and since the community has much more experience with RTL languages, it became a welcomed community effort.
First, we tried to handle one component at a time by adding custom CSS selectors for RTL. It proved to be possible, but not feasible. Duplicating CSS selectors to make the CSS properties compliant with RTL was not easily maintainable, and we had to find a different way to tackle this problem.
We decided that we needed to take advantage of Sass mixins to compensate for the lack of RTL support in CSS. For example, using the property padding: 1px 2px 3px 4px
in RTL doesn’t look correct, because CSS uses the format of top right bottom left
on both LTR and RTL directions.
We found that the words left
and right
do not make sense to use for both directions, and decided on what more progressive CSS already uses:
- For left-to-right
start
is the same asleft
, andend
is the same asright
. - For right-to-left
start
is the same asright
, andend
is the same asleft
.
So we replaced the padding
, margin
, border-radius
, transform
and text-align
properties with Sass mixins using the top end bottom start
format instead. By defining padding using the mixin @include padding(1px, 2px, 3px, 4px)
padding is applied based on the direction, removing the need to maintain code for every single component.
Many RTL changes have already been made in the framework, but here are some screenshots of a few
Actionsheet
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Alert
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Arrows
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
Item
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Radio & Checkbox
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Toggle
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
![]() ![]() |
![]() ![]() |
Searchbar
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Tabs
Before | After |
---|---|
![]() ![]() |
![]() ![]() |
Animations like menu toggling and navigation (page transition) have also been adjusted.
One More Hurdle Along the Way
While Sass is awesome, and adjusting it to our needs works perfectly, there are some styles which are controlled from TypeScript.
These component styles can only be adjusted to support RTL on a case-by-case basis, and this can be tricky depending upon requirements.
The risk of case-by-case fixes is that developing with them won’t come naturally to all developers, and we will need to ensure code coverage for every new component that gets added, and every edge case presented.
Getting Technical
To view the technical work we’ve already accomplished, and learn what is planned for development, you can read the docs.
Adding RTL Support to Your App
Ionic’s styles have support for RTL, but your app may not. We recommend using our new Sass mixins to include multi-directional support for your custom styling.
Below is an example of using these new Sass mixins: padding
, ltr
and rtl
on a selector
:
selector {
// Include directional properties via mixins
@include padding(0, 10px, null, 5px);
// Direction agnostic styles go here
background-color: black;
@include ltr() {
// Custom ltr styles go here
order: 1;
}
@include rtl() {
// Custom rtl styles go here
order: -1;
}
}
Enabling RTL/LTR
Those of you who do not need to support RTL languages may be concerned by the CSS bundle size increasing. Don’t worry, we got you! The $app-direction
is set to ltr
by default, so your app will need to enable RTL.
By setting $app-direction: multi
in your Sass, your CSS will include all of the styles for both LTR and RTL languages.
What if your app is RTL only? Just set $app-direction: rtl
and your app will only support RTL.
Special Thanks
It has been great seeing so many pull requests and issues describing these technological challenges that need addressing. I believe that the only thing making RTL possible is the great community that is behind it driving it forward.
I want to thank Brandy, Manu, sijav, John-Luke, and everyone who has helped and contributed towards achieving this goal. You all are awesome!
View the state of RTL on GitHub.
If you have any issues or questions, we will be happy to help you on our forum, slack channel or through GitHub issues.