Ionic-framework: Add Right To Left Support

Created on 18 Jan 2016  ·  75Comments  ·  Source: ionic-team/ionic-framework

_From @mashaly100200 on December 30, 2015 17:24_

kindly add support rtl to animation and the components

_Copied from original issue: driftyco/ionic2#832_

help wanted

Most helpful comment

Any update about the RTL issue?

All 75 comments

_From @adamdbradley on December 30, 2015 17:38_

Yes this is on our roadmap to complete and we would love to get more feedback from experienced RTL dev's to help us point out where we need to improve. Would you be able to provide a checklist of certain parts of ionic2 that do not work well with RTL. Our goal would be to provide an additional RTL css file, and have any JS adjust accordingly depending if the html element has dir="rtl" or not. Thanks

_From @mashaly100200 on December 30, 2015 18:39_

It's my pleasure to help ionic2 team to support RTL
firest it's easy to watch what are the bad effects if we use rtl direction
we can add this attr to html tag that will convert all website to to rtl

or
we can use it in the body as a style like this
style="direction:rtl"

if ionic team plan to support rtl

thay will need to add the target direction in App configurations , because the application will need to know what is the direction on the start up
, and if the developer need to change the app language to rtl language in runtime then we should refresh all app (like native android,windows phone app , ios need to restart the application to change it's direction)

now when i try to change ionic2 html direction i found that there are things aleady support rtl direction coz pure html konw how to deal with rtl direction
but thare are things need to be support rtl direction
first thing is animation
i donn't know if ionic team do the animation with css or javascript code , in both cases all animation witch have rtl or ltr will need to add another animation direction , not only change varialbe but add another one coz many things will need to change

I would like to provide assistance as i can to ionic team to help in this great library

i know my English is not good , but i hope you understand my words :)

_From @mashaly100200 on December 30, 2015 18:44_

plz change this goal " Our goal would be to provide an additional RTL css file "
because we need the two direction in the same application , based on the user's choice , some time it will be in runtime

_From @adamdbradley on December 30, 2015 18:51_

we need the two direction in the same application , based on the user's choice , some time it will be in runtime

Ionic itself will be able to dynamically add this css file for you, depending on the <html dir="rtl">

_From @mashaly100200 on December 30, 2015 19:23_

these imgs from trying to change direction of onic-conference-app example
if ionic team cover the rtl direction in this example i think it will be not less than 90% of rtl support

Image of Yaktocat

_From @mashaly100200 on December 30, 2015 19:26_

Image of Yaktocat

_From @mashaly100200 on December 30, 2015 19:27_

Image of Yaktocat

_From @mashaly100200 on December 30, 2015 20:21_

any icon which are right,left,back or forward arrow like back-button icon will need this style
{
-webkit-transform: rotate(180deg);
-moz-transform: rotate(180deg);
-o-transform: rotate(180deg);
-ms-transform: rotate(180deg);
transform: rotate(180deg);
}

_From @adamdbradley on December 31, 2015 4:27_

So @brandyscarney had a good idea that we create all the RTL scss files within the repo and get them ready to be filled.

I was thinking that instead of dynamically adding another rtl css, we could have a default $rtl-support: false sass variable that can be updated in each app's sass variables. So in most cases the extra rtl css wouldn't be added to apps, but for those who require the rtl css they can set $rtl-support: true.

Then within our new rtl scss files, the css can be wrapped with @if $rtl-support. This way we can keep the css files separated and easier to edit, and provide rtl support out of the box. Think this will work @mashaly100200 ?

_From @mashaly100200 on December 31, 2015 11:48_

yes load rtl dynamically is a good idea ,

let us start with animation , coz it may be need more effort

  • i want to know is it possible to add specific page transition animation when do push and pop pages ?
  • and how developer add this specific animation to the tow pages witch enter and leave ?
  • can developer watch back event then add his specific animation also to the two pages ?

if your answer are yes for the previous three questions , then i can congratulate my self coz animation topic don't need any effort and full support rtl direction and ionic team deserve a very big thanks :)

