SASS(scss)

发布时间 2023-06-25 17:27:01作者: 青柠i

Scss

1.认识Scss

Sass 支持两种不同的语法,每个都可以加载另一个。

scss其实是Sass的一种语法。SCSS 语法使用.scss文件扩展名 。除了一些小的例外,它是CSS的超集,这意味着基本上所有有效的CSS也是有效的SCSS

scss示例:

$view-width: 500px;
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
.content {
    width: $view-width;
    height: 200px;
    color: $border-dark;
}

sass原始的语法为缩进语法,使用.sass作为文件扩展名。习惯将其成为sass语法,缩进语法支持与 SCSS 相同的所有功能,但它使用缩进而不是大括号和分号来描述文档的格式(不好阅读,所以scss比较受欢迎)。

sass示例:

$view-width: 500px
$base-color: #c6538c
$border-dark: rgba($base-color, 0.88)
.content
    width: $view-width;
    height: 200px;
    color: $border-dark;

Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 //,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会。

2.嵌套规则

在编写 HTML 时,它有一个清晰的嵌套和可视化层次结构。另一方面,CSS 则没有。

Sass 允许以遵循 HTML 相同视觉层次结构的方式嵌套 CSS 选择器。请注意,过度嵌套的规则将导致过度限定的 CSS,这可能难以维护,并且通常被认为是不好的做法。

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

转换为css:

nav ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
nav li { 
    display: inline-block;
}
nav a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
 }

2.1 处理选择器列表

scss样式

.alert, .warning {
  ul, p {
    margin-right: 0;
    margin-left: 0;
    padding-bottom: 0;
  }
}

转换的css

.alert ul, .alert p, .warning ul, .warning p {
  margin-right: 0;
  margin-left: 0;
  padding-bottom: 0;
}

2.2 选择器组合

scss样式

ul > {
  // 直接子元素
  li {
    list-style-type: none;
  }
}

h2 {
  // 兄弟元素
  + p {
    border-top: 1px solid gray;
  }
}

p {
  // p标签之后出现的span元素
  ~ {
    span {
      opacity: 0.8;
    }
  }
}

转换的css

ul > li {
  list-style-type: none;
}

h2 + p {
  border-top: 1px solid gray;
}

p ~ span {
  opacity: 0.8;
}

2.3 父选择器&

父选择器 ,是 Sass 发明的一种特殊选择器,用于嵌套选择器中指代外部选择器。它使得以更复杂的方式重用外部选择器成为可能,例如添加伪类或在父类之前添加选择器。标识符:&

.alert {
  &:hover {
    font-weight: bold;
  }
  &::before {
     content: '';
     display: block;
     width: 200px;
     height: 200px;
     background-color: red;
   }
}

转换的css

.alert:hover {
   font-weight: bold;
}
.alert::before {
   content: '';
   display: block;
   width: 200px;
   height: 200px;
   background-color: red;
}

2.3.1 添加后缀

可以使用父选择器向外部选择器添加额外的后缀。

.accordion {
  margin: 4rem auto;
  width: 90%;
  background: #f4f4f4;

  &__copy {
    display: none;
    padding: 1rem 1.5rem 2rem 1.5rem;
    color: gray;
    line-height: 1.6;
    font-size: 14px;
    font-weight: 500;

    &--open {
      display: block;
    }
  }
}

转换的css

.accordion {
  margin: 4rem auto;
  width: 90%;
  background: #f4f4f4;
}
.accordion__copy {
  display: none;
  padding: 1rem 1.5rem 2rem 1.5rem;
  color: gray;
  line-height: 1.6;
  font-size: 14px;
  font-weight: 500;
}
.accordion__copy--open {
  display: block;
}

2.4 属性嵌套

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

.funky {
  font: {
    family: fantasy;
    size: 30em;
    weight: bold;
  }
}

// 编译的CSS
.funky {
  font-family: fantasy;
  font-size: 30em;
  font-weight: bold; 
}

又如:

nav {
  border: {
  style: solid;
  width: 1px;
  color: #ccc;
  }
}
// 编译的CSS
nav {
  border-style: solid;
  border-width: 1px;
  border-color: #ccc;
}

