展开 折叠

Sass 3.4.21 中文手册

Sass 是一个 CSS 的扩展,它在 CSS 语法的基础上,允许您使用变量 (variables), 嵌套规则 (nested rules), 混合 (mixins), 导入 (inline imports) 等功能,令 CSS 更加强大与优雅。使用 Sass 以及 Compass 样式库 有助于更好地组织管理样式文件,以及更高效地开发项目。

特色 (Features)

  • 完全兼容 CSS3
  • 在 CSS 语言的基础上增加变量(variables)、嵌套 (nesting)、混合 (mixins) 等功能
  • 通过函数进行颜色值与属性值的运算
  • 提供 控制指令等高级功能
  • 自定义输出格式

语法 (Syntax)

Sass 有两种语法格式。首先是 SCSS (Sassy CSS) ,也是本参考资料示例所使用的格式 , 这种格式仅在 CSS3 语法的基础上进行扩展,这意味着每个CSS样式表是一个同等的SCSS文件。此外,SCSS 也支持大多数 CSS hacks 写法 以及浏览器专属前缀语法 (vendor-specific syntax),例如,IE 古老的 filter 语法。 这种语法的样式表文件需要以 .scss 作为拓展名。

另一种,也是最早的语法,被称为缩进语法 (Indented Sass),或者通常说的 "Sass",它提供了一种更加简介的方式来书写CSS。它使用缩进而不是花括号来表示选择器的嵌套,用换行而不是分号来分隔属性,一些人认为这样做比 SCSS 更容易阅读,书写也更快速。 缩排语法具有 Sass 的所有特色功能, 虽然有些语法上稍有差异; 具体差异在缩进语法参考中都有描述。 使用此种语法的样式表文件需要以 .sass 作为扩展名。

任何一种语法的文件可以直接 import(导入) 到另一种语法的文件中使用,只要使用 sass-convert 命令行工具,就可以将一种语法转换为另一种语法:

# Convert Sass to SCSS
$ sass-convert style.sass style.scss

# Convert SCSS to Sass
$ sass-convert style.scss style.ss 

请注意,此命令 不会 生成CSS文件。要想生成CSS文件,请使用其他地方描述的 sass 命令。

使用 Sass (Using Sass)

Sass 有三种使用方式:作为命令行工具,作为独立的 Ruby 模块 (Ruby module),或者作为 Rack-enabled 框架的插件,包括 Ruby on Rails 与 Merb。无论使用哪种方式都需要首先安装 Sass gem :

gem install sass 

如果你使用的是Windows ,你可能首先需要安装Ruby

如果要在命令行中运行 Sass ,只要使用

sass input.scss output.css 

你还可以使用Sass命令来监视某个Sass文件的改动,并自动编译来更新 CSS :

sass --watch input.scss:output.css 

如果你的目录里有很多 Sass 文件,你也可以使用Sass命令来监视整个目录:

sass --watch app/sass:public/stylesheets 

使用 sass --help 可以列出完整的帮助文档。

在 Ruby 中使用 Sass 也非常容易,Sass gem 安装完毕后,用它运行 require "sass", 然后按照下面的方法使用 Sass::Engine

engine = Sass::Engine.new("#main {background-color: #0000ff}", :syntax => :scss)
engine.render #=> "#main { background-color: #0000ff; }\n" 

Rack/Rails/Merb 插件(Plugin)

在 Rails 3 之前的版本中启用 Sass,需要在 environment.rb 文件中添加一行代码:

config.gem "sass" 

对于 Rails 3,则是把这一行加到 Gemfile 中:

gem "sass" 

要在 Merb 中启用 Sass,需要在 config/dependencies.rb 文件中添加一行代码:

dependency "merb-haml" 

在 Rack 应用中启用 Sass,需要在 config.ru 文件中添加以下代码:

require 'sass/plugin/rack'
use Sass::Plugin::Rack 

Sass 样式表跟视图(views)的工作方式不同。 它不包含任何动态内容, 因此只需要在 Sass 文件更新时生成 CSS 即可。 默认情况下,.sass.scss 文件是放在 public/stylesheets/sass 目录下的(这可以通过 :template_location 选项进行配置)。 然后,在需要的时候,它们会被编译成相应的 CSS 文件并被放到 public/stylesheets 目录下。 例如,public/stylesheets/sass/main.scss 文件将会被编译为 public/stylesheets/main.css 文件。

缓存 (Caching)

默认情况下,Sass 会自动缓存编译后的模板(template)与 partials,这样做能够显著提升重新编译的速度,在处理 Sass 模板被切割为多个文件并通过 @import 导入,形成一个大文件时效果尤其显著。

如果不使用框架的情况下,Sass 将会把缓存的模板放入 .sass-cache 目录。 在 Rails 和 Merb 中,缓存的模板将被放到tmp/sass-cache 目录。 此目录可以通过:cache_location 选项进行自定义。 如果你不希望 Sass 启用缓存功能, 可以将 :cache 选项设置为 false

配置选项 (Options)

选项可以通过设置的Sass::Plugin#options hash,具体设置在Rails中的environment.rb或者Rack中的config.ru的文件中:

Sass::Plugin.options[:style] = :compact 

或者,如果你使用Merb,那么可以在init.rb文件中设置Merb::Plugin.config[:sass] hash :

Merb::Plugin.config[:sass][:style] = :compact 

或者通过传递一个选项 (options) hash 给Sass::Engine#initialize
所有相关的选项也可通过标记在sassscss命令行可执行文件中使用。可用选项有:

选项 描述
:style 设置输出CSS的代码风格,可以查看输出的代码风格
:syntax 输入文件的语法,:sass 表示缩进语法,:scss表示CSS扩展语法。只有在你自己构造Sass::Engine 实例的情况下有用;当你使用 Sass::Plugin时,它会自动设置正确的值。默认设置为 :sass
:property_syntax 强制缩进语法文档使用一个属性语法。如果不使用正确的语法,将抛出一个错误。:new值表示强制在属性名后面使用一个冒号。例如:color: #0f3或者 width: $main_width:old值表示强制在属性名前面使用一个冒号。例如::color #0f3 或者 :width $main_width。默认请客下,两种语法都是有效的。该选项对于SCSS(.scss)文档是无效的。
:cache 解析 Sass 时是否应该缓存,允许更快的编译速度。默认设置为 true
:read_cache 如果设置了这个选项,而没有设置:cache选项,那么缓存存在就只读 Sass 缓存,如果没有没有缓存,那就不会编译。
:cache_store 如果该选项设置为 Sass::CacheStores::Base 的子类的实例,该缓存存储将被用于存储和检索缓存编译结果。默认设置为Sass::CacheStores::Filesystem,初始化使用:cache_location 选项
:never_update CSS文件永远不应该被更新,即使是模板(template)文件改变。将其设置为true可能会带来小的性能提升。它总是默认为false。该选项只有在Rack,Ruby on Rails,或Merb中有意义。
:always_update CSS文件总是应该进行更新,即使是在每一个控制器被访问时,而不是只当模板被修改时更新。默认为false。该选项只有在Rack,Ruby on Rails,或Merb中有意义。
:always_check Sass模板总是应该被检查是否更新,即使是在每一个控制器被访问时,而不是只在服务启动时。如果一个Sass模板(template)被更新,它会被重新编译并且覆盖相应的CSS文件。在生产模式中默认为false,否则true。该选项只有在Rack,Ruby on Rails,或Merb中有意义。
:poll 如果为true,始终使用Sass::Plugin::Compiler#watch后端轮询而不是本机文件系统的后端。
:full_exception Sass代码中错误是否应该在生成的CSS文件中提供详细的说明。如果设置为true,这个错误将显示在CSS文件的注释中 和页面顶部(支持的浏览器),错误内容包括行号和源代码片段。 否则,异常将在Ruby代码中提醒。在生产模式中默认为false,否则true
:template_location 一个路径,应用根目录中Sass模板(template)的目录。如果散列,:css_location 将被忽略,并且这个选项指定输入和输出目录之间的映射。也可以给定二元列表,代替散列(hash)。默认为css_location + "/sass"。该选项只有在Rack,Ruby on Rails,或Merb中有意义。请注意,如果指定了多个模板位置,它们全部都放置在导入路径中,允许你在它们之间进行导入。
需要注意的是,由于它可以采用许多可能的格式,这个选项应该只直接设置,不应该被访问或修改。使用 Sass::Plugin#template_location_arraySass::Plugin#add_template_locationSass::Plugin#remove_template_location方法来代替。
:css_location CSS文件输出的路径,当:template_location选项为一个散列(hash)时,这个选项将被忽略。默认设置为"./public/stylesheets"。该选项只有在Rack,Ruby on Rails,或Merb中有意义。
:cache_location 其中,高速缓存sassc 文件应写入的路径。在Rails和Merb中默认为"./tmp/sass-cache",否则默认为"./.sass-cache" 。如果设置了:cache_store 选项,这个将被忽略。
:unix_newlines 如果为true,写入文件时使用Unix风格的换行符。只有在Windows上,并且只有当Sass被写入文件时有意义(在 Rack, Rails, 或 Merb中,直接使用Sass::Plugin时,或者使用命令行可执行文件时)。
:filename 被渲染文件的文件名。这完全是用于报告错误,使用Rack, Rails, or Merb时自动设置。
:line Sass模板(template)第一行的行号。用于报告错误的行号。如果Sass模板(template)嵌入一个Ruby文件中,这个设置是很有用的。
:load_paths 一个数组,包含文件系统 或 通过@import指令导入的 Sass模板(template)路径。他们可能是字符串, Pathname (路径名)对象或者是Sass::Importers::Base的子类。该选项默认为工作目录,并且在Rack, Rails, 或 Merb中,该选项无论如何值都是:template_location。加载路径也可以由Sass.load_pathsSASS_PATH 环境变量通知。
:filesystem_importer 一个Sass::Importers::Base的子类,用来处理普通字符串的加载路径。这应该从文件系统导入文件。这应该是一个通过构造函数带一个字符串参数(加载路径),继承自Sass::Importers::Base的Class对象。默认为Sass::Importers::Filesystem
:sourcemap 控制如何生产sourcemap。这些sourcemaps告诉浏览器如何找到Sass样式,从而生成每一个CSS样式。该选项有三个有效值::auto在可能的情况下使用相对URI,假设在你使用的任何服务器上提供的源样式,那么它们的相对位置将和本地文件系统是相同的。如果一个相对URI不可用,那么将被"file:"替换。:file总是使用"file:" URI,这将在本地工作,但不能被部署到一个远程服务器。 :inline包含sourcemap中完整的源文本,这是最方便的,但是可能生产非常大的sourcemap文件。 最后,:none 会导致总是不会生成sourcemap文件。
:line_numbers 当设置为true的时候,定义的选择器的行号和文件名 将被作为注释注入到编译的CSS中。这对调试来说是有用的,特别是使用@import@mixin的时候。这个选项有个别名叫做:line_comments。当使用 :compressed输出样式或使用:debug_info/:trace_selectors选项时这个选项将自动禁用。
:trace_selectors 当设置为true的时候,将在每个选择器之前注入@import@mixin的完整轨迹。在浏览器中调试通过@import@mixin包含进来的样式表时是很有用的。此选项将取代 :line_comments 选项,并且被:debug_info选项取代。当使用 :compressed输出样式时,这个选项将自动禁用。
:debug_info 当设置为true的时候,定义的选择器的行号和文件名 将被注入到编译后的CSS中,可以被浏览器所识别。用于FireSass Firebug 扩展,以显示Sass文件名和行号。当使用 :compressed输出样式时,这个选项将自动禁用。
:custom 这个选项可用于单个应用程序设置以使数据可用于定制Sass功能
:quiet 当设置为true的时候,导致禁用警告信息。

