变量
$base-color: #c6538c;$border-dark: rgba($base-color, 0.88);.alert {border: 1px solid $border-dark;}
⚠️注意
CSS 有自己的变量,它们与 Sass 变量完全不同。差异:
- Sass 变量都被 Sass 编译掉了。CSS 变量包含在 CSS 输出中。
- CSS 变量对于不同的元素可以具有不同的值,但 Sass 变量一次只有一个值。
- Sass 变量是必不可少的,这意味着如果您使用变量然后更改其值,则较早的使用将保持不变。CSS 变量是声明性的,这意味着如果更改该值,它将影响早期使用和以后的使用。
$variable: value 1;.rule-1 {value: $variable;}$variable: value 2;.rule-2 {value: $variable;}
💡有趣的事实
与所有 Sass 标识符一样,Sass 变量将连字符和下划线视为相同。这意味着,$font-size 和 $font_size 既指代相同的变量。这是 Sass 早期的历史遗留,当时它只允许标识符名称中的下划线。一旦 Sass 添加了对连字符的支持以匹配 CSS 的语法,这两者就相当于使迁移更容易。
默认值
通常,当您为变量赋值时,如果该变量已有值,则会覆盖其旧值。
// _library.scss$black: #000 !default;$border-radius: 0.25rem !default;$box-shadow: 0 0.5rem 1rem rgba($black, 0.15) !default;code {border-radius: $border-radius;box-shadow: $box-shadow;}
// style.scss$black: #222;$border-radius: 0.1rem;@import 'library';
作用域
在样式表顶层声明的变量是全局变量。这意味着它们可以在声明之后的任何地方访问,甚至可以在另一个样式表中访问。但对于所有变量而言并非如此,在块中声明的那些(SCSS 中的花括号或 Sass 中的缩进代码)通常是本地的,并且只能在声明它们的块中访问。
$global-variable: global value;.content {$local-variable: local value;global: $global-variable;local: $local-variable;}.sidebar {global: $global-variable;}
如果需要在局部作用域内设置全局变量的值,则可以使用 !global。标记为的变量声明 !global 将改变全局变量。该 !global 标志只能用于设置已在定义的全局变量,不能用于声明新的全局变量。
$variable: first global value;.content {$variable: second global value !global;value: $variable;}.sidebar {value: $variable;}
控制语句的作用域
在 @if 语句中不能声明变量,必须在使用之前定义。
高级变量函数
variable-exists() 当前局部作用域是否有该变量,global-variable-exists() 当前作用域是否有该全局变量。
从变量对象中取出一个键的值使用。
$theme-colors: ("success": #28a745,"info": #17a2b8,"warning": #ffc107,);.alert {background-color: map-get($theme-colors, "warning");}
插值
插值几乎可以在 Sass 样式表中的任何位置使用,以将 SassScript 表达式的结果嵌入到 CSS 中。
使用插值使用变量,color: #{$accent} 而不是写作 color: $accent 。
不要使用数字插值,因为插值返回不带引号的字符串,不能用于任何进一步的数学运算,它避免了 Sass 的内置安全措施,以确保正确使用单位。使用 $width * 1px 而不是 #{$width}px 。
功能
@import
扩展了 CSS 的 @import 规则,能够导入 Sass 和 CSS 样式表,提供对 mixin,函数和变量的访问,并将多个样式表的 CSS 组合在一起。与纯 CSS 导入不同,后者需要浏览器在呈现页面时发出多个 HTTP 请求,因此 Sass 导入在编译期间完全处理。
查找文件
不必明确写出要导入的文件的扩展名; @import "variables" 会自动加载 variables.scss,variables.sass或 variables.css。
⚠️注意
为确保样式表适用于每个操作系统,Sass 按 URL 而不是文件路径导入文件。这意味着即使在 Windows 上,也需要使用正斜杠而不是反斜杠。
加载路径
所有 Sass 实现都允许用户提供加载路径:Sass 在解析导入时将查看的文件系统上的路径。例如,如果您node_modules/susy/sass 作为加载路径传递,则可以使用 @import "susy" 加载 node_modules/susy/sass/susy.scss。
但是,始终会首先相对于当前文件解析导入。仅当不存在与导入匹配的相对文件时,才会使用加载路径,确保在添加新库时不会意外地弄乱相对导入。
💡有趣的事实
与其他一些语言不同,Sass 不要求您使用 ./ 相对导入。相对入口始终可用。
片段
以 _ 开头的 sass 文件不会被编译,而是在导入时编译。
嵌套
可以嵌套在样式规则或简单的 CSS 规则 中,导入的 CSS 嵌套在该上下文中,使得嵌套导入可用于将一大块 CSS 定义到特定元素或媒体查询。请注意,嵌套导入中定义的顶级 mixins,函数和变量仍然是全局定义的。
// _theme.scsspre, code {font-family: 'Source Code Pro', Helvetica, Arial;border-radius: 4px;}
// style.scss.theme-sample {@import "theme";}
💡有趣的事实
嵌套导入对于确定第三方样式表的范围非常有用,但如果您是要导入的样式表的作者,通常最好在 mixin 中编写样式并在嵌套上下文中包含该 mixin。mixin 可以以更灵活的方式使用,并且在查看导入的样式表时如何使用它更清晰。
⚠️注意
嵌套导入中的 CSS 被评估为 mixin 这意味着任何父选择器都将引用样式表嵌套的选择器。
// _theme.scssul li {$padding: 16px;padding-left: $padding;[dir=rtl] & {padding: {left: 0;right: $padding;}}}
// style.scss.theme-sample {@import "theme";}
导入 CSS
除了导入 .sass 和 .scss 文件,Sass 还可以导入普通的旧 .css 文件。唯一的规则是导入不能明确包含 .css 扩展名,因为它用于表示纯CSS @import。
// code.csscode {padding: .25em;line-height: 0;}
// style.scss@import 'code';
Sass 导入的 CSS 文件不允许任何特殊的 Sass 功能。为了确保作者不会在 CSS 中不小心写 Sass ,所有不是有效 CSS 的 Sass 功能都会产生错误。
纯 CSS @import
纯 CSS @import 有以下情况:
- 以 .css 后缀名导入的文件。
- 以
http://或https://的文件。 - 以
url()函数导入。 - 具有媒体查询的文件。
@import "theme.css";@import "http://fonts.googleapis.com/css?family=Droid+Sans";@import url(theme);@import "landscape" screen and (orientation: landscape);
插值
虽然 Sass 导入不能使用插值(以确保始终可以告诉 mixins,函数和变量来自哪里),但纯 CSS 导入可以。这使得可以动态地生成导入,例如基于 mixin 参数。
@mixin google-font($family) {@import url("http://fonts.googleapis.com/css?family=#{$family}");}@include google-font("Droid Sans");
@mixin 和 @include
Mixins 允许您定义可在整个样式表中重复使用的样式。它们可以很容易地避免使用非语义类 .float-left,并在库中分发样式集合。
参数
Mixins 还可以接受参数,这样就可以在每次调用时自定义它们的行为。mixin 必须以 SassScript 表达式的形式包含相同数量的参数。这些表达式的值在 mixin 的主体中可用作相应的变量。
@mixin rtl($property, $ltr-value, $rtl-value) {#{$property}: $ltr-value;[dir=rtl] & {#{$property}: $rtl-value;}}.sidebar {@include rtl(float, left, right);}
可选参数
@mixin replace-text($image, $x: 50%, $y: 50%) {text-indent: -99999em;overflow: hidden;text-align: left;background: {image: $image;repeat: no-repeat;position: $x $y;}}.mail-icon {@include replace-text(url("/images/mail.svg"), 0);}
关键字参数
在声明 mixin 时的语法与可选参数没有什么不同,只是在使用时需要传入与形式参数相同的名称。
@mixin square($size, $radius: 0) {width: $size;height: $size;@if $radius != 0 {border-radius: $radius;}}.avatar {@include square(100px, $radius: 4px);}
注意
因为任意参数都可以作为名称传递,所以在重命名 mixin 参数时,要将传入原参数名的行为打印警告,以通知他们使用新的参数名称。
任意数量的参数
@mixin order($height, $selectors...) {@for $i from 0 to length($selectors) {#{nth($selectors, $i + 1)} {position: absolute;height: $height;margin-top: $i * $height;}}}@include order(150px, "input.name", "input.address", "input.zip");
传入的剩余参数将作为参数列表传给 $selectors 。
你可以这样实现 mixin 重命名
@mixin btn($args...) {@warn "The btn() mixin is deprecated. Include button() instead.";@include button($args...);}
内容块
@mixin hover {&:not([disabled]):hover {@content;}}.button {border: 1px solid black;@include hover {border-width: 2px;}}
⚠️注意
在内容块中使用变量必须提前定义。
@function
抽象公式和行为。
@function pow($base, $exponent) {$result: 1;@for $_ from 1 through $exponent {$result: $result * $base;}@return $result;}.sidebar {float: left;margin-left: pow(4, 3) * 1px;}
@return
它只能在 @function 体内使用,每个 @function 必须以 @return 结束。
@extend
.error:hover {background-color: #fee;}.error--serious {@extend .error;border-width: 3px;}
规则
@extend 可以拓展选择器的样式规则
- 永远不会生成 #main#footer 这样的选择器。
- 确保复杂选择器无论怎么嵌套都能工作。
- 尽可能除去冗余选择器,同时确保选择器的准确性。
- 合并相同规则的选择器。
- 智能地处理组合器,通用选择器和包含选择器的伪类。
.content nav.sidebar {@extend .info;}// 不会拓展,因为 p 和 nav 不能同时存在p.info {background-color: #dee9fc;}// 无法确定 .guide 和 .content 的包含关系,所以 SASS 将两个都生成了.guide .info {border: 1px solid rgba(#000, 0.8);border-radius: 2px;}// main.content 存在 main.content nav.sidebar 必然存在main.content .info {font-size: 0.8em;}
强制和可选扩展
@extend 必须匹配到选择器,否则会产生错误。如果想让拓展是可选的,在末尾加上 !optional 。
@media
不能在 @media 中使用 @extend 。
@error
在编写带有参数的 mixin 和函数时,需要确保参数具有所期望的类型和格式。如果不是,则通知用户并且您的 mixin / function 停止运行。
@mixin reflexive-position($property, $value) {@if $property != left and $property != right {@error "Property #{$property} must be either left or right.";}$left-value: if($property == right, initial, $value);$right-value: if($property == right, $value, initial);left: $left-value;right: $right-value;[dir=rtl] & {left: $right-value;right: $left-value;}}.sidebar {@include reflexive-position(top, 12px);// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^// Error: Property top must be either left or right.}
@warn
在编写 mixin 和函数时,阻止用户传递某些参数或某些值。它们可能正在传递现已弃用的旧参数,或者它们可能以不太理想的方式调用 API。
$known-prefixes: webkit, moz, ms, o;@mixin prefix($property, $value, $prefixes) {@each $prefix in $prefixes {@if not index($known-prefixes, $prefix) {@warn "Unknown prefix #{$prefix}.";}-#{$prefix}-#{$property}: $value;}#{$property}: $value;}.tilt {// Oops, we typo'd "webkit" as "wekbit"!@include prefix(transform, rotate(15deg), wekbit ms);}
@debug
开发样式表时查看变量或表达式的值, @debug 打印该表达式的值,以及文件名和行号。
@mixin inset-divider-offset($offset, $padding) {$divider-offset: (2 * $padding) + $offset;@debug "divider offset: #{$divider-offset}";margin-left: $divider-offset;width: calc(100% - #{$divider-offset});}
@at-root
和 selector-unify() 函数一起使用表示使用根选择器作为 & 的值。
@mixin unify-parent($child) {@at-root #{selector-unify(&, $child)} {@content;}}.wrapper .field {@include unify-parent("input") {/* ... */}@include unify-parent("select") {/* ... */}}
使用 with 或者 without 告诉 @at-root 排除哪些规则。
@media print {.page {width: 8in;@at-root (without: media) {color: #111;}@at-root (with: rule) {font-size: 1.2em;}}}
除了 at-rules 的名称之外,还有两个可以在查询中使用的特殊值:
rule指的是风格规则。例如,@at-root (with: rule)排除所有 at-rules 但保留样式规则。all指的是所有的规则和风格规则都应该被排除在外。
流程控制
@if 和 @else
false 和 null 在 Sass 中是假,空字符串、空列表和数字 0 在 Sass 中都是真。
@each
解构
$icons:"eye" "\f112" 12px,"start" "\f12e" 16px,"stop" "\f12f" 10px;@each $name, $glyph, $size in $icons {.icon-#{$name}:before {display: inline-block;font-family: "Icon Font";content: $glyph;font-size: $size;}}
@for
使用 to 排除最后的数字,使用 through 包含最终数字。
$base-color: #036;@for $i from 1 through 3 {ul:nth-child(3n + #{$i}) {background-color: lighten($base-color, $i * 5%);}}
参考
【1】Sass 官网文档
