Do you know of an example of a theme that does not work with RTL? If you do, post a link to the theme here and I will test out my theory and explain what is going wrong after I test it.
Edit: Here is an explanation of the issue:
For the CSS files that are in the main Discourse codebase, the RTL CSS is created by “flipping” most of the CSS rules that are dependent on the direction of the site’s layout. For example, padding-left
gets flipped to padding-right
. This is done with the RTLcss gem: GitHub - discourse/rtlcss: A wrapper around the rtlcss npm package to flip CSS direction in Ruby.
The problem is that Discourse themes do not get their CSS rules flipped. That means that if a theme has CSS rules that specify a direction, the direction will be the same when an RTL language is used as when a LTR language is used. Here’s a minor example of that:
When the theme is used with an RTL interface padding-left: 8px;
is not getting flipped to padding-right: 8px;
This causes a minor issue with alignment. I am sure there are examples of bigger issues that happen when themes are used with an RTL language.
The same is true for any CSS that you add to a default Discourse theme in the theme editor. Here is an example using the code from this topic: Can it be done with CSS? Grouping categories on category page - #4 by cosdesign.
Here is a rule from that CSS that sets a direction:
body [data-category-id="2"]::before,body [data-category-id="4"]::before {
position: absolute;
top: -35px;
left: 0; // this needs to be changed
font-weight: bold;
font-size: 15px;
text-transform: uppercase;
color: var(--primary-medium);
}
With an RTL locale, this is the issue:
If that rule was in a core Discourse CSS file, left: 0;
would be automatically converted to right: 0;
when an RTL language was selected. Because the CSS is added to a theme, you need to manually edit it to this:
body [data-category-id="2"]::before,body [data-category-id="4"]::before {
position: absolute;
top: -35px;
right: 0; // changed to the proper position for RTL layouts
font-weight: bold;
font-size: 15px;
text-transform: uppercase;
color: var(--primary-medium);
}
Discourse adds an rtl
class to the html
tag when an RTL layout is used. Theme developers could use this class to make their themes work both for LTR and RTL layouts. This works, and I think it’s correct, but possibly the left: auto
declaration doesn’t need to be there.
body [data-category-id="2"]::before,body [data-category-id="4"]::before {
position: absolute;
top: -35px;
left: 0;
font-weight: bold;
font-size: 15px;
text-transform: uppercase;
color: var(--primary-medium);
}
/* Fix positioning for rtl layouts */
.rtl body [data-category-id="2"]::before,.rtl body [data-category-id="4"]::before {
right: 0;
left: auto;
}
I am not sure if developers should take this approach with their themes. It is time consuming and could lead to errors and maintenance issues. Maybe Discourse could compile some themes could consider providing an RTL version. It might be worth testing out this approach with a few of them:
require "rtlcss"
Rtlcss.flip_css("theme_css")
This was supposed to be a short answer If what I have written is correct and has not been dealt with in another topic, maybe it should be moved to a new topic.