语法选择(Syntax Selection)

Sass命令行工具将使用文件扩展名以确定你使用的是哪种语法,但并不总是一个文件名。sass命令行程序默认为缩进语法,但如果输入应该被解析为SCSS语法,你可以传递--scss选项给她。此外,你可以使用scss命令行程序,它和sass程序完全一样,但是他的默认语法为SCSS。

编码格式 (Encodings)

在 Ruby 1.9 及以上环境中运行 Sass 时,Sass 对文件的编码格式比较敏感,首先会根据 CSS spec 判断样式文件的编码格式, 如果失败则检测 Ruby 字符串编码。也就是说,Sass 首先检查 Unicode 字节顺序标记,然后是 @charset 声明,最后是 Ruby 字符串编码,假如都没有检测到,默认使用 UTF-8 编码。

要明确指定样式表的编码,与 CSS 相同,使用@charset声明。在样式文件的起始位置(前面没有任何空白与注释)插入 @charset "encoding-name";, Sass 将会按照给定的编码格式编译文件。注意,无论你使用哪种编码,它必须可以转换为 Unicode 字符集。

默认情况下,Sass 总会以UTF-8编码输出 CSS 文件。当且仅当输出文件包含非ASCII字符时,才会在输出文件中添加 @charset 声明,在压缩模式中,而在压缩模式下 (compressed mode) 使用 UTF-8字节顺序标记代替 @charset 声明语句。

CSS扩展 (CSS Extensions)

嵌套规则 (Nested Rules)

Sass 允许将一个 CSS 样式嵌套进另一个样式中,内层样式仅适用于外层样式的选择器范围内(手册网注:可以理解为层级选择器),例如:

#main p {
  color: #00ff00;
  width: 97%;

  .redbox {
    background-color: #ff0000;
    color: #000000;
  }
} 

编译为:

#main p {
  color: #00ff00;
  width: 97%; }
  #main p .redbox {
    background-color: #ff0000;
    color: #000000; } 

这有助于避免父选择器重复,相对于复杂的CSS布局中多层嵌套的选择器 要简单得多。 例如:

#main {
  width: 97%;

  p, div {
    font-size: 2em;
    a { font-weight: bold; }
  }

  pre { font-size: 3em; }
} 

编译为:

#main {
  width: 97%; }
  #main p, #main div {
    font-size: 2em; }
    #main p a, #main div a {
      font-weight: bold; }
  #main pre {
    font-size: 3em; } 

引用父选择器:& (Referencing Parent Selectors: &)

有些时候需要直接使用嵌套外层的父选择器,这个就很有用了,例如,你可能喜欢给选择器指定 hover样式,或者当body元素具有某个样式时,在这些情况下,你可以 & 字符来明确地表示插入指定父选择器。 例如:

a {
  font-weight: bold;
  text-decoration: none;
  &:hover { text-decoration: underline; }
  body.firefox & { font-weight: normal; }
} 

编译为:

a {
  font-weight: bold;
  text-decoration: none; }
  a:hover {
    text-decoration: underline; }
  body.firefox a {
    font-weight: normal; } 

&将替换为呈现在CSS文件中的父选择器。这意味着,如果你有一个多层嵌套的规则,父选择器将在被&替换之前完全分解。 例如:

#main {
  color: black;
  a {
    font-weight: bold;
    &:hover { color: red; }
  }
} 

编译为:

#main {
  color: black; }
  #main a {
    font-weight: bold; }
    #main a:hover {
      color: red; } 

& 必须出现在的选择器的开头位置(手册网注:也就是作为选择器的第一个字符),但可以跟随后缀,将被添加到父选择的后面。 例如:

#main {
  color: black;
  &-sidebar { border: 1px solid; }
} 

编译为:

#main {
  color: black; }
  #main-sidebar {
    border: 1px solid; } 

父选择器 & 被作为一个后缀的时候,Sass 将抛出一个错误。

嵌套属性 (Nested Properties)

CSS中有一些属性遵循相同的“命名空间”;比如,font-family, font-size, 和 font-weight都在font命名空间中。在CSS中,如果你想在同一个命名空间中设置一串属性,你必须每次都输出来。Sass为此提供了一个快捷方式:只需要输入一次命名空间,然后在其内部嵌套子属性。例如:

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
} 

编译为:

.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; } 

命名空间也可以有自己的属性值。例如:

.funky {
  font: 20px/24px fantasy {
    weight: bold;
  }
} 

编译为:

.funky {
  font: 20px/24px fantasy;
    font-weight: bold;
} 

占位符选择器: %foo (Placeholder Selectors: %foo)

Sass 支持一种特殊类型的选择器,叫做"占位符选择器" (placeholder selector)。这些看起来像 class 和 id 选择器,除了#.%替换。他们需要在@extend 指令中使用;有关详细信息,请参阅@extend-Only Selectors

当他们单独使用的时候,即没有使用@extend的,使用占位符选择器的规则集将不会被渲染为CSS。

注释: /* *///(Comments: /* */ and //

Sass 支持标准的CSS多行注释以/* */以及单行注释 //。在尽可能的情况下,多行注释会被保留在输出的CSS中,而单行注释会被删除。 例如:

/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body { color: black; }

// These comments are only one line long each.
// They won't appear in the CSS output,
// since they use the single-line comment syntax.
a { color: green; } 

编译为:

/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body {
  color: black; }

a {
  color: green; } 

如果多行注释的第一个字母是 !,那么注释总是会被保留到输出的CSS中,即使在压缩输出模式下。这可用于在你生成的CSS中添加版权声明。

使用插值语句 (interpolation) ,可以将变量值输出到多行注释中,例如:

$version: "1.2.3";
    /* This CSS is generated by My Snazzy Framework version #{$version}. */ 

编译为:

/* This CSS is generated by My Snazzy Framework version 1.2.3. */ 

SassScript

除了普通的CSS属性的语法,Sass 支持一些扩展,名为SassScript。SassScript允许属性使用变量,算术和额外功能。SassScript可以在任何属性值被使用。

