sass

116 阅读5分钟

sass

变量声明

  • $标识变量
$theme: red;
  • 变量作用域

具有块级作用域{}

a {
    $width: 100px;   
}
​
div {
    width: $width;
}
​
// Undefined variable.
  • 变量采用中划线连字符
$theme-color: red;

sassscript

  • 在 CSS 属性的基础上 Sass 提供了一些名为 SassScript 的新功能。 SassScript 可作用于任何属性,允许属性使用变量、算数运算等额外功能。
$theme-color: red; // 变量
$width: 1 + 1px;  // + - * / %
$width: 2 * 1px;
$width: 2 - 1px;
$width: 2 / 1px;

数据类型

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

  • 数字,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, 相当于 JavaScript 的 object,(key1: value1, key2: value2)

字符串

  • 两种字符串类型

    • 有引号字符串"100px url("https://***.png")"
    • 无引号字符串 "sans-serif bold" 字体
  • #{} 标识符,字符串拼接.,相当于字符串模板

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

数组

  • 是一种概念
margin: 10px 15px 0 0; // [10px, 15px, 0, 0]
font-face: Helvetica, Arial, sans-serif; // [Helvetica, Arial, sans-serif]
  • nth 函数可以直接访问数组中的某一项;
  • join 函数可以将多个数组连接在一起;
  • append 函数可以在数组中添加新值;
  • @each 指令能够遍历数组中的每一项。

运算

  • 所有数据类型均支持相等运算 ==!=,此外,每种数据类型也有其各自支持的运算方式。
  • 支持数字的加减乘除、取整等运算 (+, -, *, /, %),如果必要会在不同单位间转换值
$width: 1000px;
​
p {
  font: 10px/8px;             // Plain CSS, no division
  width: $width/2;            // Uses a variable, does division
  width: round(1.5)/2;        // Uses a function, does division
  height: (500px/2);          // Uses parentheses, does division
  margin-left: 5px + 8px/2px; // Uses +, does division
}
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;
}

颜色值运算

p {
  color: #010203 + #040506;
}

// 计算 01 + 04 = 05 02 + 05 = 07 03 + 06 = 09,然后编译为
p {
  color: #050709;
}
p {
  color: #010203 * 2;
}
p {
  color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}
  • opacify
$translucent-red: rgba(255, 0, 0, 0.5);
p {
  color: opacify($translucent-red, 0.3);
  background-color: transparentize($translucent-red, 0.25);
}

/**  compiler **/
p {
  color: rgba(255, 0, 0, 0.8);
  background-color: rgba(255, 0, 0, 0.25);
}
  • 其他滤镜功能
$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);
}

字符串运算

  • + 可用于连接字符串
  • 运算表达式与其他值连用时,用空格做连接符
p {
  cursor: e + -resize;
  w
}
a {
    cursor: "e" + -resize;
}
/** compiler **/
p {
  cursor: e-resize;
}
a {
  cursor: "e-resize";
}
  • 注意,如果有引号字符串(位于 + 左侧)连接无引号字符串,运算结果是有引号的,相反
  • 无引号字符串(位于 + 左侧)连接有引号字符串,运算结果则没有引号。
p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}
p:before {
  content: "Foo Bar";
  font-family: sans-serif;
}
  • #{} 插值语句,字符串模板
  • 普通字符
p:before {
  content: "I ate #{5 + 10} pies!";
}
/** compiler **/
p:before {
  content: "I ate #{5 + 10} pies!";
}
  • 变量字符串
$value: 10;
p:before {
  content: "I ate #{$value} pies!";
}

/** compiler **/
p:before {
  content: "I ate 10 pies!";
}
  • 空的值被视作插入了空字符串
$value: null;
/**  compiler **/
$value: '';

布尔运算

and
or
not
运算

数组运算

  • 数组不支持任何运算方式,只能使用 list functions 控制。

圆括号

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

/** compiler  **/
p {
  width: 7em;
}

函数

  • 查看函数

