将CSS通过mixin作为另一个mixin的参数

有没有办法将一个mixin或style的声明传递给另一个mixin作为输入参数?

让我们来看一下动画关键帧的例子.以下是我们如何在纯CSS中定义关键帧:

@-moz-keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

@-webkit-keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

@keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

想法是使用mixins来简化这些声明,所以我们可以有如下的内容:

.keyframes(name, from, to)
{
    // here we need somehow to reproduce structure
    // that we have in an example above
}

// define one animation
.my-from() { color: red; }
.my-to() { color: blue; }
// the following won't work because you cannot pass mixin as a parameter
// in way I have here, so I am looking for a way to solve this problem
.keyframes('some-name', .my-from, .my-to);

// define another animation
.another-from() { font-size: 1em; }
.another-to() { font-size: 2em; }
.keyframes('another-name', .another-from, .another-to);

系统将具有可以动态附加到应用程序以及删除的不同模块.所以,不要建议我使用@import,因为不是这样.输出CSS使用关于模块和他们自己的LESS样式的信息以及基本的LESS依赖关系(如mixins库等)动态编译.

注意:如果您知道通过类定义而不是mixin,它将适用于我.在上面的例子中,它将是.my-from而不是.my-from()等等.

更新为1.7.0(更简单)

现在我们可以更直接地使用1.7.0更新和create rulesets的能力,并使用variables in setting @keyframes.

现在我们真的可以通过规则集的参数传递一个mixin,或者我们可以传递属性自己.所以考虑一下:

LESS(使用1.7)

.keyframes(@name, @from, @to) {
    @frames: {
        from { @from(); }
        to { @to(); }
    };
    @pre: -moz-keyframes;
    @-moz-keyframes @name
    {
       @frames();
    }

    @-webkit-keyframes @name
    {
       @frames();
    }

    @keyframes @name
    {
       @frames();
    }
}

.keyframes(testName, {color: red; .myMix(0);}, {color: blue; .myMix(1);});

.myMix(@value) {opacity: @value;}

请注意,我传递了一个属性设置和一个混合调用,我的输出是:

CSS输出

@-moz-keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}
@-webkit-keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}
@keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}

注意在{…}括号中如何传递规则集,然后通过@from()和@to()调用(看起来很像一个mixin调用).我正在使用这些传递的规则集来设置另一个@frames的规则集,然后自己调用它来填充关键帧定义.

更一般

在这里我将一个私人混音传递给另一个混音,然后从另一个混音中调用它:

.someMixin(@class; @expectedMixin) {
    .@{class} {
      @expectedMixin();
      .myPrivateMix(0.6);
      test: 1;
    }
}

.someMixin(newClass; {.myClass;});

.myClass {
  .myPrivateMix(@value) {opacity: @value;}
}

CSS输出

.newClass {
  opacity: 0.6;
  test: 1;
}

保留下面的遗留信息.

更新(添加了LESS 1.4.0支持)

哇,这做了一些事情,但我想我有一些你可以合作的东西.但是,它确实需要您的模块中的一些特殊的定义,特别是使用pattern matching.所以…

首先,定义你的模块Mixins

请注意,要在特定将来的mixin中使用的模块组合是如何使用相同的混合名称定义的,但使用不同的模式名称.这是做这项工作的关键.

// define one animation in a module
.from(my-from){ color: red; }
.to(my-to) { color: blue; }

// define one animation in another module
.from(another-from){ font-size: 1em; }
.to(another-to) { font-size: 2em; }

如果您还想在模块中使用单个mixin名称,那么您应该可以这样做:

// define one animation in a module
.my-from(){ color: red; }
.my-to() { color: blue; }

.from(my-from){ .my-from() }
.to(my-to) { .my-to() }   

// define one animation in another module
.another-from(){ font-size: 1em; }
.another-to() { font-size: 2em; }

.from(another-from){ .another-from() }
.to(another-to) { .another-to() }