SassScript也可以用来生成选择器和属性名称,当编写mixins时非常有用。这是通过 interpolation(插值) 完成。

交互式 shell(Interactive Shell)

Interactive Shell 可以在命令行中测试 SassScript 的功能。在命令行中输入 sass -i,然后输入想要测试的 SassScript 查看输出结果:

您可以使用交互式shell(Interactive Shell)轻松地尝试 SassScript。
要箱运行启动 shell ,只要使用-i选项的 sass 命令行(手册网注:在命令行中输入 sass -i)。
在提示符下,输入任何合法的 SassScript表达式,由它他评估并打印出您的结果:

$ sass -i
>> "Hello, Sassy World!"
"Hello, Sassy World!"
>> 1px + 1px + 1px
3px
>> #777 + #777
#eeeeee
>> #777 + #888
white 

变量: $(Variables: $

使用SassScript最直截了当的方法是使用变量。变量以美元符号开始,赋值像设置CSS属性那样:

$width: 5em; 

你可以在属性中引用他们:

#main {
  width: $width;
} 

变量仅在它定义的选择器嵌套层级的范围内可用(手册网注:可以理解为块级作用域)。不在任何嵌套选择器内定义的变量则在可任何地方使用(手册网注:可以理解为全局变量)。定义变量的时候可以后面带上!global标志,在这种情况下,变量在任何地方可见(手册网注:可以理解为全局变量)。例如:

#main {
  $width: 5em !global;
      width: $width;
}

#sidebar {
  width: $width;
} 

编译为:

#main {
  width: 5em;
}

#sidebar {
  width: 5em;
} 

由于历史原因,变量名(以及其他所有Sass标识符)可以互换连字符(手册网注:-)和下划线(手册网注:_)。例如,如果你定义了一个名为 $main-width,您可以使用 $main_width访问它,反之亦然。

数据类型 (Data Types)

