让我们来看一下动画关键帧的例子.以下是我们如何在纯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更新和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; }
保留下面的遗留信息.
哇,这做了一些事情,但我想我有一些你可以合作的东西.但是,它确实需要您的模块中的一些特殊的定义,特别是使用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,@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("","-moz-"); .setVendor(~"}@{newline}","-webkit-"); .setVendor(~"}@{newline}","-o-"); .setVendor(~"}@{newline}","-ms-"); .setVendor(~"}@{newline}",1,""); }
LESS 1.4.0
.keyframes(@selector,@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("",""); }
现在打电话给你的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; }