Need help upgrading to Ionic Framework 4.0? Get assistance with our Enterprise Migration Services EXPLORE NOW

Ionic offers full LTR and RTL support for apps of all languages. If you have any custom styles that are applied to your app, you might want to use some built in mixins that will address the multi-directional needs.

Enabling support

By default, apps are set to LTR only. To enable support for multi-directional apps, change the $app-direction variable to multi

$app-direction: multi // Both RTL and LTR

If you know your app will only ever be in either RTL or LTR, you can lock the direction.

$app-direction: rtl // RTL only apps
// or
$app-direction: ltr // LTR only apps

This has the added benefit of also keeping the generated CSS a bit smaller as well.

Directional mixins

To remove all directional properties, there are mixins added that handle directions in LTR and RTL automaically. The mixins should have the same structure as the full property: prop($top, $start: $top, $bottom: $top, $end: $start)

Mixins:

Custom directional support

If your custom styles need additional rules applied for RTL/LTR, you can use the ltr() and rtl() functions:

selector {
    // Include directional properties
    @include padding(0, 10px, null, 5px);

    // Direction agnostic style goes here
    background-color: black;

    @include ltr() {
        // Custom ltr style goes here
        float: left;
    }

    @include rtl() {
        // Custom rtl style goes here
        float: right;
    }
}

Directional properties

We kept the properties left and right where possible, to actually mean left and right, regardless of app direction To make things work well in both directions, we added new properties: start and end. where start means left on ltr, right on rtl, and end means right on ltr, left on rtl.

We recommend using just start and end, as for 99% of the cases those are the correct sides on both directions.

New names
Deprecated names

Deprecated variables

In order to best support multidirectional apps, we felt it was needed to deprecate some sass variables:

And to change many variables with left or right with them to have start or end instead. These sass variables will continue to stay in the framework, until the next major release (4.x). We strongly suggest that you update your variables sooner than later.

Platform direction

Currently, if a dir attribute is not set on the html tag, platform will automatically set it to be “ltr”, for the scss to work for them as well. We recommend that you set the attribute before hand though as it is much faster.

Nesting directions

There is no support for nested directions. For example:

<any dir="ltr">
    <!-- ltr -->
    <any dir="rtl">
        <!-- rtl -->
    </any>
</any>
<any dir="rtl">
    <!-- rtl -->
    <any dir="ltr">
        <!-- rtl -->
    </any>
</any>

Real-time direction change

You can change the direction in real time (platform.setDir('rtl', true)), but currently we are aware that some things might get stuck in a direction, and aren’t correct. (Style that is controlled from TS) We recommend setting the direction as in-advance as possible, but plan to fix the real time directional support.

CSS direction support

We cannot support direction: rtl in scss, because properties like padding-block-start are not available in all browsers, and rules like float: start does not exist at all.

Mixins usage guide:

multi-dir, ltr, rtl

If you want to set styling specifically for ltr or rtl, and no other mixin can help, use that style inside the ltr and rtl mixins.

@include ltr() {
  order: 1;
}
@include rtl() {
  order: -1;
}

If you want to use the same style on both directions, and it is direction critical, use that style inside the multi-dir mixin.

@include multi-dir() {
  order: 1;
}

svg-background-image

If you are using a background image as an svg, we added another parameter to flip it in rtl.

Previous usage:

@include svg-background-image($some-svg);

New usage, if you want to flip it in rtl:

@include svg-background-image($some-svg, true);

padding / margin

Just like normal padding/margin, it has 4 parameters: top, end, bottom, start.

@include padding(0); // same on both directions
@include padding(0, 1px); // same on both directions
@include padding(0, 1px, 2px); // same on both directions
@include padding(0, 1px, 2px, 3px); // on rtl it would flip to `0 3px 2px 1px`

If you want to use any specific padding/margin (top/right/bottom/left), use the mixin with null values.

