0

is it possible to += (plus-equal) a string in LESS (less-css)?

I am trying to create a loop to extend a string.

In particular I am trying to create a mixin (no inline JS) that can add vendor prefixes to transform in transition-propery

basic for loop

// for-loop
// works with two integers or a list
.for(@i;@n) when     (@i <= @n)     {.-each(@i);}
.for(@n)    when not (isnumber(@n)) {.for(1;length(@n));}
.for(@i;@n) when not (@i = @n)      {.for(@i + 1;@n);}

prop loop (duplicated for loop to resolve variable overrides)

// prop-loop
// works with two integers or a list
.prop(@in;@n) when     (@in <= @n)   {.-prop(@in);}
.prop(@n)    when not (isnumber(@n)) {.prop(1;length(@n));}
.prop(@in;@n) when not (@in = @n)    {.prop(@in + 1;@n);}

transition property

.transition-property(@values) {

    @vendorPrefixes: -webkit-, -moz-, -o-, ' ';
    // http://caniuse.com/#search=transition
    // http://caniuse.com/#search=transform
    .for(@vendorPrefixes);.-each(@i) {
        @vendorPrefix: e(extract(@vendorPrefixes, @i));
        .prop(@values);.-prop(@in) {
            @value: e(extract(@values, @in));
            .-call(@v) when (@v = transform){
                @prop: e('@{vendorPrefix}@{v}');
            }
            .-call(@v) when not (@v = transform){
                @prop: @v;
            }
        @propList: @prop;
        .-call(@value);
        }
        @{vendorPrefix}transition-property: @propList;
    }
}

of course the above example does not work it only returns the last value

If I try something like:

@prop: '';
@propList: @propList @prop;

I get SyntaxError: Recursive variable definition for @propList

If I only use one property it works. Only using multiple values without any prefixes is also not a problem (different mixin structure needed).

So what is really missing is an operator that will allow to extend the existing string (list of keywords)

Any Ideas how to get it to work WITHOUT inline-js is appreciated.

Reason: I am currently trying to use less 1.6.x to make a less-hat-like library without all the inline-javaScript,

TESTS

.transition-prop-transform {
// works
    .transition-property(transform;);
}
.transition-prop-mutli-with-transform { 
// fails: only return the last value (height)
    .transition-property(transform, color, height;);
}
.transition-prop { 
// works
    .transition-property(height;);
}
.transition-multi { 
// fails: only return the last value (color)
// works with a different mixin
    .transition-property(height, width, color;);
}

GOAL

// input
.transition-prop-mutli-with-transform {
    .transition-property(transform, color, height;);
}
// output
.transition-prop-mutli-with-transform {
  -webkit-transition-property: -webkit-transform, color, height;
  -moz-transition-property: -moz-transform, color, height;
  -o-transition-property: -o-transform, color, height;
  transition-property:  transform, color, height;
}
  • Hm. as soon as I posted this question I found this http://stackoverflow.com/questions/21061361/less-js-mixin-property-as-an-argument-of-another-mixin?rq=1 in the sidebar. maybe I can apply some of the stuff. –  Feb 02 '14 at 14:20
  • (I'm assuming you have read the "greatest misuse" remark at http://stackoverflow.com/a/21068438/2712740. But either way here it is again: Don't make autoprefixing Less libraries/mixins. All your hard efforts go to dev/null by just one line: 'autoprefixer my.css' (or similar)). – seven-phases-max Feb 02 '14 at 14:46
  • It's all about the fun behind it. Really.. ;). Misuse? I like minimal dependency stuff, so if I can use 'one' tool instead of 'multiple', that's the way I choose. And to mention it again: IT'S ALL ABOUT THE FUN BEHIND IT. Anyways: the less.js webpage shows auto-prefixing as the mixin example o_O. –  Feb 02 '14 at 15:12
  • >Misuse? Yep. 100%. (It's fine to put a few vendor prefixes here an there but making a library... Well, it's your time so I guess you decide how to waste it). – seven-phases-max Feb 02 '14 at 15:16
  • ah.. waste is such an awful word. I guess studying must be the greatest waste of all. Anyways.. thanks for your answers (in general). Most of them are really helpful. –  Feb 02 '14 at 15:28
  • >minimal dependency - You're forgetting that you just replace a tool dependency with a library dependency *plus* make your Less/CSS code cryptic. Maybe some kind of animation library would be more useful to experiment with those list technique/tricks? – seven-phases-max Feb 02 '14 at 15:29
  • Either way, speaking of "Property Merging" feature, it's documented [here](https://github.com/less/less-docs/blob/master/content/features/merge.md) plus a minor extension for it discussed [here](https://github.com/less/less.js/issues/1756) – seven-phases-max Feb 02 '14 at 15:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/46633/discussion-between-pixelass-and-seven-phases-max) –  Feb 02 '14 at 16:37