2.4.1 命名空间的属性值

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

.funky {
  font: 20px/24px {
    family: fantasy;
    weight: bold;
  }
}
// 编译后
.funky {
    font: 20px/24px;
    font-family: fantasy;
    font-weight: bold; 
}

2.4.2 缩写后指明例外规则

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

nav {
  border: 1px solid #ccc {
  left: 0px;
  right: 0px;
  }
}
// 编译的CSS
nav {
  border: 1px solid #ccc;
  border-left: 0px;
  border-right: 0px;
}

3. 数据类型

Sass支持许多值类型,其中大多数直接来自CSS。每个表达式产生一个值,变量保存值。大多数值类型直接来自CSS:

  • Numbers数字,可能有或者没有单位, 像12100px.
  • Strings字符串,可能有或者没有双引号,像"Helvetica Neue"bold.
  • Colors颜色,它们可以通过十六进制表示或名称来引用,如#c6538cblue,或从函数返回,如rgb(107, 113, 127)hsl(210, 100%, 20%).
  • Lists数组,可以用空格或逗号分隔,可以用方括号括起来,也可以根本不用括号,比如1.5em 1em 0 2em, Helvetica, Arial, sans-serif, or [col1-start]

还有一些 Sass特有的:

  • boolean布尔型,包括true/false
  • 单一实例空值null
  • 值与键的关联Maps,如("background": red, "foreground": pink)
  • 由get-function()返回并由call()调用的函数引用。

4. 变量

Sass变量很简单:将值赋给以$开头的名称,然后可以引用该名称而不是值本身。

在声明变量时,变量值也可以引用其他变量。

$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);

.alert {
  border: 1px solid $border-dark;
}

转换的css

.alert {
  border: 1px solid rgba(198, 83, 140, 0.88);
}

4.1 作用域

变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 !global 声明:

$variable: 6em;

.content {
  $variable: 3em;
  $width: 5em !global;
  height: $variable;
}

.sidebar {
  width: $width;
  height: $variable;
}

转换的css

.content {
  height: 3em; /* local value */
}

.sidebar {
  width: 5em; /* global value */
  height: 6em; /* global value */
}

4.2 默认变量值

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

$link-color: blue;
$link-color: red;
a {
color: $link-color;
}
// 超链接的color会被设置为red。

如果有个需求是当你写了一个可被他人通过@import导入的sass库文件,你可能希望导入者可以定制修改sass库文件中的某些值。那就可以使用sass!default标签实现这个目的。含义是:如果这个变量被声明赋值了,那就用它声明的值,否则就用这个默认值。

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

5. 运算/计算

所有数据类型均支持相等运算 ==!=,此外,每种数据类型也有其各自支持的运算方式。

圆括号可以用来影响运算的顺序

p {
  width: 1em + (2em * 3);
}
// 转换为
p {
  width: 7em; 
}

5.1 数字运算

sass支持数字的加减乘除、取整等运算 (+, -, *, /, %),如果必要会在不同单位间转换值。

关系运算 <, >, <=, >= 也可用于数字运算,相等运算 ==, != 可用于所有数据类型。

div {
  $width: 300px;
  $height: 100px;
  width: $width + $height;
  height: $width - $height;
}
// 编译后
div {
  width: 400px;
  height: 200px;
}

5.1.1 除法运算/

/ 在 CSS 中通常起到分隔数字的用途,Sass 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了 / 除法运算的功能。

以下三种情况 / 将被视为除法运算符号:

  • 如果值,或值的一部分,是变量或者函数的返回值
  • 如果值被圆括号包裹
  • 如果值是算数表达式的一部分
p {
  font: 10px/8px;             // 纯CSS,不做除法运算
  $width: 1000px;
  width: $width/2;            // 使用变量做除法运算
  width: round(1.5)/2;        // 利用函数做除法运算
  height: (500px/2);          // 被括号包括做除法运算
  margin-left: 5px + 8px/2px; // 作为+算术表达式的一部分,做除法运算
}

5.1.2 使用计算函数