&标识符

  • &父选择器标识符
nav {
    &:hover {
        color: red;
    }
}

/** compiler **/
nav:hover {
  color: red;
}
#content aside {
    color: red;
    body.ie & { color: green }
}

/** compiler **/
#content aside {
  color: red;
}
body.ie #content aside {
  color: green;
}

群组选择器

  • , + > ~选择都支持
  • 属性嵌套,类型嵌套
body, article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  }
  nav + & { margin-top: 0 }
}

/** compiler **/
body ~ article, article ~ article {
  border-top: 1px dashed #ccc;
}
body > section, article > section {
  background: #eee;
}
body dl > dt, article dl > dt {
  color: #333;
}
body dl > dd, article dl > dd {
  color: #555;
}
nav + body, nav + article {
  margin-top: 0;
}

sass导入

  • 省略后缀*.scss,*.sass
  • *.css更改*.scss
@import "colors";
@import "mixins";
@import "var";
@import url(foo);
@import "colors", "mixins"; // 导入多个文件
$family: unquote("Droid+Sans");

插值导入

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

嵌套导入

  • 垮级引用
  • 不可以在混合指令 (mixin) 或控制指令 (control directives) 中嵌套 。@import
// base.scss
.mt-10 {
    margin-top: 10px;
}
.mb-10 {
    margin-bottom: 10px;
}
body {
    @import "base"; // 导入
}

/** compiler **/
body .mt-10 {
  margin-top: 10px;
}
body .mb-10 {
  margin-bottom: 10px;
}
  • 禁止导入编译
  • _name.scss 下划线标识
@import "_colors";

@media

  • 嵌套媒体查询
  • 编译后,自动剥离到外层
.sidebar {
  width: 300px;
  @media screen and (orientation: landscape) {
    width: 500px;
  }
}

/** complier  **/
.sidebar {
  width: 300px;
}
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}
  • 多层媒体查寻嵌套
  • 自动合并编译条件
@media screen {
  .sidebar {
    @media (orientation: landscape) {
      width: 500px;
    }
  }
}
// and 自动合并
@media screen and (orientation: landscape) {
  .sidebar {
    width: 500px;
  }
}
  • @media 甚至可以使用 SassScript(比如变量,函数,以及运算符)代替条件的名称或者值:
$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;
  }
}

!default 默认变量值

  • !default默认变量值
  • 有变量就用变量,没有就使用默认值
$color: green; // 变量声明
$color: red !default; // 无变量,就使用默认值变量
a {
    color: $color;
}

/** compiler **/
a {
  color: green;
}

静默注释

  • /** css 默认注释 **/多行注释会编译到文件
  • // javascript java 单行注释语法 为静默注释,不会出现在编译后的文件
body {
  color: #333; // 这种注释内容不会出现在生成的css文件中
  padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}

/** compiler **/
@charset "UTF-8";
body {
  color: #333;
  padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}

插值注释

  • #{}字符串模板 + 变量,输出到css
  • ! 作为多行注释的第一个字符表示在压缩输出模式下保留这条注释并输出到 CSS 文件中,通常用于添加版权信息。
$version: "1.2.3";
/* This CSS is generated by My Snazzy Framework version #{$version}. */

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

#{} 插值语句

  • 通过 #{} 插值语句可以在选择器属性名中使用变量
$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}

/** compiler **/
p.foo {
  border-color: blue;
}
  • & 是否为null
  • if else 使用
@mixin does-parent-exist {
    @if & {
        &:hover {
            color: red;
        }
    }

    @else {
        a {
            color: red;
        }
    }
}

@include does-parent-exist;
  • other组合
.foo.bar .baz.bang, .bip.qux {
    $selector: &;
    #{$selector} {
        font-size: 12px;
    }
}

@mixin 混合器

  • @mixin 混合器标识符定义
  • @mixin 声明
  • @include 标识符调用
  • 类似函数,重复调用
  • 可以传参数

基础使用

@mixin common-box {
    width: 100%;
    border: 1px solide red;
    background: red;
}

