Skip to content
索引

scss

dart-sass与node-sass区别

相同点:都是用来将 sass 编译成 css 的工具

区别:

  • node-sass 是用 node (调用 cpp 编写的 libsass) 来编译 sass,dart-sass是用 drat VM 来编译 sass
  • node-sass 是实时自动编译的,dart-sass 需要保存后才会生效
  • dart sass是sass的主要实现,它快速,易于安装,并且可以编译为纯 JavaScript,从而可以轻松集成到现代 Web开发工作流中,sass 官方目前主力推 dart-sass,最新的特性都会在这个上面先实现

sass和scss的区别

主要在于缩进语法的区别,原先版本称为sass,不使用{}的写法,第三代开始,使用传统的{}的写法,称为scss

html中使用

搭配vscode插件live sass compiler,点击vscode下方栏中图标,即可自动转换scss文件为css文件

vscode的settings.json可以配置live sass compiler,scss有以下输出风格

  • nested 嵌套格式
  • expanded 展开格式
  • compact 紧凑格式
  • compressed 压缩格式
js
 "liveSassCompile.settings.formats": [
    {
      "format": "nested",  // nested/expanded/compact/compressed四种格式
      "extensionName": ".css",
      "savePath": null // 为null代表当前目录
    }
  ],
  "liveSassCompile.settings.generateMap": false, // 不生成map.css
  "liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"], // 自动添加兼容前缀
  "liveSassCompile.settings.excludeList": ["**/node_modules/**", ".vscode/**"],
 "liveSassCompile.settings.formats": [
    {
      "format": "nested",  // nested/expanded/compact/compressed四种格式
      "extensionName": ".css",
      "savePath": null // 为null代表当前目录
    }
  ],
  "liveSassCompile.settings.generateMap": false, // 不生成map.css
  "liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"], // 自动添加兼容前缀
  "liveSassCompile.settings.excludeList": ["**/node_modules/**", ".vscode/**"],

vue中使用

安装

sh
yarn add -D sass  
yarn add -D sass-loader@10.2.0
yarn add -D sass  
yarn add -D sass-loader@10.2.0

使用

css
<style lang="scss" scoped>
$bg-pink: deeppink;
.home {
  background-color: $bg-pink;
}
</style>
<style lang="scss" scoped>
$bg-pink: deeppink;
.home {
  background-color: $bg-pink;
}
</style>

局部使用

scss
<style lang="scss" scoped>
@import "../styles/global.scss";
$bg-pink: deeppink;
.box {
  background-color: $bg-pink;
}
</style>
<style lang="scss" scoped>
@import "../styles/global.scss";
$bg-pink: deeppink;
.box {
  background-color: $bg-pink;
}
</style>

全局使用

方法一

main.ts或main.js中引入全局scss文件

方法二

如使用vue脚手架,可在vue.config.js中配置全局scss文件

js
module.exports = {
  css: {
    loaderOptions: {
      scss: {
        additionalData: `@import "styles/global.scss";`
      }
    }
  }
}
module.exports = {
  css: {
    loaderOptions: {
      scss: {
        additionalData: `@import "styles/global.scss";`
      }
    }
  }
}

vite.config.ts

