css预编译语言 sass scss(变量$var, css嵌套规则,@import规则,@extend,@mixin)

时间:2022-06-07 08:21:59

什么是sass

Sass 是对 CSS 的扩展,让 CSS 语言更强大、优雅。 它允许你使用变量、嵌套规则、 mixins、导入等众多功能, 并且完全兼容 CSS 语法。 Sass 有助于保持大型样式表结构良好, 同时也让你能够快速开始小型项目, 特别是在搭配 Compass 样式库一同使用时

【特点】

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

scss && sass

Sass 有两种语法。 第一种被称为 SCSS (Sassy CSS),是一个 CSS3 语法的扩充版本。 也就是说,所有符合 CSS3 语法的样式表也都是具有相同语法意义的 SCSS 文件。 另外,SCSS 理解大多数 CSS hacks 以及浏览器专属语法,例如IE古老的 filter 语法。 这种语种语法的样式表文件需要以 .scss 扩展名。

第二种比较老的语法成为缩排语法(或者就称为 "Sass"), 提供了一种更简洁的 CSS 书写方式。

任一语法都可以导入另一种语法撰写的文件中。 只要使用 sass-convert 命令行工具

[注意]本文使用scss语法

缓存

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

基础规则

【注释】

/* 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; }

使用插值语句的注释

$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. */

【嵌套规则】

Sass 允许将一个 CSS 样式嵌套进另一个样式中,内层样式仅适用于外层样式的选择器范围内

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

【引用父选择器 &】

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

[注意] & 等于 a 即父元素

【属性嵌套】

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;
}

SassScript

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

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

【变量】

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

$width: 5em;
#main {
width: $width;
} 编译为:
#main {
width: 5em;
}

数据类型

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))

【字符串】

CSS指定两种字符串类型:带引号的字符串("Lucida Grande"),还有不带引号的字符串(sans-serif)SassScript 识别这两种类型,并且一般来说,在编译输出的CSS文件中不会改变Sass文档中使用的字符串类型。

[例外]当使用 #{} 时,带引号的字符串将被编译为不带引号的字符串

@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
} @include firefox-message(".header"); 编译后: body.firefox .header:before {
content: "Hi, Firefox users!";
} ".header" 最终被编译为 .header

【列表】

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

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

【Maps】

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

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

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

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

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

运算

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

【数字运算】

SassScript 支持对数字标准的算术运算(加法+,减法 - ,乘法*,除法/和取模%)。Sass 数学函数在算术运算期间会保留单位。这意味着,就像在现实生活中,你不能用不相同的单位数字进行算术运算(比如数字后面添加了px和em单位)

【除法和 /】

CSS允许 / 出现在属性值之间作为分隔数字的方式,如下代码

p.ex2{font:italic bold 12px/20px arial,sans-serif;})
12px/20px 是 font-size/line-height的简写形式

SassScript在以下几种情况下会进行除法运算

  • 使用了变量
  • 使用了函数
  • 使用了括号
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)中,括号可以被忽略。
}

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

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

【减法,负数,和 -】

在CSS和在Sass中 - 有许多不同的意义。它可以是一个减法运算符(比如在5px - 3px中)

也可以表示一个负数(比如在-3px中)

还可以是一个一元负运算符(比如在-$var中)

或是标识符的一部分(比如在font-weight中)

那么如何使用 - 呢?

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

【颜色运算】

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

p {
color: #010203 + #040506; // 计算 01 + 04 = 05, 02 + 05 = 07, 和 03 + 06 = 09,并且编译为:
} 编译后
p {
color: #050709;
}

【opacify和transparentize函数】

调整颜色的alpha通道可以使用

$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); // 0.5 + 0.3
background-color: rgba(255, 0, 0, 0.25);// 直接使用0.25替代了0.5
}

【字符串运算】

运算可用于连接字符串

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 {
width: 1em + (2em * 3);
} 编译后:
p {
width: 7em;
}

插值

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

使用插值来避免运算

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

