FortAwesome / Font-Awesome

The iconic SVG, font, and CSS toolkit
https://fontawesome.com
Other
73.7k stars 12.19k forks source link

RTL support #3505

Open muhammad-saleh opened 10 years ago

muhammad-saleh commented 10 years ago

Dears, I'm making a rating component and it supports RTL and after using your great font I found that all of your half full / half empty stars looks right only with LTR applications

In LTR the empty side is on the right which is correct In RTL the empty side is on the right too which unfortunately is wrong

Images to explain: LTR: http://imgur.com/HxgorFe

RTL: http://imgur.com/BUWjdWk

Stars Icons you have: http://imgur.com/glwNNBC as you can see the full side of the half empty star is always on the left

Thanks.

MrGeneric commented 10 years ago

There are some existing classes that can be used to rotate and flip icons. http://fortawesome.github.io/Font-Awesome/examples/

fa-flip-horizontal should cover your needs :)

muhammad-saleh commented 10 years ago

@MrGeneric thank you for your reply fa-flip-horizontal uses CSS3 to rotate the icon and I support IE8 :) Also in the arrows icons FontAwesome provided all of the arrows directions and I now I wonder why didn't they do the same for the stars

tagliala commented 10 years ago

@muhammad-saleh good point

We could release an rtl stylesheet which flips icons that need to be flipped

tagliala commented 10 years ago

@muhammad-saleh as far as I can remember, IE8 supports flipping via filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)

muhammad-saleh commented 10 years ago

@tagliala Yes I just knew that :) Also I found out that fa-flip-horizontal includes this line to flip the icons for IE I will now close the issue as I guess now is invalid Thank you all for your support

tagliala commented 10 years ago

you're welcome, but I will reopen this issue for tracking purposes

Renamed as RTL support

tagliala commented 10 years ago

Can we make a todo list of what needs to be done?

E.g:

?

We can then create a separate stylesheet rtl.less and add all the fixes needed.

Of course last word is up to Dave but this undoubdtedly is good feature

elad commented 10 years ago

Hello,

Just saw this was referenced in the issue I opened recently and I'm very happy to see there's interest in addressing it. :)

One question though: Is there a clear preference for a separate RTL stylesheet? I maintain a multilingual (and bidirectional) app and found that it's a lot cleaner to keep one stylesheet with direction-dependent rules rather than separate stylesheets.

tagliala commented 10 years ago

@elad

I mean rtl.less alongside all other less stylesheets here: https://github.com/FortAwesome/Font-Awesome/tree/master/less so you can include it or exclude it in your build according to your needs.

BTW I never had the chance to write an RTL website, so I'm far from being an expert.

I started this playground: http://jsfiddle.net/tagliala/2tsff0nL/ (note: it uses SCSS instead of CSS for faster integration with FA)

The purpose is to provide the minimum amount of stylesheet needed to support RTL.

Variables are here: https://github.com/FortAwesome/Font-Awesome/blob/master/scss/_variables.scss

elad commented 10 years ago

I think this is a step in the right direction. I do have one comment though.

I find it very confusing when left and right definitions are direction-dependent. For example, standard CSS flipping techniques produce results such as:

.text-left {
  text-align: right;
}

.text-right {
  text-align: left;
}

This is obviously not what the documentation suggests even if it does help create RTL websites. It assumes too much.

In the playground you referred to, for example, the fa-arrow-left class is actually pointing right. What if the icon desired is, in fact, an arrow pointing left? (Case: Driving/walking instructions.)

That's why my preference is for classes that convey what the content is supposed to display. If I want a left-pointing arrow, I will use fa-arrow-left. If I want an arrow pointing in the writing direction, I'll use fa-arrow-dir. And if I want an arrow pointing in the opposite direction, I'll use (say) fa-arrow-flipdir.

Modifying the CSS you posted in the playground, this would look like so:

/* Add here variables required by rtl support */
$fa-var-arrow-left: "\f060";
$fa-var-arrow-right: "\f061";

.fa-arrow-left { &:before { content: $fa-var-arrow-left; } };
.fa-arrow-right { &:before { content: $fa-var-arrow-right; } };
/* Direction-dependent support starts here */
body[dir=ltr] {
    .fa-arrow-dir { &:before { content: $fa-var-arrow-right; } };
    .fa-arrow-flipdir { &:before { content: $fa-var-arrow-left; } };
}
body[dir=rtl] {
    .fa-arrow-dir { &:before { content: $fa-var-arrow-left; } };
    .fa-arrow-flipdir { &:before { content: $fa-var-arrow-right; } };
}
/* Direction-dependent support ends here */

And then:

<span class="fa fa-arrow-left"></span> This arrow is pointing left
<span class="fa fa-arrow-right"></span> This arrow is pointing right
<span class="fa fa-arrow-dir"></span> This arrow is pointing to the writing direction

RTL support often suffers what I call "the mirror effect" which is arbitarily-applied flipping of content and visualizations. Windows 98 (!), for example, flipped everything, including icons, and the results weren't pretty. :)

tagliala commented 10 years ago

