CSS预处理器Sass详解

时间:2021-05-08

Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。

1. 特色功能

  • 完全兼容 CSS3
  • 在 CSS 基础上增加变量、嵌套 (nesting)、混合 (mixins) 等功能
  • 通过函数进行颜色值与属性值的运算
  • 提供控制指令 (control directives)等高级功能
  • 自定义输出格式
  • 文件后缀名称:sass有两种后缀名文件,一种后缀名为sass,不使用大括号和分号;另一种就是我们这里使用的scss文件,这种和我们平时写的css文件格式差不多,使用大括号和分号。而本教程中所说的所有sass文件都指后缀名为scss的文件。在此也建议使用后缀名为scss的文件,以避免sass后缀名的严格格式要求报错。

    //文件后缀名为sass的语法body background: #eee font-size:12pxp background: #0982c1//文件后缀名为scss的语法 body { background: #eee; font-size:12px;}p{ background: #0982c1;}

    2. Sass、Less语法比较

    2.1 Sass与Less不同之处

  • 编译环境不一样——Sass基于Ruby等服务器端环境编译,Less既可以支持服务器端编译也可在客户端(浏览器环境)编译
  • 变量符不一样——Sass使用$符号声明变量,Less使用@符号声明变量
  • 对于条件语句的支持不一样——Sass支持复杂的条件语句(类似于if..else..),Less仅支持简单的条件语句(类似于if()..)
  • 作用域——Sass局部修改变量可影响全局变量,Less则只会在局部作用域生效。
  • 引用外部CSS文件方式不同——Sass默认引入.sass或.scss文件时可忽略后缀,Less则需要通过关键字配置来控制引入文件如何处理。
  • 2.2 Sass与Less相似的地方

  • 混入(Mixins)——类似于函数或者宏,并且可以传递参数;
  • 嵌套规则——class中嵌套class,从而减少重复的代码;
  • 运算——CSS中运用加减乘除计算各种数值以及字符串等;
  • 颜色功能——可以通过内置函数编辑颜色;
  • 命名空间(namespace)——分组样式,从而可以被调用;
  • 3. Sass语法主要功能介绍

    3.1 CSS功能扩展

    嵌套规则

    Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理,例如:

    //sass style or less style#main p { color: #00ff00; width: 97%; .redbox { background-color: #ff0000; color: #000000; }}//css style#main p {color: #00ff00;width: 97%; }#main p .redbox { background-color: #ff0000; color: #000000; }

    父选择器 &

    在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,例如,当给某个元素设定 hover 样式时,或者当 body 元素有某个 classname 时,可以用 & 代表嵌套规则外层的父选择器。

    //sass style or less stylea { font-weight: bold; text-decoration: none; &:hover { text-decoration: underline; } body.firefox & { font-weight: normal; }}//css stylea {font-weight: bold;text-decoration: none; }a:hover { text-decoration: underline; }body.firefox a { font-weight: normal; }

    属性嵌套

    有些 CSS 属性遵循相同的命名空间 (namespace),比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中,例如:

    //sass style.funky { font: { family: fantasy; size: 30em; weight: bold; }}//css style.funky { font-family: fantasy; font-size: 30em; font-weight: bold; }

    命名空间也可以包含自己的属性值,例如:

    //sass style.funky { font: 20px/24px { family: fantasy; weight: bold; }}//css style.funky { font: 20px/24px; font-family: fantasy; font-weight: bold; }

    3.2导入

    sass的导入(@import)规则和CSS的有所不同,编译时会将@import的scss文件合并进来只生成一个CSS文件。但是如果你在sass文件中导入css文件如 @import ‘reset.css’,那效果跟普通CSS导入样式文件一样,导入的css文件不会合并到编译后的文件中,而是以 @import 方式存在。

    所有的sass导入文件都可以忽略后缀名.scss。一般来说基础的文件命名方法以_开头,如_mixin.scss。这种文件在导入的时候可以不写下划线,可写成@import “mixin”。

    less的导入(@import)语法:@import (keyword) “filename”;

    多个关键字 @import 是允许的,你必须使用逗号分隔关键字:example: @import (optional, reference) “foo.less”;

  • reference: 使用该less文件但是不输出它
  • inline: 包括在源文件中输出,但是不作处理
  • less: 将该文件视为less文件,无论其扩展名为什么
  • css: 将文件视为css文件,无论扩展名为什么
  • once: 该文件仅可导入一次 (默认)
  • multiple: 该文件可以多次导入
  • optional: 当没有发现文件时仍然编译
  • 导入文件代码示例:

    //a.scss or a.less//-------------------------------body { background: #eee;}@import "reset.css";@import "a";p{ background: #0982c1;} @import "reset.css";body { background: #eee;}p{ background: #0982c1;}

    根据上面的代码可以看出,b.scss编译后,reset.css继续保持import的方式,而a.scss则被整合进来了。同理,less中也是这样处理的。

    3.3 注释 与 //

    Sass 支持标准的 CSS 多行注释 ,以及单行注释 //,前者会被完整输出到编译后的 CSS 文件中,而后者则不会。Less中不用担心这一点,Less中多行注释 ,以及单行注释 //都可以随意使用,都会在编译过程中被保留。例如:

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

    3.4 SassScript

    变量 $

    Sass的变量必须是$开头,后面紧跟变量名,如果值后面加上!default则表示默认值。Less的变量与Sass类似,只是使用符号不同,Less中采用的是@

    //sass style//-------------------------------$fontSize: 12px;body{ font-size:$fontSize;} //less style//-------------------------------@fontSize: 12px;body{ font-size:@fontSize;}//css style//-------------------------------body{ font-size:12px;}

    变量默认值

    sass的默认变量一般是用来设置默认值,然后根据需求来覆盖的,覆盖的方式也很简单,只需要在使用默认变量之前重新声明下变量即可;默认变量的价值在进行组件化开发的时候会非常有用。

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

    变量 #{} 的使用形式

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

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

    多值变量 list

    简单来说list类型有点像js中的数组。list数据可通过空格,逗号或小括号分隔多个值,可用nth($var,$index)取值。

    关于list数据操作还有很多其他函数如length($list),join($list1,$list2,[$separator]),append($list,$value,[$separator])等

    定义:

    //一维数据$px: 5px 10px 20px 30px;//二维数据,相当于js中的二维数组$px: 5px 10px, 20px 30px;$px: (5px 10px) (20px 30px);

    使用方法:

    //sass style//-------------------------------$linkColor: #08c #333 !default;//第一个值为默认值,第二个鼠标滑过值a{ color:nth($linkColor,1); &:hover{ color:nth($linkColor,2); }}//css style//-------------------------------a{ color:#08c;}a:hover{ color:#333;}

    多值变量 map

    简单来说map类型有点像es6语法中的map数据结构。map数据以key和value成对出现,其中value又可以是list。

    格式为:$map: (key1: value1, key2: value2, key3: value3);可通过map-get($map,$key)取值。关于map数据还有很多其他函数如map-merge($map1,$map2),map-keys($map),map-values($map)等

    定义:

    $heading: (h1: 2em, h2: 1.5em, h3: 1.2em);

    使用方法:

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

    变量作用域

    Sass和Less中的变量作用域分别类似与javascript中的两种变量申明方式,下面一段代码可以对比出变量声明时的不同处理方式。

    Sass中的变量赋值直接修改全局变量,Less中的变量赋值可只在局部生效。

    //Sass style$color:red; p{ $color:blue; color:$color;//blue } a{ color:$color;//blue }//Less style@color:red; p{ @color:blue; color:@color;//blue } a{ color:@color;//red }

    3.5 混合(mixin)

    sass中使用@mixin声明混合,可以传递参数,也可以给参数设置默认值。声明的@mixin通过@include来调用;在less中只需要将定义好的class用类似函数的方式直接引用。

    无参数 mixin

    //sass style@mixin center-block { margin-left:auto; margin-right:auto;}.demo{ @include center-block;}//less style.center-block { margin-left:auto; margin-right:auto;}.demo{ .center-block;}//css style.demo{ margin-left:auto; margin-right:auto;}

    有参数 mixin

    //sass style@mixin opacity($opacity:50) { opacity: $opacity / 100; filter: alpha(opacity=$opacity);}.opacity-80{ @include opacity(80); //传递参数}//less style.opacity(@opacity:50) { opacity: @opacity / 100; filter: alpha(opacity=@opacity);}.opacity-80{ .opacity(80); //传递参数}//css style.opacity-80{ opacity: .8; filter: alpha(opacity=80);}

    多个参数 mixin

    Sass调用时可直接传入值,如@include传入参数的个数小于@mixin定义参数的个数,则按照顺序表示,后面不足的使用默认值,如不足的没有默认值则报错。除此之外还可以选择性的传入参数,使用参数名与值同时传入;Less中使用方法类似。

    //sass style @mixin horizontal-line($border:1px dashed #ccc, $padding:10px){ border-bottom:$border; padding-top:$padding; padding-bottom:$padding; }.imgtext-h li{ @include horizontal-line(1px solid #ccc);}//less style.horizontal-line(@border:1px dashed #ccc, @padding:10px){ border-bottom:@border; padding-top:@padding; padding-bottom:@padding; }.imgtext-h li{ .horizontal-line(1px solid #ccc);}//css style.imgtext-h li { border-bottom: 1px solid #cccccc; padding-top: 10px; padding-bottom: 10px;}

    多组值参数 mixin

    Sass中如果一个参数可以有多组值,如box-shadow、transition等,那么参数则需要在变量后加三个点表示,如$variables…;Less表示不定参数时可以直接使用 … 表示,并用@arguments表示所有参数

    //sass style //box-shadow可以有多组值,所以在变量参数后面添加...@mixin box-shadow($shadow...) { -webkit-box-shadow:$shadow; box-shadow:$shadow;}.box{ border:1px solid #ccc; @include box-shadow(0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3));}//less style.box-shadow(...) { -webkit-box-shadow:@arguments; box-shadow:@arguments;}.box{ border:1px solid #ccc; .box-shadow(0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3));}//css style.box{ border:1px solid #ccc; -webkit-box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3); box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3);}

    3.6 运算

    sass具有运算的特性,可以对数值型的Value(如:数字、颜色、变量、字符串等)进行加减乘除四则运算。请注意运算符前后请留一个空格,不然会出错。

    //计算数值、变量$baseFontSize: 14px !default;$baseLineHeight: 2 !default;$baseGap: $baseFontSize * $baseLineHeight !default; // => 28px$halfBaseGap: $baseGap / 4 !default; // => 7px$samllFontSize: $baseFontSize - 2px !default; // => 12px$_columns: 12 !default; $_column-width: 60px !default; $_gutter: 20px !default; $_gridsystem-width: $_columns * ($_column-width + $_gutter); // => 960px//计算颜色p { color: #010203 + #040506; // => #050709}//计算字符串p:before { content: "Foo " + Bar; // => "Foo Bar" font-family: sans- + "serif"; // => sans-serif}

    3.7 控制指令

    SassScript 提供了一些基础的控制指令,比如在满足一定条件时引用样式,或者设定范围重复输出格式。控制指令是一种高级功能,日常编写过程中并不常用到,主要与混合指令 (mixin) 配合使用。

    @if

    //sass stylep { @if 1 + 1 == 2 { border: 1px solid; } @if 5 < 3 { border: 2px dotted; } @if null { border: 3px double; }}//css stylep {border: 1px solid; }//sass style$type: monster;p { @if $type == ocean { color: blue; } @else if $type == matador { color: red; } @else if $type == monster { color: green; } @else { color: black; }}//less style@type: monster;p (@type) when (@type = ocean){color: blue;}p (@type) when (@type = matador){color: red;}p (@type) when (@type = monster){color: green;}p (@type) when (@type = dark){color: black;}//css stylep {color: green; }

    @for

    @for 指令包含两种格式:@for $var from <start> through <end>,或者 @for $var from <start> to <end>,区别在于 through 与 to 的含义:当使用 through 时,条件范围包含 <start> 与 <end> 的值,而使用 to 时条件范围只包含 <start> 的值不包含 <end> 的值。另外,$var 可以是任何变量,比如 $i;<start> 和 <end> 必须是整数值。

    //sass style@for $i from 1 through 3 { .item-#{$i} { width: 2em * $i; }}//css style.item-1 { width: 2em; }.item-2 { width: 4em; }.item-3 { width: 6em; }

    @each

    语法为:@each $var in <list or map>。其中$var表示变量,而list和map表示list类型数据和map类型数据。

    单个字段list数据循环:

    //sass style$animal-list: puma, sea-slug, egret, salamander;@each $animal in $animal-list { .#{$animal}-icon { background-image: url('/images/#{$animal}.png'); }}//css style.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'); }

    多个字段list数据循环:

    //sass style//-------------------------------$animal-data: (puma, black, default),(sea-slug, blue, pointer),(egret, white, move);@each $animal, $color, $cursor in $animal-data { .#{$animal}-icon { background-image: url('/images/#{$animal}.png'); border: 2px solid $color; cursor: $cursor; }}//css style//-------------------------------.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; }

    多个字段map数据循环:

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

    @extend

    @extend 的作用是将重复使用的样式 (.error) 延伸 (extend) 给需要包含这个样式的特殊样式(.seriousError),例子:

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

    3.8 函数指令

    Sass 支持自定义函数,并能在任何属性值或 Sass script 中使用:

    //sass style//-------------------------------$grid-width: 40px;$gutter-width: 10px;@function grid-width($n) { @return $n * $grid-width + ($n - 1) * $gutter-width;}#sidebar { width: grid-width(5); }//css style//-------------------------------#sidebar { width: 240px; }

    与 mixin 相同,也可以传递若干个全局变量给函数作为参数。一个函数可以含有多条语句,需要调用 @return 输出结果。

    Sass 函数允许使用关键词参数,上面的例子也可以写成:

    //关键词参数调用形式#sidebar { width: grid-width($n: 5); }

    虽然不够简明,但是阅读起来会更方便。关键词参数给函数提供了更灵活的接口,以及容易调用的参数。关键词参数可以打乱顺序使用,如果使用默认值也可以省缺,另外,参数名被视为变量名,下划线、短横线可以互换使用。

    参考文献:Sass中文文档 — https://www.sass.hk/docs/

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

    声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

    相关文章