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 as left, and end is the same as right.
  • For right-to-left start is the same as right, and end is the same as left.

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
as-before as-after

Alert

Before After
alert-before alert-after

Arrows

Before After
arrows-before arrows-after
arrows-before2 arrows-after2

Item

Before After
item-before item-after

Radio & Checkbox

Before After
rc-before rc-after

Toggle

Before After
toggle-before toggle-after
toggle-before2 toggle-after2

Searchbar

Before After
sb-before sb-after

Tabs

Before After
tabs-before tabs-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.

Signup for the Ionic Newsletter to get the latest news and updates!