thanks, got it and I do agree. Like I said, I didn't know about RTL and I was confused about the left/right arrow stuff and I thought it was normal

Feel free to edit the fiddle and post the updated version. That will require extra aliases (arrow-dir, circle-arrow-dir but it is ok)

Meanwhile you can check icons that needs to be flipped and flip that one

elad commented 10 years ago

Here's an updated fiddle: http://jsfiddle.net/2tsff0nL/2/

It provides -dir and -flipdir classes for directional icons. The stars require actual flipping so I haven't added that yet, but if the relevant CSS is kept in a variable it should be trivial to add.

tagliala commented 10 years ago

can we automatize this? I mean

  1. Look for all icons ending in -left or -right
  2. Provide -dir and -flipdir aliases for the above icons
  3. Override -dir and -flipdir aliases for body[dir="rtl"]
elad commented 10 years ago

Oh, sure. I was also thinking about the following case:

<html dir="rtl">
    <body>
        <div dir="ltr">
            <i class="fa fa-arrow-dir"></i>
        </div>
    </body>
</html>

Any thoughts on whether this should be supported, and if so, how?

tagliala commented 10 years ago

ah ok got it. so body[dir=rtl] needs to be a universal selector like *[dir=rtl]

elad commented 10 years ago

I thought so too but couldn't get it to work, I think because the wrong rule would override. Does it work for you?

fisharebest commented 10 years ago

BTW I never had the chance to write an RTL website, so I'm far from being an expert.

I've done a fair bit, and have access to hebrew/arabic speaking testers...

Is there a clear preference for a separate RTL stylesheet?

We can then create a separate stylesheet rtl.less and add all the fixes needed.

Are you thinking that RTL pages will load this extra stylesheet, which will mirror everything? If so, this won't work on sites that have both RTL and LTR on the same page, e.g. any site with user-generated content.

so body[dir=rtl] needs to be a universal selector like *[dir=rtl]

You don't need the *. Just [dir=rtl] works fine.

For icons, my preference is to add xxx-start and xxx-end versions of xxx-left and xxx-right. This mimics the familiar CSS constructs, such as text-align: start;, and allows us to specify exactly what we want - an arrow pointing left (e.g. turn directions), or an arrow pointing to the start of the line (e.g. got to previous page).

I haven't looked at how the fonts are defined, but unicode allows characters to be defined with a "mirror" property, meaning they are rendered in mirror form when used in RTL contexts. Parentheses are a good example. In RTL text, the open parenthesis is rendered as ). I don't know if this could be used. See http://www.unicode.org/reports/tr9/#Mirroring

tagliala commented 10 years ago

Are you thinking that RTL pages will load this extra stylesheet, which will mirror everything? If so, this won't work on sites that have both RTL and LTR on the same page, e.g. any site with user-generated content.

No, I mean as a .less file that should be included if need to enable if you want to support rtl in your website. I don't know how other frameworks deal with RTL

I haven't looked at how the fonts are defined, but unicode allows characters to be defined with a "mirror" property, meaning they are rendered in mirror form when used in RTL contexts. Parentheses are a good example. In RTL text, the open parenthesis is rendered as ). I don't know if this could be used. See http://www.unicode.org/reports/tr9/#Mirroring

Could you please identify all icons that needs to be mirrored?

As far as I understood, arrow-right should always point right so directional icons should be aliased rather than mirrored.

Do you have a fix or a better implementation of fa-ul? You can fix this fiddle: http://jsfiddle.net/tagliala/2tsff0nL/3/

fisharebest commented 10 years ago

No, I mean as a .less file that should be included if need to enable if you want to support rtl in your website.

For clarification, would these rtl.less files be included in font-awesome.less (to create a single font-awesome.css) or would they be included in font-awesome-rtl.less, (meaning that end-users would need to include a both font-awesome.css and font-awesome-rtl.css).

IMHO, they should all be included in a single font-awesome.less.

Do you have a fix or a better implementation of fa-ul?

