Less js: Mixin property as an argument of another mixin?

后端 未结 2 513
悲哀的现实
悲哀的现实 2020-12-06 15:43

How could I create a mixin that uses as an argument a nested mixin property?

I explain myself with the next example.

I have a \'transition-property\' mixin:<

相关标签:
2条回答
  • 2020-12-06 15:48

    OK, so first of all, a general remark: using a CSS preprocessor (e.g. LESS, SASS or whatever) to generate vendor prefixes is actually one of the greatests misuses these days (really, there's no need to bloat your code with prefixes and waste your time writing such mixins since tools like Autoprefixer, -prefix-free and similar came in).

    Either way here's a (sort of) generic solution (but considering amount of code and its complexity I think it's actually an overkill, here I will use LESS 1.6.0 example because in earlier versions it would be even more verbose and hackish):

    // usage:
    
    element1 {
        .vendorize(transition-property; opacity, transform);
    }
    
    element2 {
        .vendorize(transition-property; width, box-shadow, color);
    }
    
    element3 {
        .vendorize(transition-property; height);
    }
    
    // implementation:
    
    // prefixes we want to be used:
    @prefixes: -webkit-, -moz-, -o-, ~'';
    
    // here we specialize what values are to be prefixed:
    .vendorize-value(transform)  {.true}
    .vendorize-value(box-shadow) {.true}
    // etc.
    .vendorize-value(...) when (default()) {.false} // to handle not prefixed values
    
    // and now the mixin that can apply all of above specializations:
    .vendorize(@property, @values) {
    
        .-1();
        .-1(@i: length(@prefixes)) when (@i > 0) {
            .-1((@i - 1));
            @prefix: extract(@prefixes, @i);
            .-2();
        }
    
        .-2(@j: length(@values)) when (@j > 0) {
            .-2((@j - 1));
            @value: extract(@values, @j);
            .vendorize-value(@value);
        }
    
        .false() {@{prefix}@{property}+: @value}
        .true()  {@{prefix}@{property}+: ~'@{prefix}@{value}'}
    }
    

    (Of course it can be simplified a bit if you need only transform to be prefixed but still looks too crazy).

    upd: fixed some errors.

    0 讨论(0)
  • 2020-12-06 15:48

    It's a simpler solution by right of before:

    // prefixes we want to be used:
    @prefixes: -webkit-, -moz-, -ms-, -o-, ~'';
    
    // here we specialize what values are to be prefixed:
    @prefvendor: ~'(transform|filter|box-shadow)'; // etc...
    
    // and now the mixin that can apply all of above specializations:
    .vendorize(@property, @values) {
        .-1();
        .-1(@i: length(@prefixes)) when (@i > 0) {
            .-1(@i - 1);
            @pref: extract(@prefixes, @i);
            @{pref}@{property}+: replace(~'@{values}', '@{prefvendor}', '@{pref}$1', 'gi');
        }
    }
    

    usage:

    element1{
        .vendorize(transition; opacity 1s ease-out, transform 3s ease-in);
    }
    

    output:

    element1 {
      -webkit-transition: opacity 1s ease-out, -webkit-transform 3s ease-in;
      -moz-transition: opacity 1s ease-out, -moz-transform 3s ease-in;
      -ms-transition: opacity 1s ease-out, -ms-transform 3s ease-in;
      -o-transition: opacity 1s ease-out, -o-transform 3s ease-in;
      transition: opacity 1s ease-out, transform 3s ease-in;
    }
    

    Tested on LessCSS 1.7.0.1

    0 讨论(0)
提交回复
热议问题