SassScript 支持 7 种主要的数据类型:

  • 数字 (例如: 1.2, 13, 10px)
  • 文本字符串,带引号字符串和不带引号字符串(例如:"foo", 'bar', baz)
  • 颜色 (例如:blue, #04a3f9, rgba(255, 0, 0, 0.5))
  • 布尔值 (例如: true, false)
  • 空值 (例如: null)
  • 值列表 (list),用空格或逗号分隔 (例如: 1.5em 1em 0 2em, Helvetica, Arial, sans-serif)
  • maps ,从一个值映射到另一个 (例如: (key1: value1, key2: value2))

SassScript也支持其他所有类型的CSS属性值,比如 Unicode 字符集,或 !important 声明。然而,不会对这些类型的属性值做特殊处理,一律视为不带引号的字符串。

字符串(Strings)

CSS指定两种字符串类型:带引号的字符串(手册网注:包括双引号和单引号),如"Lucida Grande" 或者 'http://sass-lang.com',还有不带引号的字符串,如sans-serif 或者 bold。SassScript 识别这两种类型,并且一般来说,在编译输出的CSS文件中不会改变Sass文档中使用的字符串类型。

有一个例外,当使用 #{} interpolation时,带引号的字符串将被编译为不带引号的字符串,这样主要是为了便于使用,比如mixins中的选择器名称。例如:

@mixin firefox-message($selector) {
      body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}

@include firefox-message(".header"); 

编译为:

body.firefox .header:before {
  content: "Hi, Firefox users!"; } 

列表(Lists)

列表(lists) 是指 Sass 如何表示在CSS声明的,类似margin: 10px 15px 0 0font-face: Helvetica, Arial, sans-serif这样的值,列表只是一串其他值,无论是用空格还是用逗号隔开。事实上,独立的值也被视为列表:只包含一个值的列表。

列表本身没有太多的功能,但 Sass list functions 赋予了数组更多新功能:nth 函数可以直接访问数组中的某一项;join 函数可以将多个数组连接在一起;append 函数可以在数组中添加新值;而 @each 指令能够遍历数组中的每一项。

列表本身没有太多的功能,但是 SassScript list functions 使它们非常有用。nth 函数可以直接访问列表中的某一项;join 函数可以将多个列表拼接在一起;append 函数可以将某项添加到列表中;@each 指令可以将添加样式到列表中的每一项。

除了包含简单的值,列表可包含其他列表。例如,1px 2px, 5px 6px包含1px 2px列表和5px 6px列表两个项。如果内外两层列表使用相同的分隔符号,你需要使用括号将内层列表括起来,以明确内层类别的开始和结束位置。
例如,(1px 2px) (5px 6px) 同样是包含1px 2px列表和5px 6px列表两个项的列表。不同的是,该列表层外用空格分隔,之前列表外层是用逗号分隔。

当列表被编译为 CSS 时,Sass 不会添加任何圆括号,因为CSS不能识别他们。这意味着, (1px 2px) (5px 6px)1px 2px 5px 6px 在编译后的 CSS 文件中看起来是完全一样的。然而,它们在 Sass 中却是不同的:第一个是含两个列表的列表,而第二个是含有四个成员的列表。

用 () 表示不包含任何值的空数组(在 Sass 3.3 版之后也视为空的 map)。空数组不可以直接编译成 CSS,比如编译 font-family: () Sass 将会报错。如果数组中包含空数组或空值,编译时将被清除,比如 1px 2px () 3px 或 1px 2px null 3px。

列表也可以没有任何项。这些列表可以用 () 表示(也是一个空的 map)。
它们不能直接输出到CSS;如果你试图这样做,例如font-family: (),Sass 将会报错。如果列表中包含空列表或空值,比如 1px 2px () 3px 或者 1px 2px null 3px,在包含列表编译成CSS前,空列表和空值将被删除。

逗号分隔的列表可以保留结尾的逗号。这是特别有用,因为它可以表示一个 单个元素的列表。
例如,(1,)表示为只包含1的列表,而(1 2 3,)这个表示包含一个列表,这个列表又包含以空格分隔的1,2, 和 3的列表。

Maps

Maps代表一个键和值对集合,其中键用于查找值。他们可以很容易地将值收集到命名组中,并且可以动态地访问这些组。在CSS中你找不到和他们类似的值,虽然他们的语法类似于媒体查询表达式:

$map: (key1: value1, key2: value2, key3: value3); 

和列表(Lists)不同,Maps必须始终使用括号括起来,并且必须用逗号分隔。Maps中的键和值可以是任意的SassScript对象。一个Maps可能只有一个值与给定的键关联(尽管该值可以是一个列表)。一个给定的值可能与许多键关联。

和列表(Lists)类似,Maps的主要操作使用的是 SassScript 函数map-get函数用于查找map中的值,map-merge函数用于添加值到map中的值, @each 指令可以用来为 map 中的每个键值对添加样式。map中键值对的顺序和map创建时始终相同。

Maps还可以用于任何列表(Lists)能做的事情。当用于一个列表函数时,map被视为键值对列表。例如,(key1: value1, key2: value2)被用于列表函数时,将被视为嵌套列表key1 value1, key2 value2。列表不能被视为maps,不过,空列表除外。 ()表示一个键/值对都没有的map,也可以被视为一个没有元素的列表。

需要注意的是 map 的建(keys)可以是任何 Sass 数据类型(甚至是另一个map),并且声明map的语法允许是任意的SassScript表达式,这个表达式将被评估为一个值以确定建(keys)。

Maps不能转换为纯CSS。作为变量的值或参数传递给CSS函数将会导致错误。使用inspect($value) 函数以产生输出字符串,这对于调试 maps 非常有用。

颜色(Colors)

任何CSS颜色表达式返回SassScript颜色值。这其中包括了大量的命名的颜色,这些名字字符串不区别带不带引号。

在压缩输出模式,Sass 将输出CSS简短的颜色表示法。例如,在压缩模式下 #FF0000 将输出为red,但是blanchedalmond将输出为 #FFEBCD

一个用户遇到的常见问题是在其它输出模式中Sass喜欢输出与命名的颜色相同的格式,当压缩的时候,插值到选择器的颜色变得无效语法。为了避免这种情况,如果他们是为了在选择施工中使用,总是给命名的颜色。

运算 (Operations)

所有数据类型的支持相等运算(==!=)。此外,每种类型都有其自己特殊的运算方式。

数字运算 (Number Operations)

SassScript 支持对数字标准的算术运算(加法+,减法 - ,乘法*,除法/和取模%)。Sass 数学函数在算术运算期间会保留单位。这意味着,就像在现实生活中,你不能用不相同的单位数字进行算术运算(比如数字后面添加了pxem单位),还有两个单位相同的数字相乘将产生单位平方(10px * 10px == 100px * px)。要知道px * px是无效的CSS单位,Sass会抛出一个错误,因为你试图在CSS中使用无效的单位。

数字支持关系运算符(<, >, <=, >=),并且所有类型支持相等运算符(==, !=)。

除法和 / (Division and /

CSS允许 / 出现在属性值之间作为分隔数字的方式(手册网注:例如font属性,p.ex2{font:italic bold 12px/20px arial,sans-serif;})。由于SassScript是CSS属性语法的扩展,所以它必须支持这一点,同时还允许 / 用于除法。这意味着,在默认情况下,在SassScript中如果两个数字由 / 分隔,在返回的CSS中将以同样的方式出现。

但是,这里有将/解析为除法三种情况。这些涵盖了绝大多数当做除法的案例。 他们是:

  1. 如果该值,或值的任何部分,存储在一个变量中或通过函数返回。
  2. 如果该值是由括号括起来的,除非这些括号是在一个列表(list)外部,并且值是括号内部。
  3. 如果该值被用作另一个算术表达式的一部分。

例如:

p {
  font: 10px/8px;             // 原生的CSS,不作为除法
  $width: 1000px;
      width: $width/2;            // 使用了变量, 作为除法
  width: round(1.5)/2;        // 使用了函数, 作为除法
  height: (500px/2);          // 使用了括号, 作为除法
  margin-left: 5px + 8px/2px; // 使用了 +, 作为除法
  font: (italic bold 10px/8px); // 在一个列表(list)中,括号可以被忽略。
} 

编译为:

p {
  font: 10px/8px;
  width: 500px;
  height: 250px;
  margin-left: 9px; } 

如果你想纯CSS 的/ 和变量一起使用(手册网注:即/不作为除法使用),你可以使用#{}插入他们。例如:

p {
  $font-size: 12px;
      $line-height: 30px;
  font: #{$font-size}/#{$line-height};
} 

编译为:

p {
  font: 12px/30px; } 
减法,负数,和 -(Subtraction, Negative Numbers, and -)

在CSS和在Sass中 - 有许多不同的意义。它可以是一个减法运算符(比如在5px - 3px中),也可以表示一个负数(比如在-3px中),还可以是一个一元负运算符(比如在-$var中),或是标识符的一部分(比如在font-weight中)。大多数时候,我们可以很容易的分辨- 到底代表什么,但也有一些棘手的请客。以下作为一般规则,你是最安全的使用-

  • 减法的时候,你总是在 - 两侧保留空格。
  • 当表示一个负数或一元负运算时候,在-前面包含一个空格,后面不加空格。
  • 如果在一个空格隔开的list(列表)中,你可以将一元负运算使用括号括起来,比如在10px (-$var)中。

- 的不同含义的优先顺序如下:

  1. - 作为标识符的一部分。这意味着a-1是一个不带引号的字符串,其值为"a-1"。唯一的例外是单位;Sass 通常允许任何有效的标识符被用作一个标识符,但标识符不可能以数字或连字符开始。这意味着,5px-3px5px - 3px是相同。

  2. - 在不带空格两个数字之间。这表明是减法,所以1-21 - 2 是相同的。

  3. 字面数字以 - 开头。这表明是一个负数,所以 1 -2是一个含有1-2的 list(列表)。

  4. - 两个数字之间,不论是否带空格。这表明是减法,所以 1 -$var1 - $var 是相同的。

  5. - 在值之前。这表明是一元负运算符;该操作需要一个数字,并返回其负值。

颜色运算 (Color Operations)

所有算术运算都支持的颜色值,颜色值的运算是分段进行计算的,也就是,依次计算红(red),绿(green),以及蓝(blue)的成分值。例如:

p {
  color: #010203 + #040506;
} 

计算 01 + 04 = 05, 02 + 05 = 07, 和 03 + 06 = 09,并且编译为:

p {
  color: #050709; } 

通常color functions(颜色函数)比尝试使用颜色运算更加有用,以达到同样的效果。

数字和颜色值之间的算术运算也是分段。例如:

p {
  color: #010203 * 2;
} 

计算 01 * 2 = 02, 02 * 2 = 04, 和 03 * 2 = 06,并且编译为:

p {
  color: #020406; } 

需要注意的是,包含alpha通道(那些由rgbahsla函数创建的)的颜色必须具有相同的alpha值,才能进行颜色运算。这样算术不会影响alpha值。例如:

p {
  color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
} 

编译为:

p {
  color: rgba(255, 255, 0, 0.75); } 

颜色的alpha通道可以使用opacifytransparentize函数进行调整。例如:

$translucent-red: rgba(255, 0, 0, 0.5);
    p {
      color: opacify($translucent-red, 0.3);
      background-color: transparentize($translucent-red, 0.25);
} 

编译为:

p {
  color: rgba(255, 0, 0, 0.8);
  background-color: rgba(255, 0, 0, 0.25); } 

IE浏览器的滤镜(filters)要求所有的颜色包括 alpha 层,而且格式必须是固定的 #AABBCCDD ,使用 ie_hex_str 函数可以轻松的将颜色转化为 IE 滤镜所要求的格式。例如:

$translucent-red: rgba(255, 0, 0, 0.5);
    $green: #00ff00;
div {
  filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr='#{ie-hex-str($green)}', endColorstr='#{ie-hex-str($translucent-red)}');
} 

编译为:

div {
  filter: progid:DXImageTransform.Microsoft.gradient(enabled='false', startColorstr=#FF00FF00, endColorstr=#80FF0000);
} 

字符串运算 (String Operations)

+ 运算可用于连接字符串:

p {
  cursor: e + -resize;
} 

编译为:

p {
  cursor: e-resize; } 

请注意,如果带引号的字符串被添加到不带引号的字符串中(也就是说,带引号的字符串在 + 的左侧),
那么返回的结果是带引号的字符串。同样,如果一个不带引号的字符串添加到带引号的字符串中(不带引号的字符串在 + 的左侧)那么返回的结果是一个不带引号的字符串。 例如:

p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
} 

编译为:

p:before {
  content: "Foo Bar";
  font-family: sans-serif; } 

默认情况下,运算表达式与其他值连用时,用空格做连接符:

p {
  margin: 3px + 4px auto;
} 

编译为:

p {
  margin: 7px auto; } 

在文本字符串中,#{}式插值可以用来在字符串中放置动态值:

p:before {
  content: "I ate #{5 + 10} pies!";
} 

编译为:

p:before {
  content: "I ate 15 pies!"; } 

在字符串插值时,Null值被视为空字符串:

$value: null;
    p:before {
      content: "I ate #{$value} pies!";
} 

编译为:

p:before {
  content: "I ate  pies!"; } 

布尔运算 (Boolean Operations)

SassScript 支持布尔值的 and, or, 和 not 运算。

列表运算 (List Operations)

数组不支持任何特殊运算,只能使用 list 函数 控制。

圆括号 (Parentheses)

圆括号可以用来影响运算的顺序(手册网注:优先级):

p {
  width: 1em + (2em * 3);
} 

编译为:

p {
  width: 7em; } 

函数 (Functions)

SassScript定义了一些有用的函数, 这些函数可以像普通 CSS 函数语法一样调用:

p {
  color: hsl(0, 100%, 50%);
} 

编译为:

p {
  color: #ff0000; } 

可用函数的完整列表,请参阅这张页面

关键词参数 (Keyword Arguments)

Sass 函数允许指定明确的关键词参数 (keyword arguments) 进行调用。 上面的例子也可以改写成:

p {
  color: hsl($hue: 0, $saturation: 100%, $lightness: 50%);
} 

虽然不够简明,但可以让Sass代码阅读起来更加方便。 关键词参数让函数具有更灵活的接口, 即便参数众多,也不会让使用变得困难。

命名参数(named arguments)可以以任意顺序传入,并且,具有默认值的参数可以省略掉。 由于命名参数也是变量名称,因此,下划线、短横线可以互换使用。

完整的 Sass 函数列表和它们的参数名称,以及在 Ruby 里如何定义你自己的函数的步骤,请见 Sass::Script::Functions

插值:#{}(Interpolation: #{}

您还可以通过 #{} 插值语法在选择器和属性名中使用 SassScript 变量:

$name: foo;
    $attr: border;
p.#{$name} {
      #{$attr}-color: blue;
} 

编译为:

p.foo {
  border-color: blue; } 

它也可以使用#{}插值语句把 SassScript 插入到属性值中。在大多数情况下,这种做可能还不如使用直接变量来的方便,但使用 #{}意味着靠近它的运算符都将被视为纯CSS(手册网注:可以避免各种运算)。 例如:

p {
  $font-size: 12px;
      $line-height: 30px;
  font: #{$font-size}/#{$line-height};
} 

编译为:

p {
  font: 12px/30px; } 

SassScript中的&& in SassScript)

就像当它在选择器中使用一样,SassScript中的&指向当前父选择器。下面是一个逗号分隔的列表(list)中包含一个空格的分隔列表(list)。例如:

.foo.bar .baz.bang, .bip.qux {
  $selector: &;
} 

$selector的值是现在 ((".foo.bar" ".baz.bang"), ".bip.qux")。这个混合选择器在这里加了引号,以表明他们是字符串,但在现实中,他们将不带引号的。即使选择器不包含逗号或空格,&总会有两个嵌套层次,因此它可以保证访问一致性。

如果没有父选择器,&的值将是空。这意味着你可以在一个mixin中使用它来检测父选择是否存在:

@mixin does-parent-exist {
  @if & {
    &:hover {
      color: red;
    }
  } @else {
    a {
      color: red;
    }
  }
} 

变量默认: !default (Variable Defaults: !default

如果分配给变量的值后面添加了!default标志 ,这意味着该变量如果已经赋值,那么它不会被重新赋值,但是,如果它尚未赋值,那么它会被赋予新的给定值。

例如:

$content: "First content";
    $content: "Second content?" !default;
$new_content: "First time reference" !default;

#main {
  content: $content;
      new-content: $new_content;
} 

编译为:

#main {
  content: "First content";
  new-content: "First time reference"; } 

通过!default赋值的时候,如果变量是 null 值时,将视为未赋值(手册网注:所以下面的$content值为 "Non-null content"):

$content: null;
    $content: "Non-null content" !default;

#main {
  content: $content;
} 