_From @adamdbradley on January 1, 2016 1:53_

This is the transition animation for ios: https://github.com/driftyco/ionic2/blob/master/ionic/animations/ios-transition.ts

Not sure if this should add logic for RTL, or if there should be a new animation instead. You can however add your own transition, and override the pageTransition config: https://github.com/driftyco/ionic2/blob/master/ionic/config/modes.ts#L24

_From @mashaly100200 on January 1, 2016 21:55_

hi @adamdbradley , merry christmas

i finished a custom animation class which reverse the default animation class behavior depend on documen.dir
https://gist.github.com/mashaly100200/bf713f2b558285322155
i tested it , and i will test it in real projects soon (inshaa allah)

also i finished some of css classes that was need to be reversed
https://gist.github.com/mashaly100200/dc23529e570034b0dfb9

and if i face more classes need to be reversed , i will add it to this file until i finish one or two real project

also rtl need these configurations in app constructor
https://gist.github.com/mashaly100200/692160b036422d7b018c

i was trying to add all configuration in one place so i found that i can add all things in the app contractor

hope these things can help to make ionic2 fully support rtl

Please feel free to add any corrections or suggestions .

_From @adamdbradley on January 2, 2016 3:2_

Cool, so it looks like the RTL transition is pretty darn close to the LTR transition, which makes me think it should be an isRTL option that gets passed into the transition's options and we only have one transition. I can update ionic so it has a common isRTL property that can be referenced throughout the app (with webworkers we want to avoid doing document reads within ionic's logic).

_From @adamdbradley on January 2, 2016 3:58_

All transitions are now passed isRTL within the opts: https://github.com/driftyco/ionic2/blob/da986a5fb0ee2c7660ad4494731b5fe98b393812/ionic/components/nav/nav-controller.ts#L798

So now the ios-transition can add the logic for RTL transitions.

_From @adamdbradley on January 2, 2016 4:38_

Added how we can include RTL css so it correctly builds within ionic.css (which includes both md and ios css) and ionic.ios.css (just ios). The thought is that apps which want to include both RTL and LTR css within the same file can set $include-rtl: true in their sass variables, otherwise it'll default to only include LTR css. https://github.com/driftyco/ionic2/blob/f38ad4a7d2d8c527a3bc64fd8569b11eb659c290/ionic/components/item/item.ios.scss#L231

_From @MatanYed on January 6, 2016 18:14_

Just you to know: RTL apps in iOS are partly LTR:
Primary navbar button side is left, side menu is left, transition animation is from left to right.

_From @adamdbradley on January 7, 2016 16:41_

Added new methods to platform to get and set language and direction: https://github.com/driftyco/ionic2/commit/942bd9b93b97a88554aafc9972c1c2d86de9273f

_From @mashaly100200 on January 12, 2016 21:2_

update
for anyone flow this topic
replace
config.set('backButtonIcon', 'ion-ios-arrow-forward');
with
config.set('backButtonIcon', 'arrow-forward');

also i update the animation class
https://gist.github.com/mashaly100200/bf713f2b558285322155

I have been working on this problem on a moodle mobile app for our company and we need the app to support English and Arabic in the same time, so it's not a problem of switching the direction of everything to RTL but it need to be in run time. I used some tweaks at the beginning using ng-if and some broadcasting through the rootscope in the app, but whenever the user change the language, the app needs a reload, things not working at all with this method.
Three days ago, I started fighting with Ionic (it becomes an universal problem :) ), The moodle team open issues at the moment but I don't think they will look at them.
I am not using Ionic 2 but my approach in this problem is very simple, with ionic side attribute in ionic directive (I think most concerned directive with the RTL problem has this attribute) will make the solution easier than it looks.
I am trying to override the directive to add binding to the side attribute because now, it doesn't then add some alignments to the rest of the content using css in the app.scss, and with the help of angular-translate and the current implementation of the moodle app, update the left in word in classes and side to right and vise versa whenever the language change.
I am still implementing it at the moment I hope it will work (it must work anyway).