2 Answers2

0

To answer the question itself, yes, for the "right-side values" concatenation is possible via escaped strings, e.g.:

@a: foo;
@b: bar;
@c: baz;

.concat {
    1: ~'@{a}@{b}';
    2: e('@{b}@{c}');
}
seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
  • concatenating is not a problem. I know how to do that ;). I was actually looking for a "+=" operator for values which was nicely answered by you in another question. (see my own answer above) –  Feb 02 '14 at 15:06
0

See my comment above:
Help from this Answer: Less js: Mixin property as an argument of another mixin?

I was able to get it to work

the clue was to add the "+" property+: value;

Final Code (covers all tests from above)

.transition-property(@values) {

    @vendorPrefixes: -webkit-, -moz-, -o-, ~'';
    // http://caniuse.com/#search=transition
    // http://caniuse.com/#search=transform
    .for(@vendorPrefixes);.-each(@i) {
        @vendorPrefix: extract(@vendorPrefixes, @i);
        .prop(@values);.-prop(@in) {
            @value: e(extract(@values, @in));
            .-true() {@{vendorPrefix}transition-property+: ~'@{vendorPrefix}@{value}';}
            .-false() {@{vendorPrefix}transition-property+: @value;}
            .-call(transform) {.-true;}
            .-call(box-shadow){.-true;}
            .-call(...) when (default()){.-false;}
            .-call(@value);
        }

    }
}

UPDATE:

(exported mixin)
// for-loop
// works with two integers or a list
.for(@i;@n) when     (@i <= @n)     {.-each(@i);}
.for(@n)    when not (isnumber(@n)) {.for(1;length(@n));}
.for(@i;@n) when not (@i = @n)      {.for(@i + 1;@n);}

// prop-loop
// loop through values for vendor-prefixing
.prop(@p;@in;@n) when     (@in <= @n)    {.-vendor(@p;@in);}
.prop(@p;@n)     when not (isnumber(@n)) {.prop(@p;1;length(@n));}
.prop(@p;@in;@n) when not (@in = @n)     {.prop(@p;@in + 1;@n);}

// prefix properties
.-vendor(@prop;@in) {
    @value: e(extract(@values, @in));
    .-true() {@{vendorPrefix}@{prop}+: ~'@{vendorPrefix}@{value}';}
    .-false() {@{vendorPrefix}@{prop}+: @value;}
    .-call(transform) {.-true;}
    .-call(box-shadow){.-true;}
    .-call(...) when (default()){.-false;}
    .-call(@value);
}

.transition-property(@values) {
    @vendorPrefixes: -webkit-, -moz-, -o-, ~'';
    // http://caniuse.com/#search=transition
    // http://caniuse.com/#search=transform
    .for(@vendorPrefixes);.-each(@i) {
        @vendorPrefix: extract(@vendorPrefixes, @i);
        .prop(transition-property;@values);
    }
}

Update

Here's another example (a little more advanced) using the method suggested by @seven-phases-max (concatenating variables). content: '@{a} @{b}'

LESS:

https://github.com/pixelass/more-or-less/blob/master/examples/less/animaless/animaless.less

Demo:

http://pixelass.github.io/more-or-less/examples/animaless.html

Community
  • 1
  • 1
  • Technically, the solution at http://stackoverflow.com/a/21068438/2712740 could be improved by changing the "value vendorization" method from "mixin specializations" list to a simple value list + a .find mixin (the implementation will become more verbose but much more straight forward in general, assuming the solution is supposed to vendorize any property and any value (as soon as they are in the lists)). But I did not bother to craft that for obvious reasons. – seven-phases-max Feb 02 '14 at 15:46