编译为:

#main {
  content: "Non-null content"; } 

@规则 和 指令 (@-Rules and Directives)

Sass 支持所有CSS3的 @规则,以及一些已知的其他特定的Sass "指令"。这些在 Sass 都有对应的效果,更多资料请查看 控制指令 (control directives)混入指令 (mixin directives)

@import

Sass 扩展了 CSS @import规则,允许其导入 SCSS 或 Sass 文件。被导入的全部SCSS 或 Sass文件将一起合并到同一个 CSS 文件中。此外,被导入文件中所定义的任何变量或混入(mixins)都可以在主文件(手册网注:主文件值的是导入其他文件的文件,即,A文件中导入了B文件,这里的主文件指的就是A文件)中使用。

Sass 会在当前目录和 Rack, Rails, Merb目录下查找其他 Sass 文件。附加搜索目录可以使用:load_paths选项或命令行中的--load-path选项指定。

通常,@import 寻找 Sass 文件并将其导入,但在以下情况下,@import 仅作为普通的 CSS 语句,不会导入任何 Sass 文件。

@import 需要一个文件名来导入。默认情况下,它会寻找一个 Sass 文件直接导入,但在以下情况下, 仅作为普通的 CSS @import 规则语句,不会导入任何 Sass 文件。

  • 如果文件的扩展名是 .css
  • 如果文件名以 http:// 开始。
  • 如果文件名是 url()
  • 如果@import 中包含任何的媒体查询(media queries)。

如果没有上述条件得到满足并且扩展名是.scss.sass,那么 Sass 或 SCSS 文件将被导入。如果没有指定扩展名,Sass 将尝试找到以.scss.sass为扩展名的该名称文件并导入。

例如,

@import "foo.scss"; 

@import "foo"; 

这两行代码都能导入文件foo.scss,而

@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo); 

将全部编译为

@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo); 

Sass 支持在一个 @import 规则中同时导入多个文件。例如:

@import "rounded-corners", "text-shadow"; 

将同时导入rounded-cornerstext-shadow 这两个文件。

导入规则中可能含有#{} 插值,但存在一定的限制。不能通过变量动态导入Sass文件;#{}插值仅适用于CSS导入规则。 因此,它仅适用于url() 导入。

例如:

$family: unquote("Droid+Sans");
    @import url("http://fonts.googleapis.com/css?family=#{$family}"); 

将编译为

@import url("http://fonts.googleapis.com/css?family=Droid+Sans"); 

Partials

如果你有一个 SCSS 或 Sass 文件要导入,但不希望将其编译到一个CSS文件,你可以在文件名的开头添加一个下划线。这将告诉Sass不要将其编译到一个正常的CSS文件。然后,在导入语句中却不需要添加下划线。

例如,你可能有一个命名为 _colors.scss 的文件,但是不会编译成 _colors.css 文件。你可以这么做

@import "colors"; 

这样, _colors.scss 将被导入。

注意,请不要将带下划线与不带下划线的同名文件放置在同一个目录下,比如,_colors.scsscolors.scss 不能同时存在于同一个目录下。否则带下划线的文件将会被忽略。

嵌套 @import(Nested @import

虽然在大部分情况下,一般都是在文档的顶层(手册网注:最外层,不在嵌套规则内)使用 @import,但是也可以在CSS 规则和@media 规则中包含@import语句。就像一个基层的 @import ,这里会包含 @import 导入文件的内容。但是,这样导入的规则只能嵌套在原先防止 @import 的地方。

举个例子,如果 example.scss 包含

.example {
  color: red;
} 

然后(手册网注:导入到 #main 样式内)

#main {
  @import "example";
} 

手册网注:这样导入后等同于:

#main {
  .example {
      color: red;
    }
} 

将被编译为

#main .example {
  color: red;
} 

该指令只允许出现在文档顶层(手册网注:最外层,不在嵌套规则内),像@mixin 或者 @charset,在文件中,不允许被@import导入到一个嵌套上下文中。

不允许在混人 (mixin) 或控制指令 (control directives) 中嵌套 @import

@media

Sass 中 @media 指令的行为和纯 CSS 中一样,只是增加了一点额外的功能:它们可以嵌套在CSS规则。如果一个@media 指令出现在CSS规则中,它将被冒泡到样式表的顶层,并且包含规则内所有的选择器。这使得很容易地添加特定media样式,而不需要重复使用选择器,或打乱样式表书写流。例如:

.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
  }
} 

编译为:

.sidebar {
  width: 300px; }
  @media screen and (orientation: landscape) {
    .sidebar {
      width: 500px; } } 

@media的查询(queries)也可以相互嵌套。这些查询(queries)在编译时,将会使用 and 操作符号结合。例如:

@media screen {
  .sidebar {
    @media (orientation: landscape) {
      width: 500px;
    }
  }
} 

编译为:

@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px; } } 

@media 甚至可以使用 SassScript(比如变量,函数,以及运算符)代替条件的名称或者值:

最后,@media 查询(queries)可以包含 SassScript 表达式(包括变量 variables,函数 functions 和操作符operators)代替特征名称和特征值。

$media: screen;
    $feature: -webkit-min-device-pixel-ratio;
$value: 1.5;

@media #{$media} and ($feature: $value) {
  .sidebar {
    width: 500px;
  }
} 

编译为:

@media screen and (-webkit-min-device-pixel-ratio: 1.5) {
  .sidebar {
    width: 500px; } } 

@extend

设计一个页面时常常遇到这种情况:当一个样式类(class)含有另一个类的所有样式,并且它自己的特定样式。处理这种最常见的方法是在HTML同时使用一个通用样式类和特殊样式类。例如,假设我们设计需要一个普通错误的样式和一个严重错误的样式。我们可以类似这样写:

<div class="error seriousError">
  Oh no! You've been hacked!
</div> 

我们的样式如下

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
} 

不幸的是,这意味着,我们必须时刻记住使用.seriousError的时候需要搭配使用.error
这对于维护来说是一个负担,甚至导致棘手的错误,并且导致无语意的样式。

@extend 指令避免这些问题,告诉 Sass 一个选择器的样式应该继承另一选择器。 例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
} 

编译为:

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}

.seriousError {
  border-width: 3px;
} 

这意味着.error说定义的所有样式也适用于.seriousError,除了.seriousError的特定样式。相当于,每个带有.seriousError类的元素也带有.error类。

其他使用了.error 规则也会同样继承给.seriousError,例如,如果我们有特殊错误样式的hack:

.error.intrusion {
  background-image: url("/image/hacked.png");
} 

然后<div class="seriousError intrusion">也同样会使用了 hacked.png 背景。

它是如何工作的(How it Works)

@extend通过在样式表中出现被扩展选择器(例如.error)的地方插入扩展选择器(例如.seriousError)。比如上面的例子:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.error.intrusion {
  background-image: url("/image/hacked.png");
}
.seriousError {
  @extend .error;
  border-width: 3px;
} 

编译为:

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd; }

.error.intrusion, .seriousError.intrusion {
  background-image: url("/image/hacked.png"); }

.seriousError {
  border-width: 3px; } 

当合并选择器时,@extend 会很聪明地避免不必要的重复,所以像.seriousError.seriousError 将转换为 .seriousError,此外,她不会生成不能匹配任何元素的选择器(比如 #main#footer )。

扩展复杂的选择器(Extending Complex Selectors)

Class 选择器并不是唯一可以被延伸 (extend) 的,Sass 允许延伸任何定义给单个元素的选择器,比如 .special.cool,a:hover 或者 a.user[href^="http://"] 等,例如:

类(class)选择,并不是唯一可以扩展。她可以扩展任何定义给单个元素的选择器,如.special.cool, a:hover, 或 a.user[href^="http://"]。 例如:

.hoverlink {
  @extend a:hover;
} 

同带 class 元素一样,这意味着,a:hover定义的样式同样也适用于.hoverlink。例如:

.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
} 