bod {
    @include common-box;
    div {
       @include common-box;
    }
}

/** compiler **/
body {
  width: 100%;
  border: 1px solid red;
  background: red;
}
body div {
  width: 100%;
  border: 1px solid red;
  background: red;
}

传参

  • 类似函数声明
  • 参数使用$定义
@mixin link-colors($normal, $hover, $visited) {
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

a {
  @include link-colors(blue, red, green);
}

/** complier **/
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }

默认参数

  • 指定参数默认值
@mixin link-colors($normal, $hover: $normal,$visited: $normal){
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

@include link-colors();

参数变量 | 参数扩展

  • js扩展运算符 [...]
@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);
}
.shadowed {
  -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 colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}
$values: #ff0000, #00ff00, #0000ff;
.primary {
  @include colors($values...);
}
.primary {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}
  • 多参数传递
  • 目前报错,没搞明白
@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);
}

@content 向混合样式中导入内容

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

/**  complier **/
* html #logo {
  background-image: url(/logo.gif);
}
$color: white;
@mixin colors($color: blue) {
  background-color: $color;
  @content;
  border-color: $color;
}
.colors {
  @include colors { color: $color; }
}


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

简写

  • 为便于书写,@mixin 可以用 = 表示,而 @include 可以用 + 表示
=apply-to-ie6-only
  * html
    @content

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

@extend继承

  • css类名继承
  • @extend继承调用
  • 相对@mixin性能更好
.dots {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.box {
    @extend .dots;
}

.title {
    @extend .dots;
}

/**  complier **/
.dots, .title, .box {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
  • 延伸复杂的选择器
  • 几重延伸,都是一个思维
// 试了下不生效,编译错误
/**
Compilation Error
Error: compound selectors may no longer be extended.
Consider `@extend a, :hover` instead.
See http://bit.ly/ExtendCompound for details.
**/
.hoverlink {
  @extend a:hover;
}
a:hover {
  text-decoration: underline;
}

%占位符选择器需要通过延伸指令使用

  • 指定选择器
  • id, class, #
    
#context a%extreme {
    color: blue;
    font-weight: bold;
    font-size: 2em;
}

.boooox {
   @extend %extreme;
}
// .boooox 替换 %extreme

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

!optional 声明

  • 冲突编译,声明不生成新的选择器
a.important {
  @extend .notice !optional;
}

@at-root提升根作用域

  • 提升到根作用域
.parent {
  ...
  @at-root {
    .child1 { ... }
    .child2 { ... }
  }
    @at-root {
        .child3 { ... }
    }
  .step-child { ... }
}
.parent .step-child {}
.child1 {}
.child2 {}
.child3 {}

@at-root(without:...) and @at-root(width: ...)

  • 在哪里使用
  • 不在哪里使用
@media print {
  .page {
    width: 8in;
    @at-root (without: media) {
      color: red;
    }
  }
}
@media print {
  .page {
    width: 8in;
  }
}
.page {
  color: red;
}

@debug

  • 类似console.log
@debug 10em + 12em;
Line 1 DEBUG: 22em

@if @else

  • 条件表达式
p {
  @if 1 + 1 == 2 { border: 1px solid; }
  @if 5 < 3 { border: 2px dotted; }
  @if null  { border: 3px double; }
}

p { border: 1px solid; }
$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 $var from <start> through <end>
    @for $var from <start> to <end>
    through to $var $i <start> <end>
    
@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 指令的格式是 , 可以是任何变量名,比如 或者 ,而 是一连串的值,也就是值列表。varinvar in var, lengthlength, name,...

@each 将变量 作用于值列表中的每一个项目,然后输出结果,例如:$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 $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;
}
  • 对象遍历
@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 指令重复输出格式直到表达式返回结果为 。这样可以实现比 更复杂的循环,只是很少会用到。例如: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;
}

function 函数指令

$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: grid-width($n: 5); }

/** compiler **/
#sidebar {
  width: 240px;
}