Scss

yuhuo2022-03-28开发库样式库

Scss 官网open in new window

编译方式

方式一:

安装 sass 包

npm install sass

使用 sass 包编译

const sass = require('sass');

const result = sass.compile(scssFilename);

方式二:

使用编译工具,比如 webpack,通过 sass-loader 调用 sass 包进行编译。

关于

node-sass 包已弃用,改用 sass 包。

因为 node-sass 是在 Node 环境下调用基于 C/C++ 实现的 LibSass,安装时会有各种版本环境问题。而 sass 基于 Dart,可以编译成 js,直接在 Node 下运行。

如果需要使用 node-sass,在 npm 安装时,有一步是到 github 上下载文件的,通常会失败,可以单独设置个映射:npm config set sass_binary_site=https://registry.npmmirror.com/node-sass

导入

内部导入

// 相对路径,直接导入
@import "./scss/one", "./scss/two";
// 绝对路径,嵌套导入
.container {
    @import "@/views/style/scss/scss/one";
}

标签导入

<style lang="scss" scoped src="./scss/one.scss"></style>

注意

  • 文件 A 中 import 文件 B,B 的代码会照搬到 A 中 import 的位置,因此 B 中代码使用到相对路径是相对于 A 的,需谨慎使用。A 的 import 后面的代码可以使用 B 中的定义的变量,混合器,继承等。
  • 局部文件使用 _ 开头,如 _ one.scss,编译后不会生成单独的 css 文件。
  • 引用时可省略文件名后缀 .scss,以及局部文件的开头 _
  • 正常情况下,css@import 会等浏览器解析时才加载该 css 文件,多个 scss 会生成多个 css 文件,但在当前 vue3 项目的同个页面下,都会被 webpack 打包成一个统一的 css 文件。

注释

$version: "1.2.3";
/* 
    css 标准注释,会出现在生成的css文件中,但压缩模式下会删除。 
    使用变量:#{$version}
*/
// scss 静默注释,不会出现在生成的css文件中

变量/嵌套

// 块级作用域,下划线_和中划线-连接符都可
$base_color: #111;
// 后者覆盖前者
$base_color: #222;
// 默认变量,权重最低,能被前者覆盖
$base_color: #333 !default;

.box {
    height: 200px;
    // 群组嵌套
    .content, .part {
        .name {
            // 变量引用变量
            $base_border: 2px solid $base_color;
            // 定义全局变量
            $fontSize: 16px !global;
            // 父选择器
            &:hover {
                color: red;
            }
        }
        // 使用全局变量
        font-size: $fontSize;
    }
}

混合器

// 无参数
@mixin namePadding {
    padding-top: 10px;
}
// 带参数
@mixin nameFont($fontSize, $i, $label) {
    // 插值语句 #{}
    // 选择器中使用
    .name:nth-child(#{$i}) {
        font-size: $fontSize;
    }
    .name_#{$label} {
        // 属性名中使用
        #{$attr}-size: $fontSize;
    }
}
// 参数带默认值
@mixin nameColor($normal, $hover: $normal, $visited: red) {
    .name {
        color: $normal;
        // 拼接成选择器名,等同于 .name_label
        &_label {
            color: black;
        }
        &:active {
            color: $visited;
        }
    }
}
// 带内容
@mixin nameText($align) {
    .name {
        text-align: $align;
        @content;
    }
}

.box {
    // 引用混合器
    .name {
        @include namePadding;
    }
    // 按顺序传参
    @include nameFont(30px, 1, "label");
    // 按名称传参
    @include nameFont($i: 1, $fontSize: 20px, $label: "label");
    // 使用参数默认值
    @include nameColor(blue);
    // 传混合器导入内容
    @include nameText(center) {
        text-shadow: none;
    }
}

继承

.error {
    margin-top: 20px;
    span {
        font-style: italic;
    }
}
div.error {
    color: red;
}
// 占位选择器,专门用来被extend,不会被单独编译
%extreme {
    letter-spacing: 1px;
}
// 继承了.error相关的所有样式
// 即所有的.error替换成.error,.seriousError
.seriousError {
    @extend .error;
    @extend %extreme;
    text-decoration: underline;
}