编译为:

a:hover, .hoverlink {
  text-decoration: underline; } 

与上面 .error.intrusion 的例子一样, a:hover 中所有的样式将继承给 .hoverlink,甚至包括其他使用到她的样式,例如:

.hoverlink {
  @extend a:hover;
}
.comment a.user:hover {
  font-weight: bold;
} 

编译为:

.comment a.user:hover, .comment .user.hoverlink {
  font-weight: bold; } 

多重扩展 (Multiple Extends)

同一个选择器可以扩展多个选择器。这意味着,它继承了被扩展选择器的所有样式。例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.attention {
  font-size: 3em;
  background-color: #ff0;
}
.seriousError {
  @extend .error;
  @extend .attention;
  border-width: 3px;
} 

编译为:

.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd; }

.attention, .seriousError {
  font-size: 3em;
  background-color: #ff0; }

.seriousError {
  border-width: 3px; } 

每个带.seriousError类的元素也有.error类和.attention类。
因此,定义在文档后面的样式优先级高于定义在文档前面的样式:.seriousError的背景颜色是#ff0,而非#fdd,因为 .attention 是在 .error 后面定义。

多重扩展也可以用逗号分隔的选择器列表(list)写入。例如,@extend .error, .attention等同于@extend .error; @extend .attention

链式扩展(Chaining Extends)

一个选择器可以扩展另一个选择器,另一个选择器又扩展的第三选择器选择。 例如:

.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
.criticalError {
  @extend .seriousError;
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%;
} 

现在,带 .seriousError 类的每个元素将包含 .error 类,而带 .criticalError 类的每个元素不仅包含 .criticalError类也会同时包含 .error 类,上面的代码编译为:

.error, .seriousError, .criticalError {
  border: 1px #f00;
  background-color: #fdd; }

.seriousError, .criticalError {
  border-width: 3px; }

.criticalError {
  position: fixed;
  top: 10%;
  bottom: 10%;
  left: 10%;
  right: 10%; } 

选择器序列 (Selector Sequences)

选择器序列,比如.foo .bar.foo + .bar,目前还不能作为扩展。但是,选择器序列本身可以使用@extend。例如:

#fake-links .link {
  @extend a;
}

a {
  color: blue;
  &:hover {
    text-decoration: underline;
  }
} 

将被编译为:

a, #fake-links .link {
  color: blue; }
  a:hover, #fake-links .link:hover {
    text-decoration: underline; } 
合并选择器序列 (Merging Selector Sequences)

有时,选择器序列扩展另一个选择器,这个选择器出现在另一选择器序列中。在这种情况下,这两个选择器序列需要合并。例如:

#admin .tabbar a {
  font-weight: bold;
}
#demo .overview .fakelink {
  @extend a;
} 

技术上讲能够生成所有匹配条件的结果,但是这样生成的样式表太复杂了,上面这个简单的例子就可能有 10 种结果。所以,Sass 只会编译输出有用的选择器。

当两个列 (sequence) 合并时,如果没有包含相同的选择器,将生成两个新选择器:第一列出现在第二列之前,或者第二列出现在第一列之前。例如:

#admin .tabbar a {
  font-weight: bold;
}
#demo .overview .fakelink {
  @extend a;
} 

编译为:

#admin .tabbar a,
#admin .tabbar #demo .overview .fakelink,
#demo .overview #admin .tabbar .fakelink {
  font-weight: bold; } 

如果两个列 (sequence) 包含了相同的选择器,相同部分将会合并在一起,其他部分交替输出。在下面的例子里,两个列都包含 #admin,输出结果中它们合并在了一起:

#admin .tabbar a {
  font-weight: bold;
}
#admin .overview .fakelink {
  @extend a;
} 

编译为:

#admin .tabbar a,
#admin .tabbar .overview .fakelink,
#admin .overview .tabbar .fakelink {
  font-weight: bold; } 

@extend-Only 选择器 (@extend-Only Selectors)

有时候你只会想写一个 @extend 扩展样式类,不想直接在你的HTML中使用。在写一个 Sass 样式库时,这是特别有用,如果他们需要,在这里你可以提供 @extend 扩展样式给用户,如果他们不需要,直接被忽视。

对于这种情况,如果使用普通的样式类,在你你最终生成的样式表中,会有很多额外(手册网注:无用)的CSS,并且在HTML被使用时,和其他样式类结合的时候容易造成冲突。这就是 Sass 为什么支持"占位选择器"的原因(例如,%foo)。

占位选择器看起来很像普通的 class 和 id 选择器,只是 #. 被替换成了 %。他可以像 class 或者 id 选择器那样使用,而它本身的规则,不会被编译到 CSS 文件中。例如:

// This ruleset won't be rendered on its own.
#context a%extreme {
  color: blue;
  font-weight: bold;
  font-size: 2em;
} 

占位符选择器,就像class和id选择器那样可以用于扩展。扩展选择器,将会编译成CSS,占位符选择器本身不会被编译。例如:

.notice {
  @extend %extreme;
} 

编译为:

#context a.notice {
  color: blue;
  font-weight: bold;
  font-size: 2em; } 

!optional 标记(The !optional Flag)

通常,当你扩展一个选择器的时候,如果说@extend不起作用了,你会收到一个错误提示。
例如,如果没有 .notice 选择器,你这么写a.important {@extend .notice},将会报错。如果只有h1.notice一个选择器包含了.notice,那么也会报错。因为 h1 会与 a 冲突,并且不会生成新的选择器。

然而,有时候,要想@extend不生成任何新的选择器。只是在选择器后添加 !optional标志就可以了。例如:

a.important {
  @extend .notice !optional;
} 

指令中的@extend (@extend in Directives)

在指令中使用 @extend 时(比如在@media 中)存在一些限制:Sass 不可以将 @media 层外的 CSS 规则扩展给指令层内的 CSS,这样会生成大量的无用代码。意思是说,如果在 @media (或者其他 CSS 指令)中使用@extend,必须扩展给相同指令层中的选择器。

下面的例子是可行的:

@media print {
  .error {
    border: 1px #f00;
    background-color: #fdd;
  }
  .seriousError {
    @extend .error;
    border-width: 3px;
  }
} 

但下面这个例子会报错:

.error {
  border: 1px #f00;
  background-color: #fdd;
}

@media print {
  .seriousError {
    // INVALID EXTEND: .error is used outside of the "@media print" directive
    @extend .error;
    border-width: 3px;
  }
} 

希望有一天,浏览器可以原生支持 @extend 指令,这样就可以在@media和其他指令中使用扩展功能了。

@at-root

@at-root指令导致一个或多个规则被限定输出在文档的根层级上,而不是被嵌套在其父选择器下。
它可以被用于单一或内联选择器:

.parent {
  ...
  @at-root .child { ... }
} 

这将生成:

.parent { ... }
.child { ... } 

或者它可以用于包含多个选择器的代码块:

.parent {
  ...
  @at-root {
    .child1 { ... }
    .child2 { ... }
  }
  .step-child { ... }
} 

这将输出如下:

.parent { ... }
.child1 { ... }
.child2 { ... }
.parent .step-child { ... } 

