5年前端的sass学习指南

199 阅读5分钟

说来惭愧,工作5年了还没有认真系统的学习过css相关内容。平时工作中因为做的是公司支撑系统,对样式要求也不高。平时就对ANTD和ElemntUI自带样式,实在不满足了,再面向百度编程。现在入职的新公司对css有要求,于是系统的学了下sass。以下是对官网内容的一些总结,mark下:

1.变量使用

把反复使用的css属性值 定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。

sass使用$符号来标识变量,变量的声明和css属性的声明很像

变量可以在css规则块定义之外存在。当变量定义在css规则块内,那么该变量只能在此规则块内使用(感觉就是局部变量和全局变量的概念)。如果它们出现在任何形式的{...}块中(如@media或者@font-face块),情况也是如此

eg:

$nav-color #F90;.png 在声明变量时,变量值也可以引用其他变量:

$highlight-color#F90;.png

2. 嵌套CSS 规则;

在Sass中,你可以像俄罗斯套娃那样在规则块中嵌套规则块。sass在输出css时会帮你把这些嵌套规则处理好,避免你的重复书写。

#content {
    article {
        h1 { color: #333 }
        p { margin-bottom: 1.4em }
      }
    aside { background-color: #EEE }
}

2.1 父选择器的标识符 &

article a {.png

2.2 群组选择器的嵌套

container {.png

2.3 子组合选择器和同层组合选择器: >+~

子组合选择器>选择一个元素的直接子元素

article > section { border: 1px solid #ccc }

同层相邻组合选择器+选择header元素后紧跟的p元素

header + p { font-size: 1.1em }

同层全体组合选择器~,选择所有跟在article后的同层article元素,不管它们之间隔了多少其他元素

article ~ article { border-top: 1px dashed #ccc }
article {
  ~ article { border-top: 1px dashed #ccc }
  > section { background: #eee }
  dl > {
    dt { color: #333 }
    dd { color: #555 }
  }
  nav + & { margin-top: 0 }
}

2.4嵌套属性 ;sass中,除了CSS选择器,属性也可以进行嵌套。尽管编写属性涉及的重复不像编写选择器那么糟糕,但是要反复写border-style border-width border-color以及border-*等也是非常烦人的。在sass中,你只需敲写一遍border

nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}

嵌套属性的规则是这样的:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }块,把子属性部分写在这个{ }块中,最后生成的效果与你手动一遍遍写的css样式一样:

nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

对于属性的缩写形式,你甚至可以像下边这样来嵌套,指明例外规则:

nav {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}

3. 导入SASS文件;

css有一个特别不常用的特性,即@import规则,它允许在一个css文件中导入其他css文件。然而,后果是只有执行到@import时,浏览器才会去下载其他css文件,这导致页面加载起来特别慢。

sass也有一个@import规则,但不同的是,sass@import规则在生成css文件时就把相关文件导入进来。这意味着所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。另外,所有在被导入文件中定义的变量和混合器均可在导入文件中使用。 可以通过@import引入其他的sass或者scss文件,可以省略.sass.scss文件后缀

image.png

3.1 使用SASS部分文件

当通过@importsass样式分散到多个文件时,你通常只想生成少数几个css文件。那些专门为@import命令而编写的sass文件,并不需要生成对应的独立css文件,这样的sass文件称为局部文件。对此,sass有一个特殊的约定来命名这些文件。(一些sass文件可能只为了@import导入到其他css文件中,属于“工具人”)

此约定即,sass局部文件的文件名以下划线开头。这样,sass就不会在编译时单独编译这个文件输出css,而只把这个文件用作导入。当你@import一个局部文件时,还可以不写文件的全名,即省略文件名开头的下划线。举例来说,你想导入themes/_night-sky.scss这个局部文件里的变量,你只需在样式表中写@import "themes/night-sky";

3.2 默认变量值;

一般情况下,你反复声明一个变量,只有最后一处声明有效且它会覆盖前边的值。比如:

$link-color: blue;
$link-color: red;
a {
    color: $link-color;
}

在上边的例子中,超链接的color会被设置为red

假如你写了一个可被他人通过@import导入的sass库文件,此时若是其他人事先定义过变量($link-color)的值,再通过@import引入你的sass文件,可能他的变量值就被你的sass文件中的变量值覆盖了。

你可能希望导入者可以定制修改sass库文件中的某些值。使用sass!default标签。它很像css属性中!important标签的对立面,不同的是!default用于变量,含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。

$fancybox-width: 400px !default;
.fancybox {
width: $fancybox-width;
}

在上例中,如果用户在导入你的sass局部文件之前声明了一个$fancybox-width变量,那么你的局部文件中对$fancybox-width赋值400px的操作就无效。如果用户没有做这样的声明,则$fancybox-width将默认为400px

3.3. 嵌套导入

跟原生的css不同,sass允许@import命令写在css规则内。这种导入方式下,生成对应的css文件时,局部文件会被直接插入到css规则内导入它的地方。举例说明,有一个名为_blue-theme.scss的局部文件,内容如下:

aside {
  background: blue;
  color: white;
}

然后把它导入到一个CSS规则内,如下所示:

.blue-theme {@import "blue-theme"}

//生成的结果跟你直接在.blue-theme选择器内写_blue-theme.scss文件的内容完全一样。

.blue-theme {
  aside {
    background: blue;
    color: #fff;
  }
}

被导入的局部文件中定义的所有变量和混合器,也会在这个规则范围内生效。这些变量和混合器不会全局有效,这样我们就可以通过嵌套导入只对站点中某一特定区域运用某种颜色主题或其他通过变量配置的样式。

4. 静默注释;

css中注释会被看到,你可能并不希望每个浏览网站源码的人都能看到所有注释。

sass另外提供了一种不同于css标准注释格式/* ... */的注释语法,即静默注释,其内容不会出现在生成的css文件中。它们以//开头,注释内容直到行末。

body {
  color: #333; // 这种注释内容不会出现在生成的css文件中
  padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}

实际上,css的标准注释格式/* ... */内的注释内容亦可在生成的css文件中抹去。当注释出现在原生css不允许的地方,如在css属性或选择器中,sass将不知如何将其生成到对应css文件中的相应位置,于是这些注释被抹掉。

body {
  color /* 这块注释内容不会出现在生成的css中 */: #333;
  padding: 1; /* 这块注释内容也不会出现在生成的css中 */ 0;
}

5. 混合器;

通过sass的混合器实现大段样式的重用。

混合器使用@mixin标识符定义。看上去很像其他的CSS @标识符,比如说@media或者@font-face。这个标识符给一大段样式赋予一个名字,这样你就可以轻易地通过引用这个名字重用这段样式。下边的这段sass代码,定义了一个非常简单的混合器,目的是添加跨浏览器的圆角边框。

@mixin rounded-corners {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

然后就可以在你的样式表中通过@include来使用这个混合器,放在你希望的任何地方。@include调用会把混合器中的所有样式提取出来放在@include被调用的地方。如果像下边这样写:

notice {
  background-color: green;
  border: 2px solid #00aa00;
  @include rounded-corners;
}

//sass最终生成:

.notice {
  background-color: green;
  border: 2px solid #00aa00;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

5.1 给混合器传参

混合器并不一定总得生成相同的样式。可以通过在@include混合器时给混合器传参,来定制混合器生成的精确样式。当@include混合器时,参数其实就是可以赋值给css属性值的变量。如果你写过JavaScript,这种方式跟JavaScriptfunction很像:

@mixin link-colors($normal, $hover, $visited) {
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

当混合器被@include时,你可以把它当作一个css函数来传参。如果你像下边这样写:

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

//Sass最终生成的是:

a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }

当你@include混合器时,有时候可能会很难区分每个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass允许通过语法$name: value的形式指定每个参数的值。这种形式的传参,参数顺序就不必再在乎了,只需要保证没有漏掉参数即可:

a {
    @include link-colors(
      $normal: blue,
      $visited: green,
      $hover: red
  );
}

5-2. 默认参数值;

为了在@include混合器时不必传入所有的参数,我们可以给参数指定一个默认值。参数默认值使用$name: default-value的声明形式,默认值可以是任何有效的css属性值,甚至是其他参数的引用,如下代码:

@mixin link-colors(
    $normal,
    $hover: $normal,
    $visited: $normal
  )
{
  color: $normal;
  &:hover { color: $hover; }
  &:visited { color: $visited; }
}

如果像下边这样调用:@include link-colors(red) $hover$visited也会被自动赋值为red

6. 使用选择器继承来精简CSS;

使用sass的时候,最后一个减少重复的主要特性就是选择器继承。选择器继承是说一个选择器可以继承为另一个选择器定义的所有样式。这个通过@extend语法实现,如下代码:

//通过选择器继承继承样式
.error {
  border: 1px solid red;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}

在上边的代码中,.seriousError将会继承样式表中任何位置处为.error定义的所有样式。以class="seriousError" 修饰的html元素最终的展示效果就好像是class="seriousError error"。相关元素不仅会拥有一个3px宽的边框,而且这个边框将变成红色的,这个元素同时还会有一个浅红色的背景,因为这些都是在.error里边定义的样式。

.seriousError不仅会继承.error自身的所有样式,任何跟.error有关的组合选择器样式也会被.seriousError以组合选择器的形式继承,如下代码:

//.seriousError.error继承样式
.error a{  //应用到.seriousError a
  color: red;
  font-weight: 100;
}
h1.error { //应用到hl.seriousError
  font-size: 1.2rem;
}

如上所示,在class="seriousError"html元素内的超链接也会变成红色和粗体。