我将LESS引入大型Web应用程序项目以简化我的CSS。我有一些CSS规则将转换应用于不同数量的属性,例如:
.movable {
transition-property: top, left;
transition-duration: 0.2s;
transition-timing-function: ease;
}
.fadeAndStretchable {
transition-property: opacity, width, height, margin;
transition-duration: 1.5s;
transition-timing-function: ease-out;
}
(注意:为简洁起见,我在此处省略了-webkit
,-moz
和-o
属性:实际上,这些规则中的每一条都是12行而不是3行。)
请注意transition-property
的值以逗号分隔。这在CSS中很常见:多个值通常以空格分隔(如border: 1px solid #f00
中所示)。较少的mixins可以使用特殊@arguments
值来produce a space-separated list of all the mixin arguments - 但是可以定义一个LESS mixin,它接受可变数量的参数并将它们转换为逗号分隔值列表,适合{{ 1}}?
如果有必要,我很满意需要两个mixin的解决方案:一个用于transition-property
,另一个用于transition-property
和transition-duration
。这是我到目前为止所尝试的内容:
transition-timing-function
结果:LESS错误(“找不到'.transition-property(顶部,左侧)'的匹配定义”)
.transition-property() {
-webkit-transition-property: @arguments;
-moz-transition-property: @arguments;
-o-transition-property: @arguments;
transition-property: @arguments;
}
.movable {
.transition-property(top, left);
}
结果:LESS错误(“找不到'.transition-property(顶部,左侧)'的匹配定义”)
.transition-property(@p1, @p2, @p3, @p4, @p5) {
-webkit-transition-property: @arguments;
-moz-transition-property: @arguments;
-o-transition-property: @arguments;
transition-property: @arguments;
}
.movable {
.transition-property(top, left);
}
结果:没有LESS错误,但它会生成一个CSS规则.transition-property(@p1:p1, @p2:p2, @p3:p3, @p4:p4, @p5:p5) {
-webkit-transition-property: @p1, @p2, @p3, @p4, @p5;
-moz-transition-property: @p1, @p2, @p3, @p4, @p5;
-o-transition-property: @p1, @p2, @p3, @p4, @p5;
transition-property: @p1, @p2, @p3, @p4, @p5;
}
.movable {
.transition-property(top, left);
}
,由于无法识别的属性,浏览器会忽略该规则。
我尝试过各种其他方法(例如将属性作为字符串-webkit-transition-property: top, left, p3, p4, p5
传递)但所有结果都是相同的:LESS错误或CSS无效。
有什么方法围绕这个吗?或者我必须咬紧牙关并定义一组在arity上重载的mixin,例如
'top,left'
答案 0 :(得分:29)
由于Luke Page指向了...
语法,我设法弄明白了。
解决方案是使用以下内容:
...
允许变量参数~
前缀escape生成的表达式(即停止将其封闭在字符串中)呼。这是得到的mixin:
.transition-properties(...) {
-webkit-transition-property: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
}
这是完整版,其中包含一整套浏览器扩展程序:
.transition-properties(...) {
@props: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
-webkit-transition-property: @props;
-moz-transition-property: @props;
-o-transition-property: @props;
transition-property: @props;
}
答案 1 :(得分:20)
也许我误解了你的需求。为什么不能使用转义字符串?
像这样:
.transition ( @property, @duration, @style: ease-in-out ) {
-webkit-transition-property: @property;
-webkit-transition-duration: @duration;
-webkit-transition-timing-function: @style;
-moz-transition-property: @property;
-moz-transition-duration: @duration;
-moz-transition-timing-function: @style;
-ms-transition-property: @property;
-ms-transition-duration: @duration;
-ms-transition-timing-function: @style;
-o-transition-property: @property;
-o-transition-duration: @duration;
-o-transition-timing-function: @style;
transition-property: @property;
transition-duration: @duration;
transition-timing-function: @style;
}
#my-id {
.transition( ~"background, border-color, color", 2s );
}
这正是我们用于多属性转换的内容。没问题。
答案 2 :(得分:6)
此解决方案不使用任何内联JavaScript,它允许:
如果属性的数量大于持续时间,延迟或时间的数量,那么如果设置了compact
输出,则持续时间/延迟/时间的最终值将成为所有参数的值超出传递数量的其他属性,但如果compact
不 设置,则输出长格式并values are duplicated per browsers interpret ion of the css standards。
LESS Mixin
.transition (@props: all;
@duration:1s;
@delay: 0s;
@timing: ease;
@compact: true;
@raw-input: false) {
.output() when (@raw-input = false) and not (@compact = true) {
-webkit-transition-property:@props;
-moz-transition-property:@props;
-ms-transition-property:@props;
-o-transition-property:@props;
transition-property:@props;
-webkit-transition-duration:@duration;
-moz-transition-duration:@duration;
-ms-transition-duration:@duration;
-o-transition-duration:@duration;
transition-duration:@duration;
-webkit-transition-delay: @delay;
-moz-transition-delay: @delay;
-ms-transition-delay: @delay;
-o-transition-delay: @delay;
transition-delay: @delay;
-webkit-transition-timing-function:@timing;
-moz-transition-timing-function:@timing;
-ms-transition-timing-function:@timing;
-o-transition-timing-function:@timing;
transition-timing-function:@timing;
}
.output() when (@raw-input = false) and (@compact = true) {
@propsLength: length(@props);
@durationLength: length(@duration);
@delayLength: length(@delay);
@timingLength: length(@timing);
.buildString(@i, @s: ~'') when (@i <= @propsLength) {
@prop: extract(@props, @i);
.setDuration() when (@i <= @durationLength) {
@dur: extract(@duration, @i);
}
.setDuration() when (@i > @durationLength) {
@dur: extract(@duration, @durationLength);
}
.setDuration();
.setDelay() when (@i <= @delayLength) {
@del: extract(@delay, @i);
}
.setDelay() when (@i > @delayLength) {
@del: extract(@delay, @delayLength);
}
.setDelay();
.setTiming() when (@i <= @timingLength) {
@time: extract(@timing, @i);
}
.setTiming() when (@i > @timingLength) {
@time: extract(@timing, @timingLength);
}
.setTiming();
.setDivider() when (@i > 1) {
@divider: ~'@{s},';
}
.setDivider() when (@i = 1) {
@divider: ~'';
}
.setDivider();
@string: @divider @prop @dur @del @time;
.buildString((@i + 1), @string);
}
.buildString(1);
.buildString(@i, @s: ~'') when (@i > @propsLength) {
.compact(@s);
}
}
.output() when not (@raw-input = false) {
.compact(@raw-input);
}
.compact(@string) {
-webkit-transition:@string;
-moz-transition:@string;
-ms-transition:@string;
-o-transition:@string;
transition:@string;
}
.output();
}
少用例
.test {
.transition();
}
.test-props {
.transition(width);
}
.test-duration {
.transition(@duration: 3s);
}
.test-delay {
.transition(@delay: 10s);
}
.test-timing {
.transition(@timing: linear);
}
.test-all {
.transition(height, 4s, 12s, ease-out);
}
.test-multitransitions {
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
}
.test-not-compact {
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease; false);
}
.test-raw-input {
.transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
}
在上面的示例中,特别注意两件事:(1)如何使用逗号分隔列表来传递多个值,而使用分号来分隔参数组。所以要想象,就是这样:
.transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
|---Properties----|-Dur.--|---Delay---|---------Timing--------|
| | |
semicolons divide groups of parameters
(2)raw-input
示例如何需要一个结尾分号才能将逗号视为列表项:
.transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
|
semicolon here needed
示例的CSS输出
.test {
-webkit-transition: all 1s 0s ease;
-moz-transition: all 1s 0s ease;
-ms-transition: all 1s 0s ease;
-o-transition: all 1s 0s ease;
transition: all 1s 0s ease;
}
.test-props {
-webkit-transition: width 1s 0s ease;
-moz-transition: width 1s 0s ease;
-ms-transition: width 1s 0s ease;
-o-transition: width 1s 0s ease;
transition: width 1s 0s ease;
}
.test-duration {
-webkit-transition: all 3s 0s ease;
-moz-transition: all 3s 0s ease;
-ms-transition: all 3s 0s ease;
-o-transition: all 3s 0s ease;
transition: all 3s 0s ease;
}
.test-delay {
-webkit-transition: all 1s 10s ease;
-moz-transition: all 1s 10s ease;
-ms-transition: all 1s 10s ease;
-o-transition: all 1s 10s ease;
transition: all 1s 10s ease;
}
.test-timing {
-webkit-transition: all 1s 0s linear;
-moz-transition: all 1s 0s linear;
-ms-transition: all 1s 0s linear;
-o-transition: all 1s 0s linear;
transition: all 1s 0s linear;
}
.test-all {
-webkit-transition: height 4s 12s ease-out;
-moz-transition: height 4s 12s ease-out;
-ms-transition: height 4s 12s ease-out;
-o-transition: height 4s 12s ease-out;
transition: height 4s 12s ease-out;
}
.test-multitransitions {
-webkit-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-moz-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-ms-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
-o-transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
transition: width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
}
.test-not-compact {
-webkit-transition-property: width, height, top;
-moz-transition-property: width, height, top;
-ms-transition-property: width, height, top;
-o-transition-property: width, height, top;
transition-property: width, height, top;
-webkit-transition-duration: 1s, 2s;
-moz-transition-duration: 1s, 2s;
-ms-transition-duration: 1s, 2s;
-o-transition-duration: 1s, 2s;
transition-duration: 1s, 2s;
-webkit-transition-delay: 0s, 1s, 3s;
-moz-transition-delay: 0s, 1s, 3s;
-ms-transition-delay: 0s, 1s, 3s;
-o-transition-delay: 0s, 1s, 3s;
transition-delay: 0s, 1s, 3s;
-webkit-transition-timing-function: ease-in, ease-out, ease;
-moz-transition-timing-function: ease-in, ease-out, ease;
-ms-transition-timing-function: ease-in, ease-out, ease;
-o-transition-timing-function: ease-in, ease-out, ease;
transition-timing-function: ease-in, ease-out, ease;
}
.test-raw-input {
-webkit-transition: top 1s, bottom 1s, color 3s 1s linear;
-moz-transition: top 1s, bottom 1s, color 3s 1s linear;
-ms-transition: top 1s, bottom 1s, color 3s 1s linear;
-o-transition: top 1s, bottom 1s, color 3s 1s linear;
transition: top 1s, bottom 1s, color 3s 1s linear;
}
如果永远不需要长篇那么mixin代码可以减少到:
.transition (@props: all;
@duration:1s;
@delay: 0s;
@timing: ease;
@raw-input: false) {
.output() when (@raw-input = false) {
@propsLength: length(@props);
@durationLength: length(@duration);
@delayLength: length(@delay);
@timingLength: length(@timing);
.buildString(@i, @s: ~'') when (@i <= @propsLength) {
@prop: extract(@props, @i);
.setDuration() when (@i <= @durationLength) {
@dur: extract(@duration, @i);
}
.setDuration() when (@i > @durationLength) {
@dur: extract(@duration, @durationLength);
}
.setDuration();
.setDelay() when (@i <= @delayLength) {
@del: extract(@delay, @i);
}
.setDelay() when (@i > @delayLength) {
@del: extract(@delay, @delayLength);
}
.setDelay();
.setTiming() when (@i <= @timingLength) {
@time: extract(@timing, @i);
}
.setTiming() when (@i > @timingLength) {
@time: extract(@timing, @timingLength);
}
.setTiming();
.setDivider() when (@i > 1) {
@divider: ~'@{s},';
}
.setDivider() when (@i = 1) {
@divider: ~'';
}
.setDivider();
@string: @divider @prop @dur @del @time;
.buildString((@i + 1), @string);
}
.buildString(1);
.buildString(@i, @s: ~'') when (@i > @propsLength) {
.compact(@s);
}
}
.output() when not (@raw-input = false) {
.compact(@raw-input);
}
.compact(@string) {
-webkit-transition:@string;
-moz-transition:@string;
-ms-transition:@string;
-o-transition:@string;
transition:@string;
}
.output();
}
答案 3 :(得分:5)
从less.js 1.3开始,您必须在参数列表中指定...以表示可以添加更多参数。 e.g。
.transition-property(...) {
foo: @arguments;
}