@at-root (without: ...)@at-root (with: ...)@at-root (without: ...) and `@at-root (with: ...))

默认情况下, @at-root只是排除了选择器。然而,它也可以使用@at-root将选择器移动到嵌套指令(比如@media)之外。例如:

@media print {
  .page {
    width: 8in;
    @at-root (without: media) {
      color: red;
    }
  }
} 

生成:

@media print {
  .page {
    width: 8in;
  }
}
.page {
  color: red;
} 

您可以使用@at-root (without: ...) 将规则移动到任何指令之外。你同样可以让多个指令做到这一点,只要多个指令使用空格分隔就可以了:@at-root (without: media supports)会将规则移动到@media@supports查询(queries)之外。

还有有两个特殊值你可以传递给@at-root。"rule"是指正常的CSS规则;@at-root (without: rule)等价于没有查询的@at-root@at-root (without: all) 意思是该样式应该移动到全部的指令和CSS规则之外。

如果你想指定哪个指令或规则包含,而不是哪些应该排除,那么,你可以使用with代替without
例如,@at-root (with: rule)将规则移动到所有指令之外,但在CSS规则内会保留。

@debug

@debug指令打印SassScript表达式的值到标准的错误输出流。这对于调试具有复杂SassScript 表达式的Sass文件非常有用的。 例如:

@debug 10em + 12em; 

输出:

Line 1 DEBUG: 22em 

@warn

@warn指令打印SassScript表达式的值到标准的错误输出流。这对于警告用户弃用库 或 修复 mixin 轻微的错误是非常有用的。@warn@debug之间有两个主要区别:

  1. 您可以使用--quiet命令行选项或:quiet Sass选项关闭警告。
  2. 样式表跟踪将与消息一起被打印出来,这样,用户可以看到他们的样式在哪里引起了警告。

用法示例:

@mixin adjust-location($x, $y) {
  @if unitless($x) {
        @warn "Assuming #{$x} to be in pixels";
        $x: 1px * $x;
      }
      @if unitless($y) {
    @warn "Assuming #{$y} to be in pixels";
        $y: 1px * $y;
      }
      position: relative; left: $x; top: $y;
} 

@error

@error指令抛出一个SassScript表达式的值作为一个致命的错误,其中包括一个不错的堆栈跟踪。这对于验证混入(mixin)和函数的参数很有用。例如:

@mixin adjust-location($x, $y) {
  @if unitless($x) {
        @error "$x may not be unitless, was #{$x}.";
      }
      @if unitless($y) {
    @error "$y may not be unitless, was #{$y}.";
      }
      position: relative; left: $x; top: $y;
} 

目前还没有办法捕获错误。

控制指令和表达式(Control Directives & Expressions)

SassScript支持一些基本控制指令和表达式,比如仅在在某些条件下包含样式,或者包括相同的样式几次变化。

注意: 控制指令是一项高级功能,日常编写过程中并不常用到,主要在 mixins(混合)指令中使用,尤其是像Compass这样的库。

if()

内置的if()函数可让您在一个条件处理分支并返回两种可能结果。它可以在任何脚本上下文中使用。if函数只判断相对应的一个参数并且返回 -- 这使您可以引用已经定义的或者可以计算的变量,否则将导致错误(例如,除以零)。

if(true, 1px, 2px) => 1px
if(false, 1px, 2px) => 2px 

@if

@if 指令需要一个SassScript表达和嵌套在它下面要使用的样式,如果表达式返回值不为 false 或者 null ,那么后面花括号中的内容就会返回:

p {
  @if 1 + 1 == 2 { border: 1px solid;  }
  @if 5 < 3      { border: 2px dotted; }
  @if null       { border: 3px double; }
} 

编译为:

p {
  border: 1px solid; } 

@if 语句后面可以跟多个@else if语句和一个 @else 语句。
 如果@if语句失败,Sass 将逐条尝试@else if 语句,直到有一个成功,或如果全部失败,那么会执行@else语句。 例如:

$type: monster;
    p {
      @if $type == ocean {
        color: blue;
      } @else if $type == matador {
        color: red;
      } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
} 

编译为:

p {
  color: green; } 

@for

@for指令重复输出一组样式。对于每次重复,计数器变量用于调整输出结果。该指令有两种形式:@for $var from <start> through <end>@for $var from <start> to <end>。注意关键字throughto的区别。$var可以是任何变量名,比如$i;<start><end>是应该返回整数的SassScript表达式。当<start><end>大的时候,计数器将递减,而不是增量。

@for语句将设置$var为指定的范围内每个连续的数值,并且每一次输出的嵌套样式中使用$var的值。对于from ... through的形式,范围包括<start><end>的值,但from ... to的形式从<start>开始运行,但不包括<end>的值。使用through语法,

@for $i from 1 through 3 {
      .item-#{$i} { width: 2em * $i; }
} 

编译为:

.item-1 {
  width: 2em; }
.item-2 {
  width: 4em; }
.item-3 {
  width: 6em; } 

@each

@each指令通常格式是@each $var in <list or map>$var可以是任何变量名,像$length 或者 $name,和<list or map>是一个返回列表(list)或 map 的 SassScript 表达式。

@each 规则将$var设置为列表(list)或 map 中的每个项目,输出样式中包含使用$var的值。 例如:

@each $animal in puma, sea-slug, egret, salamander {
      .#{$animal}-icon {
        background-image: url('/images/#{$animal}.png');
  }
} 

编译为:

.puma-icon {
  background-image: url('/images/puma.png'); }
.sea-slug-icon {
  background-image: url('/images/sea-slug.png'); }
.egret-icon {
  background-image: url('/images/egret.png'); }
.salamander-icon {
  background-image: url('/images/salamander.png'); } 

多重赋值(Multiple Assignment)

@each指令也可以使用多个变量,格式为@each $var1,$var2, ... in <list>。如果<list>是列表(list)中的列表,子列表中的每个元素被分配给各自的变量。例如:

@each $animal, $color, $cursor in (puma, black, default),
                                      (sea-slug, blue, pointer),
                                      (egret, white, move) {
      .#{$animal}-icon {
        background-image: url('/images/#{$animal}.png');
        border: 2px solid $color;
        cursor: $cursor;
  }
} 

编译为:

.puma-icon {
  background-image: url('/images/puma.png');
  border: 2px solid black;
  cursor: default; }
.sea-slug-icon {
  background-image: url('/images/sea-slug.png');
  border: 2px solid blue;
  cursor: pointer; }
.egret-icon {
  background-image: url('/images/egret.png');
  border: 2px solid white;
  cursor: move; } 

因为maps被视为键值对的列表,所以多重赋值也可以很好的工作。例如:

@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
        font-size: $size;
  }
} 

编译为:

h1 {
  font-size: 2em; }
h2 {
  font-size: 1.5em; }
h3 {
  font-size: 1.2em; } 

@while

@while 指令重复输出嵌套样式,直到SassScript表达式返回结果为false。这可用于实现比@for语句更复杂的循环,只是很少会用到例如:

$i: 6;
    @while $i > 0 {
  .item-#{$i} { width: 2em * $i; }
      $i: $i - 2;
} 

编译为:

.item-6 {
  width: 12em; }

.item-4 {
  width: 8em; }

.item-2 {
  width: 4em; } 

混入指令 (Mixin Directives)

混入(mixin)允许您定义可以在整个样式表中重复使用的样式,而避免了使用无语意的类(class),比如 .float-left。混入(mixin)还可以包含所有的CSS规则,以及任何其他在Sass文档中被允许使用的东西。
他们甚至可以带arguments,引入变量,只需少量的混入(mixin)代码就能输出多样化的样式。

定义一个混入(mixin):@mixin(Defining a Mixin: @mixin

混入(mixin)通过 @mixin 指令定义。在它后面跟混入的名称和任选的arguments(参数),以及混入的内容块。例如,large-text混入定义如下:

@mixin large-text {
  font: {
    family: Arial;
    size: 20px;
    weight: bold;
  }
  color: #ff0000;
} 

混入也可以包含选择器和属性的混合体,选择器中甚至可以包含parent references(父选择器)。 例如:

@mixin clearfix {
  display: inline-block;
  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }
  * html & { height: 1px }
} 

由于历史原因,混入(mixin)的名字(和所有其他 Sass 标识符)可以互换连字符和下划线。例如,如果你定义了一个名为add-column的混入,你可以把它作为add_column,反之亦然。

引用混合样式:@include (Including a Mixin: @include

使用 @include 指令可以将混入(mixin)引入到文档中。这需要一个混入的名称和可选的参数传递给它,并包括由混入定义的当前规则的样式。 例如:

.page-title {
  @include large-text;
  padding: 4px;
  margin-top: 10px;
} 

编译为:

.page-title {
  font-family: Arial;
  font-size: 20px;
  font-weight: bold;
  color: #ff0000;
  padding: 4px;
  margin-top: 10px; } 

混入(mixin)也可以包含在任何规则的外(即,在文档的根),只要它们不直接定义的任何属性或使用任何父选择器引用。例如:

@mixin silly-links {
  a {
    color: blue;
    background-color: red;
  }
}

@include silly-links; 

编译为:

a {
  color: blue;
  background-color: red; } 

混入(mixin)定义也可以包含其他的混入。例如:

@mixin compound {
  @include highlighted-background;
  @include header-text;
}

@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; } 

混入可以包含自己。这行为不同于 Sass 3.3 之前的版本,以前混入递归是被禁止的。

只定义后代选择器的混入可以安全地混入到文件的最顶层。

参数 (Arguments)

混入(mixin)可以用 SassScript 值作为参数,给定的参数被包括在混入(mixin)中并且作为为变量提供给混入(mixin)。

当定义一个混入(mixin)的时候,参数被作为变量名,写到混入(mixin)名字后面的括号内,多个参数可以用逗号分隔。然后,当调用混入的时候,值通过对应的参数顺序被传递。 例如:

@mixin sexy-border($color, $width) {
  border: {
    color: $color;
        width: $width;
    style: dashed;
  }
}

p { @include sexy-border(blue, 1in); } 

编译为:

p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed; } 

混入(mixin)也可以使用普通的变量赋值语法为参数指定默认值。然后,当调用混入的时候,如果没有给参数赋值,则自动会使用默认值代替。 例如:

@mixin sexy-border($color, $width: 1in) {
  border: {
    color: $color;
        width: $width;
    style: dashed;
  }
}
p { @include sexy-border(blue); }
h1 { @include sexy-border(blue, 2in); } 

编译为:

p {
  border-color: blue;
  border-width: 1in;
  border-style: dashed; }

h1 {
  border-color: blue;
  border-width: 2in;
  border-style: dashed; } 

关键字参数 (Keyword Arguments)

混入(mixin)在引入(@include指令)的时候也可以使用明确的关键字参数。例如,上面的例子可以写成:

p { @include sexy-border($color: blue); }
    h1 { @include sexy-border($color: blue, $width: 2in); } 

虽然这是不够简明,但是它可以使样式表更容易阅读。它给函数呈现了更加灵活的接口,它使多参数的混入更加容易调用。

命名的参数可以按任何顺序进行传递,有默认值的参数可以省略。由于命名参数是变量名,下划线和连字符可以互换使用。

可变参数 (Variable Arguments)

有时,不能确定一个混入(mixin)或者一个函数(function)使用多少个参数。例如,用于创建盒子阴影(box-shadow)的一个混入(mixin)可以采取任何数量的box-shadow作为参数。对于这些情况,Sass支持"可变参数",参数在声明混入(mixin)或函数(function)结束的地方,所有剩余的参数打包成一个列表(list)。参数看起来就像普通参数一样,但后面跟随着...。例如:

@mixin box-shadow($shadows...) {
      -moz-box-shadow: $shadows;
      -webkit-box-shadow: $shadows;
      box-shadow: $shadows;
}

.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
} 

编译为:

.shadows {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
} 

可变参数可以包含任何关键字参数传递给混入(mixin)或者函数(function)。这些可以使用keywords($args)函数 来访问,返回一个map,参数名称字符串(无$)和值的键值对。

可变参数,也可以在调用(@include指令)一个混入(mixin)时使用。使用相同的语法,你可以扩展值的列表(list),以便每个值作为单独的参数传入,或扩展值的map,以使每个键值对作为一个关键字参数处理。例如:

@mixin colors($text, $background, $border) {
      color: $text;
      background-color: $background;
      border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;
    .primary {
      @include colors($values...);
}

$value-map: (text: #00ff00, background: #0000ff, border: #ff0000);
    .secondary {
      @include colors($value-map...);
} 

编译为:

.primary {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}

.secondary {
  color: #00ff00;
  background-color: #0000ff;
  border-color: #ff0000;
} 

你可以同时传递一个列表(list)和一个map参数,只要列表(list)在map上之前,比如@include colors($values..., $map...)

您可以使用可变参数来包装一个混入(mixin)并且添加额外的样式,而不改变混入(mixin)的参数签名。如果你这样做,关键字参数将通过包装的混入(mixin)直接传递。例如:

@mixin wrapped-stylish-mixin($args...) {
      font-weight: bold;
      @include stylish-mixin($args...);
}

.stylish {
  // The $width argument will get passed on to "stylish-mixin" as a keyword
      @include wrapped-stylish-mixin(#00ff00, $width: 100px);
} 

传递内容块到混入(Passing Content Blocks to a Mixin)

样式内容块可以传递到混入(mixin)包含样式的位置。样式内容块将出现在混入内的任何 @content 指令的位置。这使得可以定义抽象 关联到选择器和指令的解析。

例如:

@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}
@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
} 

生成:

* html #logo {
  background-image: url(/logo.gif);
} 

同样的混入(mixin)可以在.sass 简写语法(@mixin 可以用 = 表示,而 @include 可以用 + 表示)来完成:

=apply-to-ie6-only
  * html
    @content

+apply-to-ie6-only
  #logo
    background-image: url(/logo.gif) 

注意:@content指令指定多次或在一个循环中指定的时候,样式块将在每次调用中被复制并引用。

变量的作用域和内容块(Variable Scope and Content Blocks)

传递给混入(mixin)的内容块在其被定义的作用域中进行运算,而不是混入(mixin)的作用域。这意味着混入(mixin)的局部变量不能传递给样式块使用,并且变量将解析为全局值:

$color: white;
    @mixin colors($color: blue) {
  background-color: $color;
      @content;
      border-color: $color;
}
.colors {
  @include colors { color: $color; }
} 

编译为:

.colors {
  background-color: blue;
  color: white;
  border-color: blue;
} 

另外,这清楚地表明,变量和传递到块中使用的混入,指向块定义的周围其他样式。例如:

#sidebar {
  $sidebar-width: 300px;
      width: $sidebar-width;
  @include smartphone {
    width: $sidebar-width / 3;
  }
} 

函数指令 (Function Directives)

Sass 支持自定义函数,并能在任何值或脚本上下文中使用。例如

$grid-width: 40px;
    $gutter-width: 10px;

@function grid-width($n) {
      @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar { width: grid-width(5); } 

就变成了:

#sidebar {
  width: 240px; } 

正如你看到的,函数可以访问任何全局定义的变量,以及接受参数,就像一个混入(mixin)。函数可以包含语句,并且你必须调用@return来设置函数的返回值。

与混入(mixin)一样,你可以使用关键字参数来调用Sass定义的函数。在上面的例子中,我们可以这样调用函数:

#sidebar { width: grid-width($n: 5); } 

建议您在函数前加上前缀,以避免命名冲突,其他人阅读样式表的时候也会知道它们不是 Sass 或者 CSS 的自带功能。例如,如果您在ACME公司工作,你可以给上面的函数取名为-acme-grid-width

用户自定义的函数也支持可变参数,方式和混入(mixin)是相同的。

由于历史的原因,函数名(和所有其他Sass标识符)中连字符和下划线可以互换。例如,如果你定义了一个名为grid-width的函数,你可以通过grid_width调用它,反之亦然。

输出格式 (Output Style)

虽然Sass 默认的 CSS 输出格式非常好,并且能反映文档的结构,但是由于每个人的喜好和需求各不相同,因此Sass 支持其他几种格式。

Sass 提供了四种输出格式,可以通过:style 选项 选项设定,或者在命令行中使用 --style 选项。

Sass 允许您通过设置:style 选项 或使用 --style 命令行标志,在四种不同的输出格式之间进行选择。

:nested

nested(嵌套)格式是 Sass 默认的输出格式,因为它的格式反映CSS样式与HTML文档结构。每个属性都独占用一行,但缩排不是固定的。每个规则是基于它的何嵌套深度缩进。例如:

#main {
  color: #fff;
  background-color: #000; }
  #main p {
    width: 10em; }

.huge {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline; } 

当阅读大型 CSS 文件时,nested(嵌套)格式是非常有用的:不用详细阅读,就可以让你轻松掌握文件的结构。

:expanded

expanded(扩展)格式更像是手写的CSS样式,每个属性和规则都独占用一行。在规则之内的属性缩进的,但规则没有任何特殊的缩进。例如:

#main {
  color: #fff;
  background-color: #000;
}
#main p {
  width: 10em;
}

.huge {
  font-size: 10em;
  font-weight: bold;
  text-decoration: underline;
} 

:compact

compact(紧凑)格式比起nested(嵌套)或expanded(扩展)格式占据更小的空间。这种格式重点聚焦在选择器上,不是它们的属性。每个CSS规则独占用一行,该行还包括定义的每个属性。嵌套的规则都是另起一行,不嵌套的选择器会输出空白行作为分隔符。 例如:

#main { color: #fff; background-color: #000; }
#main p { width: 10em; }

.huge { font-size: 10em; font-weight: bold; text-decoration: underline; } 

:compressed

compressed(压缩)格式占用尽可能小的空间,在该文件的末尾会有一个换行,并且除了必要的分隔选择器之外,基本没有多余空格,它还包括其他一些小的压缩,比如选择颜色最小的表示方式。这意味着可读性很差。 例如:

#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline} 

扩展 Sass (Extending Sass)

对于独特的需求,Sass为用户提供了多项高级定制功能。使用这些功能需要对Ruby有深刻的理解。

自定义 Sass 函数 (Defining Custom Sass Functions)

用户通过 Ruby API 可以自定义 Sass 函数,更多信息请查看 源代码文档

缓存存储(Cache Stores)

Sass会缓存已经解析的文档,这使得它们可以重复使用,而无需再次解析,除非他们已经被更改。 默认情况下,Sass会将这些缓存文件写到 :cache_location指定的文件系统中。如果你不能写入文件系统或者需要ruby进程或计算机共享缓存,那么你可以定义自己的缓存存储,并设置:cache_store选项。有关创建自定义缓存存储的详细信息,请查看源代码文档

自定义导入 (Custom Importers)

Sass导入主要负责获取路径传递给@import并找到这些路径相应的Sass代码。默认情况下,这些代码是从文件系统中加载,但是Importers可以从数据库加载,通过HTTP,或者使用不同的文件命名方案,被添加到Sass。

每个importer负责一个单独的加载路径(或任何相应的后端概念)。importer可以和普通的文件系统路径一起放置在:load_paths数组中。

当解析一个@import的时候,Sass将通过加载路径寻找importer来成功地导入路径。一旦被发现,该导入的文件就会被使用。

用户创建的导入必须继承自 Sass::Importers::Base