SassScript中的 &

就像当它在选择器中使用一样,SassScript中的&指向当前父选择器。

.foo{
&:hover{
color:red;
}
} 编译后:
.foo:hover {
color: red;
}

变量默认

如果分配给变量的值后面添加了!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";
}

规则

Sass 支持所有CSS3的 @ 规则,以及一些已知的其他特定的Sass "指令"。

【@import】

Sass 扩展了 CSS @import规则,允许其导入 SCSS 或 Sass 文件。被导入的全部SCSS 或 Sass文件将一起合并到同一个 CSS 文件中。此外,被导入文件中所定义的任何变量或混入(mixins)都可以在主文件

可以正确导入scss或sass文件
@import "foo.scss";
@import "foo"; 不能正确导入的形式
@import "foo.css";
@import "foo" screen;
@import "http://foo.com/bar";
@import url(foo);

@import支持导入多个文件语句

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

@import用在嵌套

example.scss 包含
.example {
color: red;
} 如此引入:
#main {
@import "example";
} 等同于
#main {
.example {
color: red;
}
} 编译后
#main .example {
color: red;
}

[注意1]该指令只允许出现在文档顶层(注:最外层,不在嵌套规则内)

[注意2]不允许在 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;
}
}

@extend

继承另一个样式

.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类。

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

.hoverlink {
@extend a:hover;
}
a:hover {
text-decoration: underline;
} 编译后:
a:hover, .hoverlink {
text-decoration: underline;
}

警告指令

【@debug】

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

@debug 10em + 12em;

输出:Line 1 DEBUG: 22em

【@warn】

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

使用示例

@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;
}

控制指令和表达式

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

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

【@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 through

@for $var from to

@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 。$var可以是任何变量名,像$length 或者 $name,和是一个返回列表(list)或 map 的 SassScript 表达式。

@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');
}

【遍历Map】

@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;
}

Mixin

混入(mixin)允许您定义可以在整个样式表中重复使用的样式,而避免了使用无语意的类(class),比如 .float-left。混入(mixin)还可以包含所有的CSS规则,以及任何其他在Sass文档中被允许使用的东西。

他们甚至可以带arguments,引入变量,只需少量的混入(mixin)代码就能输出多样化的样式。

【定义一个Mixin】

@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
} @mixin clearfix {
display: inline-block;
&:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
* html & { height: 1px }
}

【引用混合指令@include】

.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 sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
} p { @include sexy-border(blue, 100px); } 编译后:
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}

【参数设置默认值】

@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;
}

【可变参数】

有时,不能确定一个混入(mixin)或者一个函数(function)使用多少个参数。例如,用于创建盒子阴影(box-shadow)的一个混入(mixin)可以采取任何数量的box-shadow作为参数。

@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;
}

【参数结合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;
}

【mixin传递内容块】

@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)的内容块在其被定义的作用域中进行运算,而不是混入(mixin)的作用域。

$color: white;
@mixin colors($color: blue) {
background-color: $color;
@content;
border-color: $color;
}
.colors {
@include colors { color: $color; }
} 编译后:
.colors {
background-color: blue; // 引用的mixin的变量值
color: white; // 这里引用的是全局的变量
border-color: blue;// 引用的mixin的变量值
}

函数指令

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;
}

调用方式

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

输出格式

虽然Sass 默认的 CSS 输出格式非常好,并且能反映文档的结构,但是由于每个人的喜好和需求各不相同,因此Sass 支持其他几种格式。Sass 允许您通过设置:style 选项 或使用 --style 命令行标志,在四种不同的输出格式之间进行选择。

【:nested】

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

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

【:expanded】

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

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

【:compact】

compact(紧凑)格式比起nested(嵌套)或expanded(扩展)格式占据更小的空间。这种格式重点聚焦在选择器上,不是它们的属性。

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

【:compressed】

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

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

小结

本文内容全部来自sass文档,通过查阅一遍文档,基本上能掌握sass的一些常用用法。