关于Sass3.4你应该知道的一些事情

Sass3.4并不是离开Sass3.3的一个开创性版本,并没有做过多的改变,但有一些小变化还是需要留意的。这些功能在Sass3.3测试版本就有显露出一些,但后面会得到更好的细化。我们来看看这些东西,这些东西对于Sass爱好者还是非常值得期待的。

本文由大漠根据Micah Godbolt的《Everything you need to know about Sass 3.4》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.phase2technology.com/blog/everything-you-need-to-know-about-sass-3-4/

——作者:Micah Godbolt

——译者:大漠

Sass3.4并不是离开Sass3.3的一个开创性版本,并没有做过多的改变,但有一些小变化还是需要留意的。这些功能在Sass3.3测试版本就有显露出一些,但后面会得到更好的细化。我们来看看这些东西,这些东西对于Sass爱好者还是非常值得期待的。

在Sass3.4中最终可以使用&来访问父选择器:

1
2
3
4
5
6
7
8
ul {
li {
background: blue;
&:hover {
background: red;
}
}
}

熟悉Sass的同学肯定知道上面的代码块在做什么。列表项设置了蓝色背景色,鼠标悬浮在列表项时,背景色变成红色。实现这个的就是通过&字符来完成。直接在li标签里嵌套,来替代写一个li:hover。其中&代表的就是ul li,所以生成的代码就是ul li:hover

虽然&可以表示选择器字符串,但现在无法对这个字符串进行编辑。也不可能将&设置成一个变量,或者通过nth()join()字符串函数来编辑&。在Sass3.4中对这方面做了变化,可以对&进行编辑,定义变量,以及其他有用的功能。接下来一起探讨这方面的一些例子。

1
2
3
4
5
6
7
8
9
nav{
ul {
li {
$selector: &;
foo: $selector; // nav ul li
bar: length($selector); // 1
}
}
}

第一件事情,你会注意到在3.4中可以设置$selector:&,不会发生任何问题。可以不需要将&设置成一个变量,就可以直接对它执行列表相关函数操作。

下一步,可以对它执行一系列的基本的列表函数操作。可以看到,&打印出来的是nav ul li。执行length($selector)你可能期望输出的值是3,而不是1,这一点让非常的头痛,直到你意识到它是列表的列表时就不再会头痛了。让我们来看看下面的例子,这将会更清晰。

1
2
3
4
5
6
7
8
9
10
11
nav, header .container{
ul {
li {
$selector: &;
foo: $selector; // nav ul li, header .container ul li
bar: length($selector); // 2
baz: length(nth($selector, 2)); // 4
qux: nth(nth($selector, 2), 1); // 'header'
}
}
}

在这里可以看到“foo”是用逗号分隔开两个用空格隔开的列表(相当于$list1:nav ul li$list2:header .container ul li)。这也意味着length($selector)将返回的是2。如果使用nth()函数来选择列表二,并且通过length()函数来计算出列表二的长度是4。甚至可以使用双重nth()函数得到选择器header

##选择器函数

快速看一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
nav{
ul {
li {
$new-selector: append(nth(&, 1), a);
@at-root #{$new-selector} {
color: pink;
}
}
}
}
// Resulting CSS
nav ul li a {
color: pink;
}

上面示例中通过append()函数给nav ul li添加了一个额外的选择器a。得到一个新选择器nav ul li a,它依旧能正常工作,但这样使用让人非常的蛋疼。在Sass3.4中使用函数来做,会变得清爽得多。接下来看几个新增的选择器函数的示例。

第一个是selector-nest($selectors...)函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#{selector-nest(".foo, .bar", ".qux")} {
background-color: red;
}
//相当于
.foo, .bar {
.qux {
background-color: red;
}
}
// 输出相同的CSS
.foo .qux, .bar .qux {
background-color: red;
}

接下来是selector-append($selectors...)函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#{selector-append(".foo .bar", ":hover")} {
background: pink;
}
//相当于
.foo .bar{
&:hover {
background: red;
}
}
// 输出相同的CSS
.foo .bar:hover {
background: red;
}

可以看出这两个函数可以轻松的帮助我们实现选择器嵌套和追加。所以,当我们不能做什么“新”事情的时候,我们可以修改选择器,让他变得更为方便而不易出错。

##真正变化在哪

虽然它擅长本地上下文(&:hover)和全局上下文(.lt-ie9 &)选择器操作,但他还是没办法为组件级上下文进行操作,这也是让人最讨厌之处。这是什么意思呢?接下来通过一个简单的示例来做阐述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.tabs {
.tab {
background: red;
&:hover {
background: white;
.tab-link {
color: red;
}
}
.tab-link {
color: white;
}
}
}

在我的“Sass partials”中,选择器只能是每个单一位置。在这个示例中,你可以看到其失败之处,我写了两次.tab-link。在这里出现这样的问题还不是很大的问题,但随着这部分复用越多,.tab-link重用的次数也就会越多,就会造成难于跟踪。

在Sass3.3中没有比较好的解决方案,我们需要.tabs .tab:hover .tab-link,但不可以在选择器内部插入一个上下文选择器。只能附加或预先准备。在Sass3.4中终于对这部分做了修复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
.tabs {
.tab {
background: red;
&:hover {
background: white;
}
.tab-link {
color: white;
@at-root #{selector-replace(&, '.tab', '.tab:hover')} {
color: red;
}
}
}
}

selector-replace($selector, $original, $replacement)函数是一个强大函数,他将多个列表函数功能集成在一起。首先他将复合选择器分成单个选择器。然后匹配到你传递的选择器$original(示例中的.tab),接下来使用$replacement选择器替代(示例中的.tab:hover)。

当时我在想使用什么方法来操纵&时,我只想到了手工操作方法。所以我非常感激有这么一个强大的函数功能。

但是这个功能,如果你每天编写代码都要用到,就显得有点笨重。需要不断重写@at-root,并且将&参数传给他,这样显得有点不必要。是否可以将这个函数功能通过定义一个mixins来完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@mixin context($old-context, $new-context) {
@at-root #{selector-replace(&, $old-context, $new-context)} {
@content;
}
}
.tabs {
.tab {
background: red;
&:hover {
background: white;
}
.tab-link {
color: white;
@include context('.tab', '.tab:hover') {
color: red;
}
}
}
}
// Output
.tabs .tab {
background: red;
}
.tabs .tab:hover {
background: white;
}
.tabs .tab .tab-link {
color: white;
}
.tabs .tab:hover .tab-link {
color: red;
}

这样变得更干净、更易阅读。

Sass3.4还包括了selector-extend($selector, $extendee, $extender)函数,他的行为除了类似于selector-replace()之外,它返回的是一串用来替换原始选择器的选择器列表。可以在框架中使用这个函数,让你尽量的少写Sass代码。

最后selector-unify($selector1, $selector2)superselector($super, $sub)函数可以执行一些更强大的功能以及simple-selectors($selector)函数可以帮助你拆解更复杂的选择器。可以通过这里了解这些函数的具体功能。

##总结

虽然这些变化比不上mapssourcempas@at-root,但Sass3.4还是带了一些很久前就希望有的功能。就我个人而言,我一直希望有这样的函数让我更好的控制上下文选择器,因为我自己在这方面吃了很多的亏。如果你想看一些实实在在的示例,可以看看@SassBites视频,这个教程介绍了关于selector-replace()函数的使用。

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

如需转载,烦请注明出处:

英文原文:http://www.phase2technology.com/blog/everything-you-need-to-know-about-sass-3-4/

中文译文:http://www.w3cplus.com/preprocessor/everything-you-need-to-know-about-sass-3-4.html