错误用法

// 不要用后代选择器去继承(如下)否则情况会变得复杂
.main .seriousError {
    @extend .error;
}
// 不要跨@media层去继承外部的样式,必须在同一层中
@media print {
    .seriousError {
        @extend .error;
    }
}

注意

  • 混合器用于展示性样式的重用,是对属性的复制。
  • 继承用于语义化样式的重用,是对选择器的复制。

运算

数字运算

$font-size: 12px;
.avatar {
    width: (40px + 10px) * 2 / 2;
    // 使用#{}给变量,以确保 / 被当成分隔符而不是除法运算
    font: #{$font-size} / 30px sans-serif;
    
    // random() 生成 0 ~ 1 的随机小数(包含0不包含1)
    font-size: random() + px;
    // random(x) 生成 1 ~ x 的随机整数(包含1和x)
    font-size: 12 + random(10) + px;
}

颜色运算

$color: rgba(255, 0, 0, 0.5);
.avatar {
	color: (#101010 + #202020) * 2 / 2;
    // alpha值必须相同才能运算
    color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
    // 增加alpha
    color: opacify($color, 0.2);
    // 减少alpha
    color: transparentize($color, 0.2);
    // rgba转#AABBCCDD
    color: ie-hex-str($color);
    // 色相-饱和度-亮度函数
    color: hsl(0, 100%, 50%);
}

字符串运算

$height: "50px";
.avatar {
	// #{}将有引号转为无引号(可用于选择器)
    height: #{$height};
    // 编译结果有无引号看 + 的左侧
    cursor: poin + "ter"; // 无引号
    // #{}添加动态的值
    content: "Foo #{5 + 10} " + Bar; // 有引号
}

数组运算

.avatar {
	$arr1: 10px auto;
    $arr2: 0 auto;
    // $separator 拼接符:comma 逗号,space 空格,auto 自动(默认)
    // 拼接数组
    margin: join($list1: $arr1, $list2: $arr2, $separator: auto);
    // 遍历数组
    @each $var in $arr1 {
        margin-top: $var;
    };
    // 数组添加新值
    margin: append($list: $arr1, $val: 0, $separator: space);
    // 取数组中的某项值
    margin-top: nth($list: $arr1, $n: 1);
}

指令

@media

$media: screen;
$feature: -webkit-min-device-pixel-ratio;
$value: 1.5;
// 使用插值语句
@media #{$media} {
    .sidebar {
        // 嵌套媒体查询
        @media ($feature: $value) {
            width: 500px;
        }
    }
}
// 编译为如下
// @media screen and (-webkit-min-device-pixel-ratio: 1.5) {
//     .sidebar[data-v-141e8fb2] {
//         width: 500px;
//     }
// }

@at-root

.parent {
    // 从嵌套移动到根作用域上
    @at-root .child {
        width: 10px;
    }
    @at-root {
        .child1 {
            width: 10px;
        }
        .child2 {
            width: 10px;
        }
    }
}

@if

// 常用于对混合器的参数判断
$type: 1;
.if {
    @if $type == 1 {
        color: blue;
    } @else if $type == 2 {
        color: red;
    } @else if $type == 3 {
        color: green;
    } @else {
        color: black;
    }
}

@for

@for $i from 1 through 3 {
    .for-#{$i} {
        width: 2em * $i;
    }
}

@each

// 遍历一维数组
@each $animal in puma, slug, egret, salamander {
    .#{$animal}-icon {
        background-image: url("/images/#{$animal}.png");
    }
}
// 遍历二维数组
@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;
    }
}
// 遍历对象
@each $key, $value in (h1: 2em, h2: 1.5em, h3: 1.2em) {
    #{$key} {
        font-size: $value;
    }
}

@while

$i: 6;
@while $i > 0 {
  .while-#{$i} { width: 2em * $i; }
  $i: $i - 2;
}

@function

$grid-width: 40px;
$gutter-width: 10px;
// 自定义函数
@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}
// 使用函数
.avatar { 
    width: grid-width(5); 
}
Last Updated 2024/3/14 09:51:53