这应该允许调用直接的mixin .my-from()或使其在稍后的混合中可变地访问,通过模式匹配访问单个.from()mixin组.

接下来,定义你的Mixin

对于您的@keyframes示例,这是非常困难的.事实上,a stack overflow answer对于帮助我解决应用@name的问题至关重要,因为@name的定义不符合正常的LESS规则.应用@name的解决方案看起来很讨厌,但它的工作原理.它确实有可能也定义一个选择器字符串以播放动画(因为它使用该字符串来帮助构建最后一个关键帧)的不幸的必要性.这个命名限制只适用于以@ like @keyframes和@media开头的css字符串.

另外,由于我们在模块文件中使用了一个标准的混合名称,所以我们可以在新的mixin中一致地访问,同时通过一个变量来通过模式匹配来选择该混合的正确变体.所以我们得到:

低于1.3.3或以下

// define mixin in mixin file

.keyframes(@selector, @name, @from, @to) {
    @newline: `"\n"`; // Newline
    .setVendor(@pre, @post, @vendor) {
        (~"@{pre}@@{vendor}keyframes @{name} {@{newline}from") {
            .from(@from); 
        }    
        to  { 
            .to(@to);
        }
       .Local(){}
       .Local() when (@post=1) {
           (~"}@{newline}@{selector}") {
              -moz-animation: @name;
              -webkit-animation: @name;
              -o-animation: @name;
              -ms-animation: @name;
              animation: @name;
           } 
       }    
       .Local;
    } 
    .setVendor(""            , 0,    "-moz-");
    .setVendor(~"}@{newline}", 0, "-webkit-");
    .setVendor(~"}@{newline}", 0,      "-o-");
    .setVendor(~"}@{newline}", 0,     "-ms-");
    .setVendor(~"}@{newline}", 1,         "");
}

LESS 1.4.0

.keyframes(@selector, @name, @from, @to) {
    @newline: `"\n"`; // Newline
    .setVendor(@pre, @post, @vendor) {
        @frames: ~"@{pre}@@{vendor}keyframes @{name} {@{newline}from";
        @{frames} {
            .from(@from); 
        }    
        to  { 
            .to(@to);
        }
       .Local(){}
       .Local() when (@post=1) {
           @animationSector: ~"}@{newline}@{selector}";
           @{animationSector} {
              -moz-animation: @name;
              -webkit-animation: @name;
              -o-animation: @name;
              -ms-animation: @name;
              animation: @name;
           } 
       }    
       .Local;
    } 
    .setVendor(""            , 0,    "-moz-");
    .setVendor(~"}@{newline}", 0, "-webkit-");
    .setVendor(~"}@{newline}", 0,      "-o-");
    .setVendor(~"}@{newline}", 0,     "-ms-");
    .setVendor(~"}@{newline}", 1,         "");
}

现在打电话给你的Mixin

你可以给它自己的名字,只是传递模式mixins上的模式匹配的直线模式(都不是点[.],没有引号),但不要忘记你还需要一个选择符字符串引用)来让mixin正常工作:

.keyframes('.changeColor', some-name, my-from, my-to);
.keyframes('.changeFontSize', another-name, another-from, another-to);

哪些给你所需的输出

@-moz-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-webkit-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-o-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-ms-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
.changeColor {
  -moz-animation: some-name;
  -webkit-animation: some-name;
  -o-animation: some-name;
  -ms-animation: some-name;
  animation: some-name;
}
@-moz-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-webkit-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-o-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-ms-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
.changeFontSize {
  -moz-animation: another-name
  -webkit-animation: another-name;
  -o-animation: another-name;
  -ms-animation: another-name;
  animation: another-name;
}
翻译自:https://stackoverflow.com/questions/11551313/less-css-pass-mixin-as-a-parameter-to-another-mixin

转载注明原文:将CSS通过mixin作为另一个mixin的参数