LESS CSS 将 mixin 作为参数传递给另一个 mixin [英] LESS CSS Pass mixin as a parameter to another mixin

查看:34
本文介绍了LESS CSS 将 mixin 作为参数传递给另一个 mixin的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there any way to pass one mixin or style's declaration to another mixin as an input parameter?

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

Let's take a look at an example with animation keyframes. Following is how we define keyframes in pure 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; }
}

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

Idea is to simplify these declarations using mixins, so we can have something like following:

.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 库等)动态编译.

The system will have different modules that could be dynamically attached to application as well as removed. So, don't suggest me to use @import because it's not the case. Output CSS is dynamically compiled on-fly using information about modules and their own LESS styles as well as base LESS dependencies like mixins library and etc.

注意:如果您知道一种传递类定义而不是 mixin 的方法,它将对我有用.在上面的示例中,它将是 .my-from 而不是 .my-from() 等等.

Note: it will work for me if you know a way to pass class definition instead of mixin. In an example above it would be .my-from instead of .my-from() and etc.

推荐答案

UPDATED for LESS 1.7.0+ (WAY Simpler)

我们现在可以通过 1.7.0 更新和的能力更直接地做到这一点创建规则集,并在设置中使用变量<代码>@keyframes.

UPDATED for LESS 1.7.0+ (WAY Simpler)

We can do this far more directly now with the 1.7.0 update and the ability to create rulesets, and to use variables in setting @keyframes.

现在我们真的可以通过规则集通过参数传递混合,或者我们可以传递属性串本身.所以考虑一下:

Now we really can pass a mixin through a parameter by a ruleset, or we can pass in the property stings themselves. So consider this:

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;}

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

Note that I am passing both a property setting and a mixin call, and my output is:

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 的另一个规则集,然后它本身被调用来填充关键帧定义.

Note how the rulesets are passed, in brackets {...}, and then called, via @from() and @to() (looking a lot like a mixin call). I'm using these passed rule sets to set another ruleset of @frames which is then itself called to fill the keyframes definitions.

更通用

这里我将一个私有 mixin 传递给另一个 mixin,然后从另一个 mixin 调用它:

Here I pass a private mixin to another mixin and then call it from that other mixin:

.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;
}

<小时>

保留以下旧信息.

哇,这花了一些时间,但我想我有一些你可以使用的东西.但是,它确实需要对模块中的 mixin 进行一些特殊定义,特别是使用 模式匹配.所以...

Wow, this took some doing, but I think I have something you can work with. However, it does take some special defining of your mixins in your modules, specifically, using pattern matching. So...

注意在特定的未来 mixin 中打算使用的模块 mixin 是如何使用相同的 mixin name 定义的,但使用不同的模式名称.这是完成这项工作的关键.

Note how the module mixins intended to be used in a specific future mixin are defined with the same mixin name, but with a different pattern name. This was key to making this work.

// 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() 通过模式匹配混合组.

This should allow one to call either the straight mixin .my-from() or, to make it variably accessible within later mixins that access the singular .from() mixin group through the pattern matching.

对于您的 @keyframes 示例,这非常困难.事实上,堆栈溢出答案 对帮助我解决应用 @name 的问题至关重要,因为它遵循 @keyframes 定义,因此在正常的 LESS 规则下不适用.应用 @name 的解决方案看起来很糟糕,但它有效.也许不幸的是,它确实需要定义一个选择器字符串来播放动画(因为它使用该字符串来帮助构建关键帧的最后一个 }).这种命名限制仅适用于以 @ 开头的 css 字符串,例如 @keyframes 和可能的 @media.

For your @keyframes example, that was extremely difficult. In fact, a stack overflow answer was vital to helping me solve an issue with applying the @name, which was not applying under normal LESS rules because of it following the @keyframes definition. The solution to apply the @name looks nasty, but it works. It does have the, perhaps, unfortunate necessity of also defining a selector string to play the animation by (because it uses that string to help build the last } of the keyframes). This naming limitation would only be true of css strings that begin with @ like @keyframes and probably @media.

此外,因为我们在模块文件中使用了标准的 mixin 名称,所以我们可以在新的 mixin 中一致地访问它,同时传入一个变量以选择适当的变体通过模式匹配混合.所以我们得到:

Further, because we have a standard mixin name used in our module files, we can access that consistently within our new mixin, while at the same time passing a variable in to select the proper variation of that mixin through a pattern match. So we get:

低于 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,         "");
}

低于 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

你可以给它自己的名字,然后直接传递模式(都是点[.]和引号)来匹配模块上的模式mixin,但不要忘记您还需要一个选择器字符串(带引号)才能使 mixin 正常工作:

Now Call Your Mixin

You can give it your own name, and just pass the straight pattern (all are no dot [.] and no quotes) for the pattern matches on the module mixins, but don't forget that you also need a selector string (which is quoted) to get the mixin to work right:

.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;
}

这篇关于LESS CSS 将 mixin 作为参数传递给另一个 mixin的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