本文由大漠根据Scottohara的《Selectors as Sass Variables?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明原作者相关信息http://www.scottohara.me/article/sass-selector-variables.html。
——作者:Scottohara
——译者:大漠
有一个正确和错误的方式来做到这一点...
在Sass中最常见的用法就是给变量指一个值,便于项目的实施和样式的更新。比如很多地方用到颜色color:#f00
,可以使用变量color:$c-red
替代,而且在有红色的阴影地方使用也更方便。
关键是Sass的变量可以很容易的帮助我们改变颜色。可以用字符串值赋值给变量。不管是box-shadow
的值,使用控制命令控制列表的多个值,或者是一个字符串文本。
对于这篇文章,我在想是否可以给变量存储字符串,然后在选择器上使用这些变量的一个想法。这样是一个很好的示例,但也是一个很低级的用例。
让我先说好的一面
Sass变量用于存储文本字符串做为CSS选择器,这里有两个很好的用例。
先来看第一个示例,假设你有一个现成的CSS框架,或者是更好的,在你的项目中你引入了第三方代码。你可能知道你有一系列重叠的类名,可能导致你整理这些代码以及他们之间的权重会让你忙到深夜。
一个非常有用的方法,就是在你的样式表中给重叠的类名加上你自己的前缀,如:
.mycss--btn {
...
}
.mycss--input {
...
}
.mycss--header {
...
}
使用mycss--
(你可以定义一个更好的名字)前缀,可以非常容易帮助你所你的类名与第三方代码重叠的类名区分出来。
要是这样设置,要无缝处理名称的更新,我们只需要使用一个变量来存储这个选择器前缀:
$my-name: mycss--;
.#{$my-name}btn {
...
}
.#{$my-name}input {
...
}
.#{$my-name}header {
...
}
2014年3月8日更新
随着Sass3.3发布,我们现在可以创建一个局部父选择(这个例子中就是前缀mycss
),并且使用&
将其他部分与根选择器嵌套连在一起。
那么上面的示例,我们可以修改成:
.#{$my-name} {
&btn {...}
&input {...}
&header {...}
}
他们编译出来的代码是一样的,但让我们少写了很多代码。
你可以阅读Stuart Robson写的一篇文章《Even Easier BEMing with Sass 3.3》,可以了解更多有关于这种选择器写法。
无论是原来的写法还是新方法,对你来说都是有用的。只不过新方法更强大,如果你在一个单一的文件中所有规则使用这个前缀,可以采用新方法。
如果你想在一个示例中一次性使用一个前缀,或者你觉得这个没有意义,要重新组织你的类名;如果你想在多个文件中都使用同一个前缀,使用原来的方法仍然是有用的。
最后,很可能两种方法结合在一起使用才是理想的解决方案。
第二个示例中使用Sass的列表和指令正确选择变量的局部。
对于这个例子,我想为标题和带类名(某一个类)的HTML元素设置字体。我的意思是就是给HTML元素中的标题,以及创建一个类名,使标题和非标题元素具有相同的样式。
$prefix: txt;
$font-list: (
h1 $prefix 3em 100,
h2 $prefix 2.5em 100,
h3 $prefix 2em 300,
h4 $prefix 1.75em 300,
h5 $prefix 1.5em 400,
h6 $prefix 1.25em 400
);
@each $value in $font-list {
#{nth($value, 1)},
.#{nth($value, 2)}-#{nth($value, 1)} {
font-size: nth($value, 3);
font-weight: nth($value, 4);
}
}
编译出来的CSS:
h1,
.txt-h1 {
font-size: 3em;
font-weight: 100;
}
h2,
.txt-h2 {
font-size: 2.5em;
font-weight: 100;
}
h3,
.txt-h3 {
font-size: 2em;
font-weight: 300;
}
h4,
.txt-h4 {
font-size: 1.75em;
font-weight: 300;
}
h5,
.txt-h5 {
font-size: 1.5em;
font-weight: 400;
}
h6,
.txt-h6 {
font-size: 1.25em;
font-weight: 400;
}
在这里,我创建了一个变量来存储前缀txt
。如果哪一天我可能要更改标题,或者我还没有想到要改成什么,那么我修改一个前缀总比修改六个要来得快。该示例其他部分展示了Sass列表和指令的功能。如果你不了解,可以看看指令相关的文章。
有关于Sass指令和列表相关的文章,可以点击下面的链接进行阅读:
因此这两个示例向你展示了选择器中使用变量好的一面。
你不应该做的...
$a-base: 'a, a:visited';
$a-hovers: 'a:hover, a:active';
#{$a-base} {
color: $c-link;
font-size: 1em;
text-decoration: none;
}
#{$a-hovers} {
color: $c-link-hover;
text-decoratoin: underline;
}
这里的想法是,将选择器的字符串存储在一个变量中。这样看起来你写了较少的代码,还能排序。
我想探讨下,在一些特殊的例子中会存在较大的问题。
首先,除非你知道扩展选择器在Sass中哪个位置,这样也并不能帮你减少代码的编写,因为他仅仅是移动了代码。我们不应该设置的变量与他们的属性有关联。
现在,如果你想用重用这些选择器,并且嵌套在其他一些元素上,那你这样做或许可以派上一点用场:
#{$a-base} {
...
}
#{$a-hovers} {
...
}
.sidebar {
#{$a-base} {
...
}
#{$a-hovers} {
...
}
}
如果能够重复使用这里设置好的变量,是可以帮助我们减少编写的代码。然而,如果你需要改变其中某个选择器时,这样的设置并没有真正的帮到我们。
因为他们只是Sass变量中的某一部分。如果我需要修改.sidebar
中的a:hover
状态,但我又要维持.sidebar
中的a:active
状态不变,那我就需要像下面这样处理:
.sidebar {
#{$a-base} {
...
}
#{$a-hovers} {
...
}
a:hover {
(alternate styling)
}
}
或者
.sidebar {
#{$a-base} {
...
}
a:hover {
(alternate styling)
}
a:active {
(alternate styling)
}
}
在第一个示例中存在两个问题:
- 我要两次声明
a:hover
样式,这不是理想中的效果 - 实际上重写的“
a:hover
”样式会覆盖“a:active
”样式,这样是不正确的
在第二个示例中,我不得不放弃变量选择器的样式,重新手写样式。这并没有错,因为我不得不这样做。但是问题就出来了,在这里不能重复使用变量,那么变量在此就没什么用处。
总结
给变量存储一个字符串文本或一个值是非常有用的。然而给选择器使用变量想法,起初是一个好的想法,但事实上我已举例说明了他们会存在一些严重的问题。
无论如何,你觉得我的例子有没有用,但实际中,Sass中的变量是一个很强的功能,可以好好的利用起来。只要确认你使用变量是明智的,而且是对你工作有帮助的。
译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!
如需转载烦请注明出处:
英文出处:http://www.scottohara.me/article/sass-selector-variables.html
中文译文:http://www.w3cplus.com/preprocessor/sass-selector-variables.html