less / less.js

Less. The dynamic stylesheet language.
http://lesscss.org
Apache License 2.0
17.03k stars 3.41k forks source link

[Feature Request] Add automatic RTL-ization of output #642

Closed mushon closed 10 years ago

mushon commented 12 years ago

Localization is one of the major headaches facing Middle Eastern Open Source hackers, we write from right to left and need to both translate the language (Arabic, Farsi, Hebrew, Urdu…) and flip the layout. Flipping the layout and the css declarations from LTR (Left-To-Right) to RTL (Right-To-Left) is definitely a major challenge for us. I would even say it has tremendously hindered the success of Open Source software in the region.

Less.js and its preprocessing workflow provides an opportunity to quickly and 'DRY'ly overcome a lot of this hurdle.

Without going into too much details, what's mainly required is a way to parse through the output css and automatically change "left" to "right" in properties (such as "margin-left: 10px" => "margin-right: 10px") and values (such as "float: left" => "float: right") and to flip the declaration positions in 4 valued statements (such as "padding:1px 2px 3px 4px" => "padding:1px 4px 3px 2px").

I am imagining this can elegantly work by extending the @import property:

@import(rtl) "lib.less";

This would allow 2-ways direction flipping and a seamless mix of cross-directional libs.

Some reference can be found in previous solutions such as:

What do you guys think, is this something that can find its way into Less.js? Any interest in helping pull this off? Patches anyone?

louy commented 12 years ago

great idea!

lukeapage commented 12 years ago

In dotless we've added the concept of plugins which can alter nodes before or after evaluation. As I support rtl in my real job I added a plugin which reverses certain rules.

I settled on using a vendor prefix type format / option for whether all relevant rules should be reversed or rules must be marked for reverse e.g.

-float: left;
-ltr-reverse-border-left: 4px;
-ltr-margin-left: 4px;
-rtl-margin-left: 3px;

would become in RTL with the option for all rules

float: right;
border-right: 4px;
margin-left: 4px;

and for marked rules..

float: left;
border-right: 4px;
margin-left: 4px;

https://github.com/dotless/dotless/blob/master/src/dotless.Test/Plugins/RtlPluginFixture.cs

lukeapage commented 12 years ago

My point (sorry for 2 comments!) was that I would love to see this part of less but it needs to be flexible - I'm not sure having to have rules that are reversed in a seperate file is good enough..

mushon commented 12 years ago

@agatronic this could be a good approach if you're building your less files from scratch, but it does not address the case of localizing a less file which has not taken RTL into account from the get-go. Specifically I'm arriving at this from my work on localizing Twitter Bootstrap.

As I was thinking about it a new possible solution came to mind: develop rtl.js If less.js is (well) a js file that preprocesses less syntax into css, why not develop a similar approach to preprocess less (or any css) to rtl. This file could be used in runtime after less.js, fired from the command line or packed together in apps such as Codekit. It should be able to take exceptions (to pre tags used for code for example) and it could provide the foundations to multiple forks that could be used in less.js, in dotless, in Sass and what not…

This would probably be a more forward looking solution, what say you?

lukeapage commented 12 years ago

@mushon - why does it not address the case when localizing a file that has not taken rtl into account from the get go?

with my approach you can switch on an option that will reverse everything, then run through and mark properties that should not be reversed?

In my situation (before the plugin) I have a rtl.css file that is included that overrides half the rules in my main css and every time we edit or alter css we have to edit both the main file and the rtl file. In that approach I can decide to only reverse marked properties and slowly get rid of the seperate rtl file. In the case where it hasn't be considered before we can switch it on and mark properties to not reverse.

The problem with an import is that you then have to seperate changes that require rtl-ization and changes that don't - forces rtl onto the file structure, rather than leaving the file structure to be whatever you like and integration rtl to where your main definitions are.

With regards a way to post- or pre-process less, your solution is exactly the same as what I have done, except plugins use the existing structure and parsing that less has already done.. we have implemented a visitor pattern on the nodes and then a plugin can visit the nodes before less outputs the css and alter whatever it wants.

mushon commented 12 years ago

Interesting… I might have not understood you correctly then, I am not familiar with DotLess. So you are saying RTL-izing any less (or css) file using your DotLess rtler would be pretty straight forward? Is it written in .Net or in .js? Can you refer me to the plugin so I can further investigate? Btw, @louy is the dev behind the RTLer (different approach then taken by CssJanus) written in PHP, originally as a WordPress plugin.

So many different approaches, all doing things slightly different but facing the same challenge. I still think there's room for a rtl.js project, or at least rtl.json with the regex rules that we can all use collaboratively.

@cloudhead, any plans on supporting plugins? Or any other suggestions on how might we be able to use Less seamlessly while outputing both rtl and ltr files for different uses?

cloudhead commented 12 years ago

ill look into it, I like the import idea

zohararad commented 12 years ago

After speaking to @mushon about this, I believe supporting this inside LESS is a bad idea as IMHO the less engine should focus on what it's meant for (which is not bidi support). take a look at https://github.com/ded/R2 which seems to provide a compelling alternative

mushon commented 12 years ago

Fair enough. If we can have some way to auto-RTL-ize the less files we should be good to go.

The question is whether R2 does a good enough job. I kinda wish there would have been a way for all of these projects to collaborate on a "what needs RTLizing and how". Maybe through a JSON file? Think about it. If the layout is flipped even the box-shadow directionality might need flipping. Not sure this is accounted for in the existing solutions.

On Feb 29, 2012, at 14:52, zohararad reply@reply.github.com wrote:

After speaking to @mushon about this, I believe supporting this inside LESS is a bad idea as IMHO the less engine should focus on what it's meant for (which is not bidi support). take a look at https://github.com/ded/R2 which seems to provide a compelling alternative


Reply to this email directly or view it on GitHub: https://github.com/cloudhead/less.js/issues/642#issuecomment-4236844

lukeapage commented 12 years ago

Closure stylesheets solution is the best one I've found.

Just RTL-ing a single file is going to be inadequate for most people - it requires some kind of mark-up to be useful. And that markup either has to survive less processing or be part of less.

But if RTL-ing a single file is adaquate for you, maybe an external program is the best idea.

moesaeed commented 12 years ago

writing bi-directional stylesheets in less http://anasnakawa.github.com/bi-app-less/

ehdv925 commented 11 years ago

I'd like to suggest a pair of different methods: Allow the use of "margin-near" and "margin-far", et cetera (or allowing inclusion of variable names in attribute declarations. The near/far usage doesn't conflict with any existing CSS rules, and makes opting in very concise. The use of variable values in attributes is more far-reaching, but possibly also more powerful.

elkebirmed commented 11 years ago

2 years later and nothing done for this feature: please take this thing seriously as RTL layout grow up faster

lukeapage commented 11 years ago

@elkebirmed we are taking it seriously and are open to ideas - however this is also open sourced development so for this to get done it requires a developer who wants to see this done. You are welcome to help.

lukeapage commented 10 years ago

technically I think this is best served as a plugin. also lack of development. closing.