Dynamic CSS properties in LESS?

I am writing a smaller stylesheet for a bi-directional website, and I need to write a file with fewer files and create two different stylesheets for left-to-right layouts (ltr), and the other for right-lef layouts (rtl)

so when I am old for rtl layouts, I want to convert each left value to the right, fade, it is float, padding or margin,

for this, I defined the required variables at the top of my smaller file as follows:

@left: right; @right: left; 

simple, I can dynamically move elements this way

 float: @left; // this will be floated to left in ltr layout while it will be right in rtl layout. 

but my problem is that I want to be able to use these variables to create dynamic properties, for example, when the positioning elements are absolute or relative, I want to be able to write the left or right property dynamically depending on the value of the @left variable as follows

 position: relative; @left: 10px; 

but it gives an error while compiling, any key how to do it. Notice that I did this with SASS, but so far I have not been able to get it to work with LESS?

+6
source share
4 answers

Below is a solution that allows you to write styles once using LESS, and then compile them as two different CSS stylesheets for rtl and ltr maps.

basically we will have three LESS files (they can be more!):

 style-ltr.less // this where we hold the rtl variables style-rtl.less // rtl variables main.less // here we'll write our styles 

in style-ltr.less following variables are defined:

 @left: left; @right: right; @import "main.less"; 

and in style-rtl.less they will have the following meanings:

 // reflect variables @left: right; @right: left; @import "main.less"; 

now in main.less , we will define the following mixins

 .left(@distance) when (@left = left) { left: @distance; } .left(@distance) when (@left = right) { right: @distance; } .right(@distance) when (@right = right) { right: @distance; } .right(@distance) when (@right = left) { left: @distance; } // now we can style our elements using these mixins div.something { position: relative; .left(10px); float: @left; } 

now all we need to do is enable style-rtl.less in rtl pages include (or a compiled version of css), and also enable style-ltr.less on ltr pages, and div.something will move left on ltr pages, in while it will move right on rtl pages

Note that you can define padding, margin, border-radius ...etc. in the same way here.

UPDATE

I created two projects on github to create bi-directional applications

Credits:

inspired by my dear friend Victor Zamfir

+9
source

If you are using DotLess, there is something more interesting that you can use instead of defining a finite number of mixins here.

It is built into the RTL plugin.

https://github.com/dotless/dotless/wiki/Plugins

 dotless.Compiler.exe -p:Rtl:forceRtlTransform=true,onlyReversePrefixedRules=false file.less 
+2
source

You can check this library: https://github.com/DevelopmentIL/direction.less

It has great support for many CSS rules. For instance:

 @direction: rtl; // use `rtl` or `ltr` @import "direction.less"; body { .direction(); } .float { .float(); } .box { display: inline-block; .margin-left(4px); .padding-right(1em); } 

It will display:

 body { direction: rtl; } .float { float: right; } .box { display: inline-block; margin-right: 4px; padding-left: 1em; } 
+1
source

Update: Take a look at Guard Expressions in LESS - maybe this can help a bit, you can create conditional conditional expressions, but you need to use mixins.

I understand your point of view, but, on the other hand, I would apply this problem in a different way. Here is another simplified example: you define variables for differences in both cases, and then import as you like - for example, put in master-ltr / master-rtl and import the remaining stylesheet after:

 // master-ltr.less // LTR: @sidebar-pos-left: 10px; @sidebar-pos-right: 0px; @content-float: left; ... @import 'styles.less'; // your styles.less would have: .content { float: @content-float; ... } .sidebar { position: relative; left: @sidebar-pos-left; right: @sidebar-pos-right; ... } 

.. or maybe more efficiently - create a separate file with vars-ltr / rtl, and then import it into your master-ltr / rtl.

Not sure how complicated the layout is, but maybe this gives you something you can use?


I tried this using String Interpolation , but it looks like variables can only be embedded in the "variable" definitions. Maybe I'm wrong, maybe people know how to achieve this.

I would do it a little differently, not because it is impossible with LESS, but because of the organization of the code and the general more reasonable approach (it is not good to call something β€œleft” when sometimes it will be actually β€œright” :)

For your second problem with position:relative , here is my take:

 <div class="element element-ltr">...</div> .element { position: relative; &.element-ltr { left: @element-side-position; } &.element-rtl { right: @element-side-position; } } 

This solution seems to be OK, but if you are a huge stylesheet, you will have many additional classes for -ltr and -rtl. Not a big pain, but you could make it even more useful by expanding the -ltr / -rtl area to the parent containers (e.g. header / content / sidebar / footer) and then adjust from there. They can have a lot in common, such as background, colors, font size .. and you will just work on the differences in their versions of -ltr / -rtl.

Also, read the LESS Namespaces , they can offer you even more organization options.

Hope this helps!

-1
source

Source: https://habr.com/ru/post/907582/


All Articles