计算是 Sass 表示 calc() 函数的方式。相似的函数还有如clamp()min()max()

5.1.2.1 calc()

不能将calc函数计算与普通的 Sass 运算操作一起使用,例如 + and *。如果你想写一些允许计算的数学函数,只需将它们写在它们自己的calc()表达式中。

$width: calc(400px + 10%);

.sidebar {
  width: $width;
  // $width * 2 // Error!
  // calc($width * 2)
  padding-left: calc($width / 4);
}

转换的css

.sidebar {
  width: calc(400px + 10%);
  padding-left: calc($width / 4);
}
5.1.2.1 min()max()
$padding: 12px;
$normalSize: 16px;

.post {
  padding-left: max($padding, normalSize);
  padding-right: max($padding, 10px);
}

.sidebar {
  padding-left: max($padding % 10, 20px);
  padding-right: max($padding % 10, 20px);
}

转换的css

.post {
  padding-left: 16px;
  padding-right: 12px;
}

.sidebar {
  padding-left: 20px;
  padding-right: 20px;
}

5.2 颜色值运算

颜色值的运算是分段计算进行的,也就是分别计算红色,绿色,以及蓝色的值:

p {
  color: #010203 + #040506;
}

计算 01 + 04 = 0502 + 05 = 0703 + 06 = 09,然后编译为

p {
  color: #050709; 
}

数字与颜色值之间也可以进行算数运算,同样也是分段计算的

p {
  color: #010203 * 2;
}
// 转换为
p {
  color: #020406; 
}

5.3 字符串运算

+ 可用于连接字符串

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 {
  margin: 3px + 4px auto;
}
// 编译为
p {
  margin: 7px auto;
}

5.4 布尔运算

Sass 支持布尔型的 and or 以及 not 运算。分别对应JavaScript中的&&与、||或、!取反

@debug not true; // false
@debug not false; // true

@debug true and true; // true
@debug true and false; // false

@debug true or false; // true
@debug false or false; // false

6. mixin 混合器

当需要大段大段的重用样式的代码,可以通过sassmixin混合器实现大段样式的重用。混合器使用@mixin标识符定义。

@mixin rounded-corners {
  // 添加跨浏览器的圆角边框
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}
@mixin no-bullets {
  list-style: none;
  li {
    list-style-image: none;
    list-style-type: none;
    margin-left: 0px;
  }
}

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

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

转换的CSS

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

6.1 给混合器传参

混合器并不一定总得生成相同的样式。可以通过在@include混合器时给混合器传参,来定制混合器生成的精确样式。当@include混合器时,参数其实就是可以赋值给css属性值的变量。

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

6.2 默认参数值

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

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

使用:

a {
    // $hover和$visited也会被自动赋值为red。
    @include link-colors(red)
}

7. 插值语句#{}

插值总是返回一个不带引号的字符串

几乎可以在 Sass 样式表的任何地方使用插值,将Sass 表达式的结果嵌入到 CSS 块中。

@mixin corner-icon($name, $top-or-bottom, $left-or-right) {
  .icon-#{$name} {
    background-image: url("/icons/#{$name}.svg");
    position: absolute;
    #{$top-or-bottom}: 0;
    #{$left-or-right}: 0;
  }
}

@include corner-icon("mail", top, left);

转换的CSS

.icon-mail {
  background-image: url("/icons/mail.svg");
  position: absolute;
  top: 0;
  left: 0;
}

7.1 避免/运算

#{} 插值语句也可以在属性值中插入,大多数情况下,这样可能还不如使用变量方便,但是使用 #{} 可以避免 Sass 运行运算表达式,直接编译 CSS。

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

7.2 在注释中使用

插值语句 也可写进多行注释中输出变量值:

$version: "1.2.3";
/* This CSS is generated by xxx version #{$version}. */

编译为:

/* This CSS is generated by xxx version 1.2.3. */

7.3 在文本字符串中使用

在有引号的文本字符串中使用 #{} 插值语句可以添加动态的值:

p:before {
  content: "I am #{5 + 10} years old!";
}
// 编译为
p:before {
  content: "I am 15 years old!";
}

空的值被视作插入了空字符串:

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