ts
css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "src/assets/theme/index.scss" as *;`
      }
    }
  }
css: {
    preprocessorOptions: {
      scss: {
        additionalData: `@use "src/assets/theme/index.scss" as *;`
      }
    }
  }

嵌套css规则

减少重复css选择器的书写,这一功能less也具备

避免非必要的嵌套,因为过多的嵌套会导致最终编译的css选择器很长,会增加浏览器的性能消耗(当然,绝大部分情况下不会有明显感受,但是这会是一个好习惯)

scss
// 传统的css
.flex {
  display: flex;
}

.flex .left {
  width: 100px;
}

.flex .right {
  width: 200px;
}
// 嵌套css
.flex {
  display: flex;
  .left {
    width: 100px;
  }
  .right {
    width: 200px;
  }
}
// 传统的css
.flex {
  display: flex;
}

.flex .left {
  width: 100px;
}

.flex .right {
  width: 200px;
}
// 嵌套css
.flex {
  display: flex;
  .left {
    width: 100px;
  }
  .right {
    width: 200px;
  }
}

& 父选择器

在嵌套css规则时,有时需要使用嵌套外层的父选择器,可以使用&代表父选择器,可以拼接,示例:

scss
.box {
  color: #000;
  &:hover {
    color: #fff;
  }
  .flex {
    color: pink;
    &-left {
      color: red;
    }
  }
}
// 编译为
.box {
  color: #000;
}

.box:hover {
  color: #fff;
}

.box .flex {
  color: pink;
}

.box .flex-left {
  color: red;
}
.box {
  color: #000;
  &:hover {
    color: #fff;
  }
  .flex {
    color: pink;
    &-left {
      color: red;
    }
  }
}
// 编译为
.box {
  color: #000;
}

.box:hover {
  color: #fff;
}

.box .flex {
  color: pink;
}

.box .flex-left {
  color: red;
}

属性嵌套

有些css属性遵循相同的命名空间(namespace),比如font-family,font-size,font-weight都以font作为属性的命名空间,为了便于管理这样的属性,同时也为了避免重复输入,sass允许将属性嵌套在命名空间中(对象形式的写法)

scss
.flex {
  color: pink;
  font : {
    size: 10px;
    family: sans-serif;
    weight: bold;
  }
}
// 编译为
.flex {
  color: pink;
  font-size: 10px;
  font-family: sans-serif;
  font-weight: bold;
}
.flex {
  color: pink;
  font : {
    size: 10px;
    family: sans-serif;
    weight: bold;
  }
}
// 编译为
.flex {
  color: pink;
  font-size: 10px;
  font-family: sans-serif;
  font-weight: bold;
}

$ 定义变量

变量具有块级作用域

scss
$pink: pink;
.box {
  color: $pink;
}
// 编译为
.box {
  color: pink;
}
$pink: pink;
.box {
  color: $pink;
}
// 编译为
.box {
  color: pink;
}

连接符与下划线

通过连接符与下划线定义的同名变量为同一变量,建议使用连接符

scss
$font-size:14px;
// 同一
$font_size:14px;
$font-size:14px;
// 同一
$font_size:14px;

全局变量

方法一,在选择器最外部定义变量

方法二,使用!global

默认值

scss
$color:#333;
$color:#666!default; // 如果变量之前未定义就采用该默认值
$color:#333;
$color:#666!default; // 如果变量之前未定义就采用该默认值

与css遍历区别

CSS有自己的变量,与 Sass 变量完全不同。了解差异!

  • Sass 变量都被 Sass 编译掉了。CSS变量包含在CSS 输出中
  • CSS变量对于不同的元素可以有不同的值,但 Sass 变量一次只有一个值
  • Sass 变量是命令式的,这意味着如果你使用一个变量然后改变它的值,之前的使用将保持不变。CSS变量是声明性的,这意味着如果您更改值,它将影响早期使用和后期使用

@import

区别于less的@import url(),scss直接使用@import引入

@mixin

@mixin 定义重复的css,@include引入,支持类似函数的写法,传参定义属性

scss
@mixin block($width, $height) {
  width: $width;
  height: $height;
}
p {
  @include block(400px, 200px);
  color: #fff;
}
@mixin block($width, $height) {
  width: $width;
  height: $height;
}
p {
  @include block(400px, 200px);
  color: #fff;
}
scss
$skyblue: skyblue;
$red: pink;

$themes: (
  blue: (
    //主题 蓝
    //布局
    theme-background: $skyblue,
    theme-color: $red,
    // 按钮
    // btn-primary-background: $blue,
    // btn-primary-boder: 1px solid $blue,
    // btn-primary-color: #ffffff,
    // btn-primary-background-hover: #409eff,
    // btn-primary-boder-hover: 1px solid #409eff,
    // btn-primary-color-hover: #ffffff
  ),
  red: (
    theme-background: $red,
    theme-color: $skyblue,
    // 按钮
    // btn-primary-background: $red,
    // btn-primary-boder: 1px solid $red,
    // btn-primary-color: #ffffff,
    // btn-primary-background-hover: #f86065,
    // btn-primary-boder-hover: 1px solid #f86065,
    // btn-primary-color-hover: #ffffff
  )
);

//取出主题色
@mixin themify($themes) {
  @each $theme-name, $map in $themes {
    $myMap: $map !global; //全局变量供函数调用
    //新定义一个类
    .theme-#{$theme-name} {
      @content; //插入位置
    }
  }
}

//从主题色map中取出对应颜色
@function themed($key) {
  @return map-get($myMap, $key);
}

//按钮混合
// @mixin button($value: default) {
//   background-color: themed("btn-#{$value}-background");
//   border: themed("btn-#{$value}-color");
//   color: themed("btn-#{value}-color");
//   border: 1px solid;
//   width: 100px;
//   height: 50px;
//   border-radius: 10px;

//   &:hover {
//     background-color: themed("btn-#{$value}-background-hover");
//     border: themed("btn-#{$value}-border-hover");
//     color: themed("btn-#{$value}-color-hover");
//   }
// }

//全局类 使用混合方法
@include themify($themes) {
  .them_title {
    width: 100%;
    height: 40px;
    background-color: themed("theme-background");
    color: themed("theme-color");
  }

  // .them-btn-primary {
  //   @include button("primary");
  // }

  // .them-btn-info {
  //   @include button("info");
  // }
}
$skyblue: skyblue;
$red: pink;

$themes: (
  blue: (
    //主题 蓝
    //布局
    theme-background: $skyblue,
    theme-color: $red,
    // 按钮
    // btn-primary-background: $blue,
    // btn-primary-boder: 1px solid $blue,
    // btn-primary-color: #ffffff,
    // btn-primary-background-hover: #409eff,
    // btn-primary-boder-hover: 1px solid #409eff,
    // btn-primary-color-hover: #ffffff
  ),
  red: (
    theme-background: $red,
    theme-color: $skyblue,
    // 按钮
    // btn-primary-background: $red,
    // btn-primary-boder: 1px solid $red,
    // btn-primary-color: #ffffff,
    // btn-primary-background-hover: #f86065,
    // btn-primary-boder-hover: 1px solid #f86065,
    // btn-primary-color-hover: #ffffff
  )
);

//取出主题色
@mixin themify($themes) {
  @each $theme-name, $map in $themes {
    $myMap: $map !global; //全局变量供函数调用
    //新定义一个类
    .theme-#{$theme-name} {
      @content; //插入位置
    }
  }
}

//从主题色map中取出对应颜色
@function themed($key) {
  @return map-get($myMap, $key);
}

//按钮混合
// @mixin button($value: default) {
//   background-color: themed("btn-#{$value}-background");
//   border: themed("btn-#{$value}-color");
//   color: themed("btn-#{value}-color");
//   border: 1px solid;
//   width: 100px;
//   height: 50px;
//   border-radius: 10px;

//   &:hover {
//     background-color: themed("btn-#{$value}-background-hover");
//     border: themed("btn-#{$value}-border-hover");
//     color: themed("btn-#{$value}-color-hover");
//   }
// }

//全局类 使用混合方法
@include themify($themes) {
  .them_title {
    width: 100%;
    height: 40px;
    background-color: themed("theme-background");
    color: themed("theme-color");
  }

  // .them-btn-primary {
  //   @include button("primary");
  // }

  // .them-btn-info {
  //   @include button("info");
  // }
}

Released under the MIT License.