@include padding(0, null, null, null); // padding-top
@include padding(null, 0, null, null); // padding-end (padding-right in ltr, padding-left in rtl)
@include padding(null, null, 0, null); // padding-top
@include padding(null, null, null, 0); // padding-start (padding-left in ltr, padding-right in rtl)

position

Gets top, end, bottom, start and sets position accordingly.

@include position(0, 1px, 2px, 3px);
// LTR: top: 0, right: 1px, bottom: 2px, left: 3px,
// RTL: top: 0, right: 3px, bottom: 2px, left: 1px,

@include position(0, 1px, null, null);
// LTR: top: 0, right: 1px
// RTL: top: 0, left: 1px,

border-radius

Just like the property, it gets up to 4 parameters: top-start, top-end, bottom-end, bottom-start

@include border-radius(50%); // border-radius: 50%
@include border-radius(50%, 0); // border-radius: 50% 0 in ltr, border-radius: 0 50% in rtl
@include border-radius(50%, 0, 1px); // border-radius: 50% 0 1px in ltr, border-radius: 0 50% 0 1px in rtl
@include border-radius(50%, 0, 1px, 2px); // border-radius: 50% 0 1px 2px in ltr, border-radius: 0 50% 2px 1px in rtl

If you want a specific border radius, use with null:

@include border-radius(0, null, null, null); // border-top-left-radius in ltr, border-top-right-radius in rtl
@include border-radius(null, 0, null, null); // border-top-right-radius in ltr, border-top-left-radius in rtl
@include border-radius(null, null, 0, null); // border-bottom-right-radius in ltr, border-bottom-left-radius in rtl
@include border-radius(null, null, null, 0); // border-bottom-left-radius in ltr, border-bottom-right-radius in rtl

text-align

Use like you normally would, but try to use start and end instead of left and right. This mixin just adds a fallback text-align in case the browser does not support start and end. In addition, there is a second parameter in which you can pass !important

div {
  @include text-align('start')
}

h1 {
  @include text-align('center')
}

direction

@include direction(ltr); // ltr on ltr, rtl on rtl
@include direction(rtl); // rtl on ltr, ltr on rtl

float

@include float(start); // float: left on ltr, float: right on rtl
@include float(end); // float: right on ltr, float: left on rtl
@include float(left); // float: left
@include float(right); // float: end
@include float(X); // float: X

background-position

A tiny bit different from the property. Horizontal must be the first property, and vertical the second, can’t be the other way around.

@include background-position(center); // background-position: center
@include background-position(left, top); // background-position: left top
@include background-position(start, top); // background-position: left top on ltr, background-position: right top on rtl
@include background-position(start, 1px, top); // background-position: left 1px top on ltr, background-position: right 1px top on rtl
@include background-position(start, 1px, top, 2px); // background-position: left 1px top 2px on ltr, background-position: right 1px top 2px on rtl

transform-origin

@include transform-origin(start, X); // transform-origin: left X on ltr, transform-origin: right X on rtl
@include transform-origin(end, X); // transform-origin: right X on ltr, transform-origin: left X on rtl
@include transform-origin(Y, X); // transform-origin: Y X
@include transform-origin(1px, X); // transform-origin: 1px X on ltr, transform-origin: calc(100% - 1px) X on rtl

transform

Gets all transformations the usual way

    @include transform(translate3d(1px, 2px, 3px), scale(-1), translateY(1px));
    // LTR: transform: translate3d(1px, 2px, 3px) scale(-1) translateY(1px)
    // RTL: transform: translate3d(calc(-1 * 1px), 2px, 3px) scale(-1) translateY(1px)

In addition, there is flip-scale which also flips the scale (of X) on rtl

    @include transform(translate3d(1px, 2px, 3px), flip-scale(1));
    // LTR: transform: translate3d(1px, 2px, 3px) scale(1)
    // RTL: transform: translate3d(calc(-1 * 1px), 2px, 3px) scale(-1, 1)

API

Native

General