after adding dir="rtl" to index.html, the rendering of elements will start from right, that affects the look of some elements, like the segment button.
to fix it I changed

  .segment-button:first-of-type {
    border-radius: 4px 0 4px 0;
    margin-left: 0; }
  .segment-button:not(:first-of-type) {
    border-left-width: 0; }
  .segment-button:last-of-type {
    border-left-width: 0;
    border-radius: 4px 0 0 4px;
    margin-left: 0; }

to

  .segment-button:first-of-type {
    border-radius: 0 4px 4px 0;
    margin-right: 0; }
  .segment-button:not(:first-of-type) {
    border-right-width: 0; }
  .segment-button:last-of-type {
    border-right-width: 0;
    border-radius: 4px 0 0 4px;
    margin-right: 0; }

The Nav animation has to be opposite to the app direction, from left for RTL apps and from the right for LTR apps. to fix it I did this:
changed
var OFF_RIGHT = '99.5%';
to
var OFF_RIGHT = '-99.5%';
and
var OFF_LEFT = '-33%';
to
var OFF_LEFT = '33%';
and

                if (backDirection) {
                    // leaving content, back direction
                    leavingContent
                        .before.clearStyles([OPACITY])
                        .fromTo(TRANSLATEX, CENTER, '100%');
                }

to

                if (backDirection) {
                    // leaving content, back direction
                    leavingContent
                        .before.clearStyles([OPACITY])
                        .fromTo(TRANSLATEX, CENTER, '-100%');
                }

in ionic-angular/transitions/transition-ios

and for the back element in the Nav bar, I put the icon before the text, and changed the icon to forward.

@App({
    config: {
        backButtonText: 'الرجوع', // this is arabic or whatever
        backButtonIcon:'ios-arrow-forward'
        //          | ion-ios-arrow-back     | ion-md-arrow-back    
    } // http://ionicframework.com/docs/v2/api/config/Config/
})

the placeholder in the searchbar input can be fixed
by doing these changes (change everything left to right)

