Sass/Scss 学习总结(三) 之 变量学习

如果有过其它语言的学习,比如PHP、Javscript等等,对变量一定不会陌生,SASS 除了普通的 CSS 属性语法,也支持一些扩展,名为 SassScript。SassScript允许属性使用变量,算术和额外功能,SassScript可以在任何属性值被使用。


变量

Scss 的变量是以 $ 开头,后面紧跟变量名,而变量值和变量名之间就需要使用冒号(:)分隔开,如:

// 定义一个变量 $width,并赋值 15px
// -----------------------------------------

$width: 15px;

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

#main {
    width: $width;
}

另外,Sass 支持两种类型变量:局部变量和全局变量;默认情况之下,所有定义在任何选择器之外的变量被认为是全局变量。这意味着他们可以在样式表中任意地方被访问。例如,这里有一个全局变量:

// body.scss 文件
// -------------------------------

$fontSize:      12px; // 定义一个全局变量
body {
    font-size:$fontSize;
}
p {
    font-size:$fontSize;
}

// 编译后的 body.css 文件
// -------------------------------

body {
  font-size: 12px; }

p {
  font-size: 12px; }

定义在选择器内的变量称为局部变量,局部变量只能在当前选择器内使用。另外,在变量后带上 !global 标志,说明这个变量是全局变量,在任何地方都可见。如:

// 定义一个全局变量 
$width: 5em;

#main {
	
    // 定义一个局部变量, 这个变量不能在 #main 外使用
    $fontSize: 12px;

    // 在局部定义一个全局变量,在任何地方都可以使用
    $color: red !global;

    width: $width;
    font-size: $fontSize;
    color: $color;
}

p {
    width: $width;
    color: $color;
}

由于历史原因,变量名可以互换连字符和下划线。例如,如果你定义了一个名为 $main-width,您可以使用 $main_width 访问它,反之亦然。


默认变量

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

// sass style
//-------------------------------
$baseLineHeight:        2;
$baseLineHeight:        1.5 !default;
body {
    line-height: $baseLineHeight; 
}

// 编译后的 css style
// -------------------------------
body {
    line-height: 2;
}

可以看出现在编译后的 line-height 为 2,而不是我们默认的 1.5。默认变量的价值在进行组件化开发的时候会非常有用。


插值变量

一般我们定义的变量都为属性值,可直接使用,但是如果变量作为属性或在某些特殊情况下则必须要以 #{$variables} 形式使用。

// scss style
// -------------------------------

$borderDirection:       top !default; 
$baseFontSize:          12px !default;
$baseLineHeight:        1.5 !default;

// 应用于 class 和属性
.border-#{$borderDirection} {
    border-#{$borderDirection}: 1px solid #ccc;
}

// 应用于复杂的属性值
body {
    font:#{$baseFontSize}/#{$baseLineHeight};
}


// 编译后的 css style
// -------------------------------

.border-top {
    border-top:1px solid #ccc;
}
body {
    font: 12px/1.5;
}


数据类型(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文档中使用的字符串类型。

有一个例外,当使用 #{} 时,带引号的字符串将被编译为不带引号的字符串,这样主要是为了便于使用,如:

// scss style
// -------------------------------

$borderDirection:  "top";

#main {
    border-#{$borderDirection}: 1px solid #ccc;
}


// 编译成了 CSS 文件为
// -------------------------------

#main {
    border-top: 1px solid #ccc; 
}


列表(Lists)

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

列表本身没有太多的功能,但 Sass 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 中却是不同的:第一个是含两个列表的列表,而第二个是含有四个成员的列表。

列表也可以没有任何项。这些列表可以用 () 表示(也是一个空的 map)。空数组不可以直接编译成 CSS,比如编译 font-family: () Sass 将会报错。如果数组中包含空数组或空值,编译时将被清除,比如 1px 2px () 3px 或 1px 2px null 3px。

逗号分隔的列表可以保留结尾的逗号。这是特别有用,因为它可以表示一个 单个元素的列表。 

例如,(1,)表示为只包含1的列表,而(1 2 3,)这个表示包含一个列表,这个列表又包含以空格分隔的1, 2 和 3的列表。

// 定义一个列表
$px: 5px 10px 15px 20px;

#main {
margin-top:nth($px, 1);
margin-right: nth($px, 2);
margin-bottom: nth($px, 3);
margin-left: nth($px, 4);
}

// 编译后的 CSS 文件

#main {
    margin-top: 5px;
    margin-right: 10px;
    margin-bottom: 15px;
    margin-left: 20px; 
}

列表合并

$px1: 5px 10px 15px;
$px2: 1px 2px 3px;

$px: join($px1, $px2); // 5px 10px 15px 1px 2px 3px

添加新值

$px: 5px 10px 15px 20px;
$px: append($px, 11px); // 将 11px 添加到 $px 中

更多函数,请参考:http://sass-lang.com/documentation/Sass/Script/Functions.html


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 非常有用。


使用

// scss style
// -------------------------------

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


// css style
// -------------------------------

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


运算符

数字运算

SassScript 支持对数字标准的算术运算(+、-、*、/、%)。Sass 数学函数在算术运算期间会保留单位。这意味着,不能使用不相同的单位做操作(如:1px + 2em = ??? ),也不能使用相同单位做乘法(1px * 10px == ?? , 因为 px * px == 无效)。

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


除法(/)

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

p { font:italic bold 12px/20px arial,sans-serif; }

由于SassScript是CSS属性语法的扩展,所以它必须支持这一点,同时还允许 / 用于除法。但是,什么时候是做除法,什么时候是 CSS 中的 / 呢?

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

  1. 如果该值,或值的任何部分,存储在一个变量中或通过函数返回。

  2. 如果该值是由括号括起来的,除非这些括号是在一个列表(list)外部,并且值是括号内部。

  3. 如果该值被用作另一个算术表达式的一部分。

$width: 1000px;

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

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

// scss style
// -------------------------------

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

// 编译后的 CSS 文件
// -------------------------------

p {
    font: 12px/30px; 
}


减法,负数(-)

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

  • 减法的时候,你总是在 - 两侧保留空格。

  • 当表示一个负数或一元负运算时候,在-前面包含一个空格,后面不加空格。

  • 如果在一个空格隔开的list(列表)中,你可以将一元负运算使用括号括起来,比如在 (-$var)中。

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

  1. 作为标识符的一部分。这意味着a-1是一个不带引号的字符串,其值为"a-1"。唯一的例外是带单位的情况,如 5px - 3px 将做为减法,因为标识符不可能以数字或连字符开始;

  2. 在不带空格两个数字之间。这表明是减法,如是 1-2;

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

  4. 存在着变量,不论是否带空格。这表明是减法,所以 1 - $var;

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


颜色运算

所有算术运算都支持的颜色值,颜色值的运算是分段进行计算的,也就是,依次计算红(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通道(那些由 rgba hsla 函数创建的)的颜色必须具有相同的alpha值,才能进行颜色运算。这样算术不会影响 alpha 值。例如:

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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


字符串运算

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

// SCSS 文件
// ---------------------

p {
  cursor: e + -resize;
}

// 编译后的 CSS 样式
// ---------------------

p {
  cursor: e-resize; }

请注意,如果带引号的字符串被添加到不带引号的字符串中(也就是说,带引号的字符串在 + 的左侧), 

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

p {
    margin: 7px auto; 
}

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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

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

// SCSS 文件
// ---------------------

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

// 编译后的 CSS 样式
// ---------------------

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


布尔运算

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


未经允许不得转载:易读小屋  »  Sass/Scss 学习总结(三) 之 变量学习