Question

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;
}
Was it helpful?

Solution 2

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

OTHER TIPS

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}');
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top