关于 Sass 3.4 你应该知道的一些事情
Sass 3.4 并不是离开 Sass 3.3 的一个开创性版本,并没有做过多的改变,但有一些小变化还是需要留意的。这些功能在Sass3.3测试版本就有显露出一些,但后面会得到更好的细化。我们来看看这些东西,这些东西对于Sass爱好者还是非常值得期待的。
在 Sass 3.4 中最终可以使用 &
来访问父选择器:
ul {
li {
background: blue;
&:hover {
background: red;
}
}
}
熟悉Sass的同学肯定知道上面的代码块在做什么。列表项设置了蓝色背景色,鼠标悬浮在列表项时,背景色变成红色。实现这个的就是通过&
字符来完成。直接在li
标签里嵌套,来替代写一个li:hover
。其中&
代表的就是 ul li
,所以生成的代码就是 ul li:hover
。
虽然&
可以表示选择器字符串,但现在无法对这个字符串进行编辑。也不可能将&
设置成一个变量,或者通过nth()
和join()
字符串函数来编辑&
。在Sass3.4中对这方面做了变化,可以对&
进行编辑,定义变量,以及其他有用的功能。接下来一起探讨这方面的一些例子。
nav{
ul {
li {
$selector: &;
foo: $selector; // nav ul li
bar: length($selector); // 1
}
}
}
第一件事情,你会注意到在 3.4 中可以设置 $selector:&
,不会发生任何问题。可以不需要将 &
设置成一个变量,就可以直接对它执行列表相关函数操作。
下一步,可以对它执行一系列的基本的列表函数操作。可以看到,&
打印出来的是 nav ul li
。执行 length($selector)
你可能期望输出的值是 3,而不是 1,这一点让非常的头痛,直到你意识到它是列表的列表时就不再会头痛了。让我们来看看下面的例子,这将会更清晰。
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
。
选择器函数
快速看一个示例:
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...)
函数。
#{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...)
函数。
#{selector-append(".foo .bar", ":hover")} {
background: pink;
}
//相当于
.foo .bar{
&:hover {
background: red;
}
}
// 输出相同的CSS
.foo .bar:hover {
background: red;
}
可以看出这两个函数可以轻松的帮助我们实现选择器嵌套和追加。所以,当我们不能做什么“新”事情的时候,我们可以修改选择器,让他变得更为方便而不易出错。
真正变化在哪
虽然它擅长本地上下文(&:hover
)和全局上下文(.lt-ie9 &
)选择器操作,但他还是没办法为组件级上下文进行操作,这也是让人最讨厌之处。这是什么意思呢?接下来通过一个简单的示例来做阐述。
.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中终于对这部分做了修复。
.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
来完成。
@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)
函数可以帮助你拆解更复杂的选择器。可以通过这里了解这些函数的具体功能。
总结
虽然这些变化比不上maps
、 sourcempas
和@at-root
,但Sass3.4还是带了一些很久前就希望有的功能。就我个人而言,我一直希望有这样的函数让我更好的控制上下文选择器,因为我自己在这方面吃了很多的亏。如果你想看一些实实在在的示例,可以看看 @SassBites 的 视频,这个教程介绍了关于selector-replace()
函数的使用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论