sass 引入sass
因此,您会不时与Sass一起玩。 您可以开始享受它了,因为它可以满足您的大多数需求。 但是,您还没有完全了解这件事: 插值 -将值插入其他值。 好吧,您很幸运,因为今天我要阐明这件事。
Interpo ...什么?
插值 (通常称为变量插值或变量替换 )并非Sass独有。 实际上,您可以使用多种语言(PHP,Perl,Ruby,Tcl,Groovy,Unix shell等)找到它。 我们经常谈论对变量进行 插值或对表达式进行插值 。 简而言之,插值是对包含一个或多个变量的表达式或字符串求值的过程,产生的结果是变量被内存中的相应值替换。
嗯
让我们来看一个例子。 如果您具有PHP的一些基本知识,则可能更容易掌握。 假设您要回显包含变量的字符串。 常见的方法是:
$description = "awesome";
echo "Tuts+ is " . $description . "!";
这不是插值。 这是字符串连接 。 基本上,我们将三个字符串串联(链接在一起): "Tuts+ is "
, "awesome"
(称为$description
)和"!"
。 现在,我们可以使用插值而不是字符串连接:
$description = "awesome";
echo "Tuts+ is ${description}!";
变量周围的花括号告诉PHP在字符串中打印变量值。 请注意,它需要双引号才能在PHP中使用(大多数语言都是如此)。
无论如何,这是变量/表达式插值。 在这一点上,究竟是使用串联还是插值取决于您,但是我们只能说插值是字符串串联的语法糖。
那Sass呢?
让我们看一下Sass中变量替换的工作原理。
像PHP中一样,Sass变量名称以美元符号( $
)为前缀。 比较就在这里结束了,因为在插值方面,Sass和PHP的行为有所不同。 这有一个很好的理由:Sass是用Ruby构建的,它使用#{}
进行表达式替换。
在Sass中,您需要执行以下操作:
$description: "awesome";
@warn "Tuts+ is #{$description}!";
请注意,变量名不像PHP中那样减去$
号。 变量被简单地封装在#{}
。 还值得注意的是,您可以插值任何变量类型,而不仅是字符串。 例如:
$answer: 42;
@warn "The Answer to the Ultimate Question of Life, the Universe, and Everything is #{$answer}.";
什么时候应该使用插值?
现在您已经了解了什么是变量插值以及如何在Sass中进行插值,现在该继续实际的用例了。 对于第一个,我们将重复使用@warn
指令的操作,该指令将内容打印到控制台。
弦乐
假设您有一个名为$colors
映射(一个映射是存储键/值对混合的变量),但是您已经厌倦了一次又一次地输入map-get($colors, ...)
,因此,您构建了一个小小的color()
函数来获取映射到传递的任何键的颜色。 让我们一起写基础知识:
// _config.scss
$colors: (
"primary": tomato,
"secondary": hotpink
);
// _function.scss
@function color($key) {
@return map-get($colors, $key);
}
// _component.scss
.el {
background-color: color(primary);
}
这样很好,对吗? 现在,您要警告自己,如果您键入错误或试图从地图中获取未知密钥,则该密钥不存在(顺便说一句,您可能想阅读Sass中错误处理的介绍 )。这是通过color()
函数中的@warn
指令完成的。
@function color($key) {
@if not map-has-key($colors, $key) {
@warn "Key not found.";
}
@return map-get($colors, $key);
}
不错。 现在,如果您想确定未找到哪个密钥怎么办?
@function color($key) {
@if not map-has-key($colors, $key) {
@warn "Key `#{$key}` not found.";
}
@return map-get($colors, $key);
}
动臂,变量插补。 调用color(awesomeness)
将在控制台中抛出以下消息:
找不到键
awesomeness
。
太酷了,但是我们真的不知道上下文是什么。 为了帮助将来自己,我们可以在错误消息中添加地图名称。
@function color($key) {
@if not map-has-key($colors, $key) {
@warn "Key `#{$key}` not found in $colors map.";
}
@return map-get($colors, $key);
}
在这种情况下,由于尚未对$colors
变量进行插值,因此将其打印为字符串。
重点
awesomeness
在$颜色没有找到映射。
CSS功能
到目前为止,我们已经看到了最常见的变量替换情况:在字符串中打印变量的内容。 这是一个很好的例子,但是我想到有一个更好的例子:CSS函数中的变量,例如calc()
。
假设您要根据边栏的宽度调整主容器的大小。 由于您是一个尽职的前端开发人员,因此已将此宽度存储在变量中,因此可以执行以下操作:
$sidebar-width: 250px;
.main {
width: calc(100% - $sidebar-width);
}
然后惊喜! 没用 没有Sass错误,但是您的容器尺寸不正确。 如果您使用DevTools检查其样式,您将看到此内容-划掉了,因为它是无效的:
.main {
width: calc(100% - $sidebar-width);
}
现在让我们考虑一下: calc()
是CSS函数,而不是Sass函数。 这意味着Sass将整个表达式解释为字符串。 你可以试试:
$type-of-expression: type-of(calc(100% - $sidebar-width)); // string
因为它是一个字符串,所以在我们的@warn
字符串中使用$colors
,Sass的行为没有任何不同。 $sidebar-width
被视为常规字符串,因此按原样打印。 但这不是您想要的,对吗? 所以让我们插值吧!
.main {
width: calc(100% - #{$sidebar-width});
}
现在,当Sass编译样式表时,它将用与$sidebar-width
关联的值替换#{$sidebar-width}
,在这种情况下为250px
,从而产生以下有效CSS表达式:
.main {
width: calc(100% - 250px);
}
任务完成! 我们在这里讨论了calc()
,但是url()
, linear-gradient()
, radial-gradient()
, cubic-bezier()
和任何其他CSS原生函数(包括所有伪类)都是一样的。
这是另一个使用CSS函数的示例:
@for $i from 1 through $max {
.el:nth-of-type(#{$i}) {
// ...
}
}
这是您可能遇到的一种情况:将for
循环与:nth-*()
选择器结合使用。 再一次,您需要对变量进行插值,以便将其打印在输出CSS中。
综上所述:Sass将CSS函数视为字符串,因此要求您转义其中使用的任何变量,以便在生成CSS中打印其值。
CSS指令
让我们继续进行另一个有趣的变量插值案例:CSS指令,例如@support
, @page
@support
,最重要的是@media
。
现在,这与Sass如何解析CSS指令(尤其是media指令)有关。 我一直在研究Sass代码,虽然我的Ruby确实不是很好,但是我设法找到了一些有趣的东西 :
def query_expr
interp = interpolation
return interp if interp
return unless tok(/\(/)
res = ['(']
ss
res << sass_script(:parse)
if tok(/:/)
res << ': '
ss
res << sass_script(:parse)
end
res << tok!(/\)/)
ss
res
end
基本上,这里的第一行告诉Sass如果存在插值表达式,或者返回错误,除非找到一个左括号( (
),否则应该继续分析所有内容),以返回媒体查询。这里:
$value: screen;
@media $value {
// ...
}
毫不奇怪,这失败了:
“ @media”之后CSS无效:预期的媒体查询(例如,打印,屏幕,打印和屏幕)为“ $ value {”
如错误消息所指出,它正在等待媒体查询。 此时,如果变量在@media
字符串之后,则必须进行插值。 例如:
$value: screen;
@media #{$value} {
// ...
}
正如我们之前从Ruby演义推论得出的那样,如果@media
后面紧跟着括号( ()
),那么您就不必再对变量进行插值了,因为Sass会评估这些括号内的任何内容。 例如:
$value: 1336px;
@media (max-width: $value) {
// ...
}
在这种情况下,Sass计算表达式(max-width: $value)
,将其转换为(max-width: 1337px)
产生有效CSS结果,因此无需对变量进行转义。
至于为什么 Sass的维护者会这样设计,我问Nathan Weizenbaum。 这是他的答复:
通常,我们不喜欢在无法使用完整SassScript表达式的地方允许使用原始变量。 媒体查询就是这样一个地方,因为在那里SassScript可能是模棱两可的(尤其是地图)。
— Nathan Weizenbaum(@ nex3) 2014年6月10日
选择器
好的,这是您需要对Sass变量进行插值的用例的最后一个示例:将变量用作选择器或用作选择器的一部分时。 尽管这可能不是日常用例,但做这样的事情并不少见:
$value: custom;
selector-$value {
property: value;
}
不幸的是,这不起作用:
“ selector-”后CSS无效:预期的“ {”为“ $ value {”
这几乎与媒体查询示例的原因相同。 Sass有自己的解析CSS选择器的方式。 如果遇到意外情况(例如未转义的美元符号),则会崩溃。
幸运的是,解决这个问题很简单(并且您现在已经知道解决方案了):对变量进行插值!
$value: custom;
selector-#{$value} {
property: value;
}
最后的想法
最后,Sass内插并不像看起来那样简单。 在某些情况下,您必须对变量进行转义,而在某些情况下则不必。 从那里开始,您有两种处理方式:
- 要么等待错误消息,然后逃脱
- 或者您可以使用常规CSS值(您知道它非常有用)逃逸到任何地方。
无论如何,我希望我能帮助您了解变量插值的工作原理。 如果您要添加任何内容,请务必分享评论。
sass 引入sass