.searchbar-search-icon {
  width: 14px;
  height: 14px;
  background-image: url("data:image/svg+xml;charset=utf-8,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2013%2013'><path%20fill='rgba(0,%200,%200,%200.5)'%20d='M5,1c2.2,0,4,1.8,4,4S7.2,9,5,9S1,7.2,1,5S2.8,1,5,1%20M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0%20L5,0z'/><line%20stroke='rgba(0,%200,%200,%200.5)'%20stroke-miterlimit='10'%20x1='12.6'%20y1='12.6'%20x2='8.2'%20y2='8.2'/></svg>");
  background-size: 13px;
  background-repeat: no-repeat;
  position: absolute;
  left: 9px;
  top: 9px;
  margin-left: calc(50% - 60px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }

.searchbar-input {
  height: 3rem;
  line-height: 3rem;
  padding: 0 28px;
  font-size: 1.4rem;
  font-weight: 400;
  border-radius: 5px;
  color: #000;
  background-color: #FFFFFF;
  padding-left: calc(50% - 28px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }
  .searchbar-input::-moz-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input:-ms-input-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input::-webkit-input-placeholder {
    color: rgba(0, 0, 0, 0.5);
    text-indent: 0; }

to

.searchbar-search-icon {
  width: 14px;
  height: 14px;
  background-image: url("data:image/svg+xml;charset=utf-8,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2013%2013'><path%20fill='rgba(0,%200,%200,%200.5)'%20d='M5,1c2.2,0,4,1.8,4,4S7.2,9,5,9S1,7.2,1,5S2.8,1,5,1%20M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0%20L5,0z'/><line%20stroke='rgba(0,%200,%200,%200.5)'%20stroke-miterlimit='10'%20x1='12.6'%20y1='12.6'%20x2='8.2'%20y2='8.2'/></svg>");
  background-size: 13px;
  background-repeat: no-repeat;
  position: absolute;
  right: 9px;
  top: 9px;
  margin-right: calc(50% - 60px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }

.searchbar-input {
  height: 3rem;
  line-height: 3rem;
  padding: 0 28px;
  font-size: 1.4rem;
  font-weight: 400;
  border-radius: 5px;
  color: #000;
  background-color: #FFFFFF;
  padding-right: calc(50% - 28px);
  -webkit-transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1);
  transition: all 400ms cubic-bezier(0.25, 0.45, 0.05, 1); }
  .searchbar-input::-moz-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input:-ms-input-placeholder {
    color: rgba(0, 0, 0, 0.5); }
  .searchbar-input::-webkit-input-placeholder {
    color: rgba(0, 0, 0, 0.5);
    text-indent: 0; }

in the file: ionic.bundle.js
change the code:


setTranslateX: ionic.animationFrameThrottle(function(amount) {
var xTransform = content.offsetX + amount;
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0)';

change it to be:


setTranslateX: ionic.animationFrameThrottle(function(amount) {
var xTransform = content.offsetX + amount;
if (content.offsetX > 0)
{
      xTransform = amount;
}
$element[0].style[ionic.CSS.TRANSFORM] = 'translate3d(' + xTransform + 'px,0,0)';

I know this is not good solution but I had to.


and I added these css:


   a , h1 , h2 , span , div{
      text-align: right;
        }

        .title.title-left.header-item{
            left : 0 !important;
        }
label.item,
ion-nav-buttons,
ion-header-bar{
    direction: rtl;
}

.item-checkbox {
    padding-right: 60px;
}


.ion-android-arrow-back:before {
  content: ""; }

.ion-android-arrow-forward:before {
  content: ""; }

and made the menu on right :


<ion-side-menus enable-menu-with-back-views="false" >

    <ion-side-menu side="right" expose-aside-when="large">
        <ion-header-bar class="bar-positive">
            <h1 class="title">Menu</h1>
        </ion-header-bar>
        <ion-content>
            <ion-list>
                <ion-item menu-close ng-click="login()">
                    Login
                </ion-item>


            </ion-list>
        </ion-content>
    </ion-side-menu>


      <ion-side-menu-content>
        <ion-nav-bar class="bar-positive">

            <ion-nav-back-button>
            </ion-nav-back-button>
            <ion-nav-buttons side="right">
                <button class="button button-icon button-clear ion-navicon" menu-toggle="right"></button>
            </ion-nav-buttons>

        </ion-nav-bar>
        <ion-nav-view name="menuContent"></ion-nav-view>
    </ion-side-menu-content>



</ion-side-menus>

yeah that's what we are waiting for , and that's will be awesome

thanks ionic team

go ahead :+1:

EDIT: nevermind this has already been fixed

ion-item-sliding needs to be swipe-left option for rtl version like this :

        <ion-item-sliding swipe-left>
            <ion-item>
                <ion-avatar item-right>
                    <img src="img/slimer.png">
                </ion-avatar>
                <h2>Slimer</h2>
            </ion-item>
            <ion-item-options>
                <button primary>
                    <ion-icon name="text"></ion-icon>
                    Text
                </button>
                <button secondary>
                    <ion-icon name="call"></ion-icon>
                    Call
                </button>
            </ion-item-options>
        </ion-item-sliding>

Hi,
I am working on ionic 2.0. how can i reduce the left navigation width.

How are you handling Gestures with rtl in v2?

I need to fix it for iOS platform in ionic v1. Not sure how iPhone capture swipe-right in RTL.

I was able to change the direction of sidemenu and swiping direction in rtl.
https://github.com/msoni11/ionic/releases/tag/v1.1.1-rtl
https://github.com/msoni11/ionic-bower/releases/tag/v1.1.1-rtl

When RTL feature will be publish, it would be able to change it after running the app (i mean live change between ltr to rtl?
Just like native apps that have change language page in app.

@MatanYed : Yes it will. It must actually. It's pretty straight in hybrid app by just changing direction and text-align using CSS.

@mhartington : when using floating ion-label with RTL direction, the floating label does not being aligned to the right, but somewhere in the middle, when typing text in the input field.
is there any solution for it?

<ion-list dir="rtl"> <ion-item> <ion-label floating >{{ usrTitle }}</ion-label> <ion-input type="text" [(ngModel)]="usrValue"></ion-input> </ion-item> <ion-item> <ion-label floating >{{ pswTitle }}</ion-label> <ion-input type="password" [(ngModel)]="pswValue"></ion-input> </ion-item></ion-list>

floating

+1

@royipressburger (_regards "+1"_) - there is "thumb up" emoticon & "Subscribe" button if you want to support or follow.

@mhartington, @msoni11: any answer? i'm really stuck with it.

@devoraf : I'm not sure which version of ionic you are using. In ionic v1 I've played with RTL css and form element worked for me.

@msoni11: ionic v2. did this particular floating behavior worked well for you?

@devoraf : I haven't tried v2 yet. My app has a lot of code written in v1 so I hacked v1 to allow RTL.

@msoni11 : can you please attach sample css that might effect the alignment/direction of the floating label?

+1

@devoraf : Sorry but I haven't used floating labels. I've used these form elements and made it right aligned for RTL.

I don't know if it has been stated, but even navigating through pages gets messed up when dir="rtl" is added to <html> tag. In Ionic 2 a lot of components I used did not support it and I ended up switching back to Ionic 1. Right now I can do something about components and haven't come across any that are a problem for me, but the navigation gets messed up and I get white screens or laggy pages. When I remove dir="rtl" everything works perfectly.

Am I doing something wrong or $state.go() actually does not work with rtl at all?

@loolooii : You have to add css to make ionic 1 work for RTL

.rtl, html[dir=rtl] {
  direction: rtl;
  text-align: right;
}

/** To fix empty page issue in rtl. **/
.rtl .click-block-hide {
  @include translate3d(9999px, 0, 0);
}

Use this ionic rtl version https://github.com/msoni11/ionic/releases/tag/v1.1.1-rtl and you will be able to swipe right in RTL.

@msoni11 Thanks! Awesome stuff.

@loolooii : :) I've written a small post also where I mentioned how actual implementation will work in ionic app. Check here

Any update about the RTL issue?

Any updates regarding this ? , also why ionic team removed it from beta 12 ?

I think if we list all the RTL issues from developer feedbacks, we can contribute and fix them one by one, eventually, we will end up with full RTL support.

RTL is really important! Is there a timeframe?

@AmitMY Not sure about ionic2 but for ionic1 one of my live app is running pretty well with RTL support.

@msoni11 Thanks. I am talking about Ionic2.

@AmitMY @msoni11 I will work soon in a mid-size project using IONIC 2, then I will spot all RTL Issues if any .

@Khalid-Nowaf : I would be happy to help.

@msoni11 thanks! I will keep you guys posted.

RTL was present in road map RC 12, i don't know why they dropped it ?!

Hello, I don't see ion-slides in this long thread?
It too needs support.
I have posted here a request
http://idangero.us/swiper/forum/#!/general:support-for-pagination-righ

my workaround, not coded yet, would be to populate the slides backwards, and move to last slide upon start. I assume I have the right events to detect end of play, when playback reaches 1st slide :)

A word of caution although I am not an expert.
I hope the RTL support is planned at the component level and not only and exclusively at the app level.

I may want my app mostly in English, like tabs/button labels but the actual consumable content in Arabic. For example, like the behavior of a slider/pager desired or configurable to RTL because of its text and graphics RTL orientation.

index 44

index 45
yup! I already got rid of that nasty scrollbar.

Also I may have a page with 2 lists each in a different language.

<ion-list flow=RTL>....
<ion-list flow=LTR>.... 

When in rtl mode, there is no margin between range and its labels, hence the icons on both sides are partially not visible.

As part of this we should also look into this issue https://github.com/driftyco/ionic/issues/10685

Hey all, we're moving the tracking of RTL support in to this issue
https://github.com/driftyco/ionic/issues/11211

Brandy will doing some work to get this going so expect to see it soon.

there are lots of messages here , i didn't find the solution as i'm not good at english .
can someone lead me to the solution of direction of the menu, because when it changes to left there animation it opens from left to right , and the swipe still from left to right also.
please any help.

@joesleiman There is no solution for you at the moment. A fix is suggested in https://github.com/driftyco/ionic/pull/11336 and is pending review.

@AmitMY ok thank you . i have another problem how to change the direction to rtl from html tag in index.html or ion-app or body because the ion-select it's not under <ion-nav> where i change the direction. can you lead me to a solution if you know ?

@joesleiman: If you're using ionic1, I've fixed it under this tag https://github.com/msoni11/ionic/releases/tag/v.1.1.1-rtl.1

You can review and apply changes.

You set your default 'dir' on the HTML tag, and if you want to change it in runtime, you do 'this.platform.setDit('rtl', true)'.

Don't use the dir attribute anywhere else, as nested directions are not supported.

Finally, please use the nightly version, as it is more RTL ready than 3.2.1

If you have any other support questions, please use the ionic forum, and for bugs/features use github

@msoni11 no ionic 3.2.0

@AmitMY i'm using in all my app in every root tag [att.dir]='isRtl? 'rtl':'ltr'' (in every form : like ion-content)
isn't good ?

@joesleiman
for now, I use material design page transition only, which is an alternative to avoid page transition from left to right.

javascript // in app.module.ts . . imports: [ BrowserModule, IonicModule.forRoot(MyApp, { pageTransition: 'md-transition' // change the page Transition to avoid "LRT" page Transition }) . .

@AmitMY how can i change the back button icon to right arrow instead of left arrow (when change it to rtl)

@joesleiman No, having dir="rtl" on ion-content is not guaranteeing support. You should always use this.platform.setDir('rtl', true) and remove all of the dir attributes except the one in the html tag. It also controls direction of ionic components from typescript, such as gestures. (note that setDir with true also updates the html tag with the correct dir)

About the back button, if you use the proper way to set direction, as mentioned above, it will flip your arrows, as done here - https://github.com/driftyco/ionic/pull/11634. It is only available in the nightly version, and a new version (3.3.0) will be released later today.

I ask again, please, for these kind of support questions use the forum. Github is for bugs/feature requests.

You can read more about RTL here - https://github.com/AmitMY/ionic-site/blob/543cc0dd6d198edd5aa2a9a31ac5bd4702ef5332/content/docs/rtl-support/index.md
This is the official RTL documentation, but it is not yet done so it is not in the website.

@AmitMY ok i will do ... thank you so much ,

@AmitMy if the user put this.platform.setDir('rtl',true); and close the app and then return to it how can i save for html tag dir='rtl' . so isn't good idea to use it. because it return to dir="ltr"

@joesleiman So if your app is multidirectional, and you use the user preferences to decide which side, I would recommend using NativeStorage, and storing for the key "preferences" the object: {lang: "he", dir: "rtl"}, and then in app.component.ts on platform.ready check if the user has preferences. If he does, apply them by setDir.

No other solution for now.

@AmitMY when i use setDir : still the ion-select >> ion-alert : have issue in rtl direction on md (android)

@AmitMY i solved it by this :
html[dir="rtl"] .alert-md .alert-radio-icon {
left: 0px;
right: 13px;
}

I think you are not using the nightly version as I suggested (3.2.1-201705231529), and if you are using it, it is a case of overridden style, and it is fixed here https://github.com/driftyco/ionic/pull/11635

@AmitMY can you complete the discussion here because i'm finding more and more bugs:
https://forum.ionicframework.com/t/how-can-i-change-the-back-button-in-header-arrow-to-the-right/91591

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gio82 picture gio82  ·  3Comments

GeorgeAnanthSoosai picture GeorgeAnanthSoosai  ·  3Comments

fdnhkj picture fdnhkj  ·  3Comments

giammaleoni picture giammaleoni  ·  3Comments

brandyscarney picture brandyscarney  ·  3Comments