选择器使用Sass变量?

本文由大漠根据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)
  }
}

在第一个示例中存在两个问题:

  1. 我要两次声明a:hover样式,这不是理想中的效果
  2. 实际上重写的“a:hover”样式会覆盖“a:active”样式,这样是不正确的

在第二个示例中,我不得不放弃变量选择器的样式,重新手写样式。这并没有错,因为我不得不这样做。但是问题就出来了,在这里不能重复使用变量,那么变量在此就没什么用处。

总结

给变量存储一个字符串文本或一个值是非常有用的。然而给选择器使用变量想法,起初是一个好的想法,但事实上我已举例说明了他们会存在一些严重的问题。

无论如何,你觉得我的例子有没有用,但实际中,Sass中的变量是一个很强的功能,可以好好的利用起来。只要确认你使用变量是明智的,而且是对你工作有帮助的。

译者手语:整个翻译依照原文线路进行,并在翻译过程略加了个人对技术的理解。如果翻译有不对之处,还烦请同行朋友指点。谢谢!

出处:

英文出处:http://www.scottohara.me/article/sass-selector-variables.html

中文译文:http://www.w3cplus.com/preprocessor/sass-selector-variables.html