The fixes for both fa-ul and xxx-start are pretty trivial. (I've fixed them on my own project...).

I could create a PR easily, but it would be good to know how to structure it.

Q1. Will RTL support actually be included in the core code. i.e. my first paragraph above.

Q2. Is RTL regarded as a "bolt-on fix", or part of the core code? i.e. should the fixes for fa-ul go in to list.less or in list-rtl.less or in rtl.less.

Q3. Should the LTR definitions of xxx-start go in icons.less or in rtl.css.

@muhamed - I haven't looked at mirroring the icons yet. It hasn't been a problem in my project yet(!). But IMHO, all icons should be mirrored by default. Places were we can't include those that contain brand logos, currencies, text, etc.

muhammad-saleh commented 10 years ago

Okay guys this is what I think we should do: As tagliala said we need to create a list of the icons that needs to support RTL I've done a lot of RTL websites I can be a tester for that if you want

I would suggest a separate stylesheet for RTL to just flip the icons there's no need to complicate things I guess :)

Also a nice technique while building (I'm using Sass) We add a variable to support RTL or not and if true then in the build process we create those 2 stylesheets one for LTR and one for RTL The core will be the same but we will just flip the icons that needs to be flipped

tagliala commented 10 years ago

For clarification, would these rtl.less files be included in font-awesome.less (to create a single font-awesome.css) or would they be included in font-awesome-rtl.less, (meaning that end-users would need to include a both font-awesome.css and font-awesome-rtl.css).

I was thinking about the first option, eg: https://github.com/FortAwesome/Font-Awesome/blob/master/less/font-awesome.less

@import "stacked.less";
@import "icons.less";
@import "rtl.less"; // maybe disabled by default because of universal selectors that slow down things?

I could create a PR easily, but it would be good to know how to structure it.

https://github.com/FortAwesome/Font-Awesome/blob/master/CONTRIBUTING.md#pull-requests

Since this is a new feature and requires to edit the font itself, (for mirroring glyphs) it needs work on Dave's side. Meanwhile we could prepare the css rules needed to support RTL and provide dave a list of glyphs to mirror

Q1. Will RTL support actually be included in the core code. i.e. my first paragraph above.

The last word is up to Dave, but even if it will not be included, we can start a wiki page and provide gists with working stylesheet. We could also mirror glyphs via css to provide full support.

Q2. Is RTL regarded as a "bolt-on fix", or part of the core code? i.e. should the fixes for fa-ul go in to list.less or in list-rtl.less or in rtl.less.

IMHO rtl.less, unless the fix works for both RTL and LTR, starting from IE8 and the fix does not contain [dir=rtl] rules.

Q3. Should the LTR definitions of xxx-start go in icons.less or in rtl.css.

IMHO rtl.less. Because like above there is no need to import ltr rules in ltr-only websites

Just my thoughts

elad commented 10 years ago

I like the "start" and "end" naming scheme.

Two comments:

IMHO rtl.less. Because like above there is no need to import ltr rules in ltr-only websites

Regardless of where the LESS rules end up, I think they should be included by default in the resulting CSS, possibly with a way to disable their generation. The reason is that the concepts of "start" and "end" for directionality aren't RTL-specific if we agree that the classes should convey what is the required visualization. It's just cleaner in my opinion. I also don't like having separate stylesheets...

Also, I still haven't seen a solution to the hierarchy problem I posted earlier, which is that in the following code:

<html dir="rtl">
    <body>
        <div dir="ltr">
            <i class="fa fa-arrow-end"></i>
        </div>
    </body>
</html>

The arrow should point to the end of the line as dictated by the dir-"ltr" tag, that is, to the right, despite the document itself being RTL. Any thoughts on how to address it?

MohammadYounes commented 9 years ago

You can control icons direction using the following CSS:

[dir=ltr].fa-dir-flip .fa.fa-flip-horizontal,
[dir=rtl].fa-dir-flip .fa,
[dir=rtl] .fa.fa-dir-flip {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
  -webkit-transform: scale(-1, 1);
      -ms-transform: scale(-1, 1);
          transform: scale(-1, 1);
}
[dir=rtl].fa-dir-flip .fa-flip-horizontal,
[dir=ltr].fa-dir-flip .fa,
[dir=ltr] .fa.fa-dir-flip {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=0);
  -webkit-transform: scale(1, 1);
      -ms-transform: scale(1, 1);
          transform: scale(1, 1);
}
:not([dir=rtl]) [dir=ltr] .fa.fa-dir-flip {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=0)!important;
  -webkit-transform: scale(1, 1)!important;
      -ms-transform: scale(1, 1)!important;
          transform: scale(1, 1)!important;
}

:not([dir=ltr]) [dir=rtl] .fa.fa-dir-flip {
  filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)!important;
  -webkit-transform: scale(-1, 1)!important;
      -ms-transform: scale(-1, 1)!important;
          transform: scale(-1, 1)!important;
}

It gives you the ability to do global and local flip for .fa icons (live demo)

  1. Globally, add direction attribute dir="rtl" and fa-dir-flip class:

    <html dir="rtl" class="fa-dir-flip">
    .
    .
       <!-- this will be RTL -->
       <span class="fa fa-arrow-left"></span>
    .
    .   
    <html>
  2. Locally, add direction attribute dir="rtl" to the container and fa-dir-flip class to the icon you want to flip.

    <html dir="rtl">  
    .
    .
        <div dir="ltr">
            <!-- this will be LTR, following the closest ancestor direction -->
            <span class="fa fa-arrow-left fa-dir-flip"></span>
            <!-- this will be RTL, falling back to the farthest ancestor direction -->
            <span class="fa fa-arrow-left"></span>
        </div>       
    .
    .
    </html>

PR ?

fisharebest commented 9 years ago

FYI, this is the solution I use in my projects: https://github.com/fisharebest/font-awesome-rtl

molerat619 commented 8 years ago

Hi, thanks for the ideas here - I like the approaches. But how can we actually use this now? Has anything been integrated?

evilaliv3 commented 5 years ago

@MahdiMajidzadeh: How difficult would be to implement for font awesome 5 the same thing that you have implemented for bootstrap 3 that was using glyphicons?