LESS variables "lazy load",这意味着它们在代码中出现的顺序无关紧要,通常是“最后”调用获胜。在您的情况下,我发现奇怪的是,我本以为它们都是20em,因为这是该值的“最后”设置。但是,我从发布this "issue" 中了解到,这特别是因为它被mixin 调用,它是唯一设置的第一个值。由于延迟加载,它会影响调用变量的整个作用域,并且因为无论调用多少次,mixin 都只会设置一次值,你最终会得到看起来像“奇怪”的行为。
你至少有四种方法可以处理你的情况,它们会输出你想要的。
(1) 在 Mixin 中设置属性
.test(@target;@context;@prop) {
@{prop}: (@target / @context) * 1em;
}
.custom-field {
position: relative;
.test(30;16;padding-bottom);
.test(30;16;margin-bottom);
.test(320;16;max-width);
}
(2) 设置全局Javascript函数
仔细注意它是如何构建/使用的。在您对 SASS 发表评论后,我从 this thread 那里得到了这个想法。可以通过这种方式设置各种功能。
@setEm: `setEm = function(target,context) { return ((target/context)+'em'); }`;
.custom-field {
position: relative;
padding-bottom: ~`setEm(30,16)`;
margin-bottom: ~`setEm(30,16)`;
max-width: ~`setEm(320,16)`;
}
(3) 使用模式匹配的非 Javascript 解决方案
仔细注意它是如何构造/使用的。这更“冗长”,但确实避免了对 javascript 环境的调用(如果需要,或者他们有时会删除内联 javascript 功能 [which has been discussed during various issues on the site]) 并提供了一些很好的灵活性。也可以使用它来设置各种功能(如图所示)。
/*make a global setter for local variable getter (this will get up to six
/*values from the same caller function to avoid variable overlap; should you
/*need more within a single scope block, just expand this).
*/
.setGetInstance(@num) {
.-(@num);
.-(1) { @getVar1: @setVar;}
.-(2) { @getVar2: @setVar;}
.-(3) { @getVar3: @setVar;}
.-(4) { @getVar4: @setVar;}
.-(5) { @getVar5: @setVar;}
.-(6) { @getVar6: @setVar;}
}
/*Create various "function" mixins that use the global setter */
.setEm(@target;@context;@num) {
@setVar: ((@target / @context) * 1em);
.setGetInstance(@num);
}
.-100(@target;@num) {
@setVar: (@target - 100px);
.setGetInstance(@num);
}
/*Use the function mixins (up to six per block in this example) */
.custom-field1 {
position: relative;
.setEm(30;16;1;);
padding-bottom: @getVar1;
.setEm(30;16;2);
margin-bottom: @getVar2;
.setEm(320;16;3);
max-width: @getVar3;
}
.custom-field2 {
.setEm(20;10;1;);
padding-bottom: @getVar1;
.setEm(10;10;2);
margin-bottom: @getVar2;
.minus100(1000;3);
max-width: @getVar3;
}
CSS 输出
.custom-field1 {
position: relative;
padding-bottom: 1.875em;
margin-bottom: 1.875em;
max-width: 20em;
}
.custom-field2 {
padding-bottom: 2em;
margin-bottom: 1em;
max-width: 900px;
}
(4) 使用嵌套块或 Mixins
我从this comment 学到了另一种方法,它也以不同的方式解决了这个问题。
.setEm(@target;@context) {
@em: ((@target / @context) * 1em);
}
.custom-field {
position: relative;
& {padding-bottom: @em; .setEm(30;16);}
& {margin-bottom: @em; .setEm(30;16);}
& {max-width: @em; .setEm(320;16);}
}
但是,这将在 1.6.2 之前的任何版本的 LESS 中产生多个选择器块,就像这样(1.6.2+ 将它们全部合并,请参阅 7-phases-max 的评论):
.custom-field {
position: relative;
}
.custom-field {
padding-bottom: 1.875em;
}
.custom-field {
margin-bottom: 1.875em;
}
.custom-field {
max-width: 20em;
}
因此,如果使用早期版本,最好将其保留为本地 mixin:
.custom-field {
position: relative;
.-() {padding-bottom: @em; .setEm(30;16);}
.-() {margin-bottom: @em; .setEm(30;16);}
.-() {max-width: @em; .setEm(320;16);}
.-()
}
将所有内容分组:
.custom-field {
position: relative;
padding-bottom: 1.875em;
margin-bottom: 1.875em;
max-width: 20em;
}