作者:19组清风

链接:https://juejin.cn/post/6996855468526141448

随着css工程化的普及,sass在前端工程中越来越举足轻重。当然sass并不局限于管理css全局变量、mixin之类的"脏活累活"。

这篇文章会跟随工程化前端一步一步记录sass中那些不为人知,但是又非常使用的小技巧分享给大家。

建议大家收藏随时观看。

内置函数

sass官网提供了很多实用的内置函数,当然目前我也是在一步一步探索这些函数。目前我会将常用到的内置函数以及场景分享给大家使用。

darken内置函数

定义

lighten()darken()两个函数都是围绕颜色的亮度值做调整的,其中lighten()函数会让颜色变得更亮,与之相反的darken()函数会让颜色变得更暗。这个亮度值可以是0~1之间。

lighten(#fff,10%) //原色的亮度值 增加百分之10亮度
draken(#fff,10%) // 在原色的基础上 减少百分之10亮度

应用场景

lightendarken这两个内置函数经常被用到元素被hover/focus时,当我们hover,一个元素的时候。此时并不希望改变这个元素的色值,但是又想要用户感知到鼠标停留在这个元素上。此时这两个内置函数就发挥了他们的作用了。

@mixin button-type($background,$border,$color,$hover-background: lighten($background, 7.5),$hover-border: lighten($border, 10%),$hover-color: $color
) {color: $color;background: $background;border-color: $border;&:hover {color: $hover-color;background: $hover-background;border-color: $hover-border;}&:focus,&.is-focus {color: $hover-color;background: $hover-background;border-color: $hover-border;}&[disabled],&.is-disabled {color: $color;background: $background;border-color: $border;}
}

desaturate

饱和度(Saturation)是指色彩的纯度,饱和度越高色彩越纯越浓,饱和度越低则色彩变灰变淡。

sass中的desaturate函数就是针对饱和度操作的内置方法。

desaturate($color, $amount) //=> color

使$color饱和度降低, 在$amount必须之间的数字0%100%(包含)。

@warn

When writing mixins[1] and functions[2], you may want to discourage users from passing certain arguments or certain values. They may be passing legacy arguments that are now deprecated, or they may be calling your API in a way that’s not quite optimal.

编写MixIn和函数时,您可能希望劝阻用户传递某些参数或某些值。他们可能正在传递现在已弃用的传统参数,或者他们可能会以不太最佳的方式调用您的API。

简单来说在mixin或者function内部,我们可以通过@warn操作符给用户提示一些警告内容输出在控制台。

@mixin prefix($property, $value, $prefixes) {@each $prefix in $prefixes {@if not index($known-prefixes, $prefix) {@warn "Unknown prefix #{$prefix}.";}-#{$prefix}-#{$property}: $value;}#{$property}: $value;
}

控制台会提示

Warning: Unknown prefix wekbit.example.scss 6:7   prefix()example.scss 16:3  root stylesheet

Inspect()断电函数

其实Inspect()函数用的比较少,主要是用来做校验类型的。

Inspect(...)表达式中的内容如果是正常会返回对应的内容,如果发生错误则会弹出一个错误提示。

Map相关内容

Map-has-key

If $keys is empty, returns whether $map contains a value associated with $key.

$font-weights: ("regular": 400, "medium": 500, "bold": 700);map.has-key($font-weights, "regular"); // truemap.has-key($font-weights, "bolder"); // false

map.has-key()scss中的条件判断时应用场景特别多。

比如下方这段代码

$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;$--breakpoints: ('xs' : (max-width: $--sm - 1),'sm' : (min-width: $--sm),'md' : (min-width: $--md),'lg' : (min-width: $--lg),'xl' : (min-width: $--xl)
);@mixin res($key, $map: $--breakpoints) {// 循环断点Map,如果存在则返回@if map.has-key($map, $key) {@media only screen and #{inspect(map-get($map, $key))} {@content;}} @else {@warn "Undefeined points: `#{$map}`";}
}

map.get(map,k1,k2,...)

简单来说就是通过keymap中取到对应的value

$config: (a: (b: (c: d)));
map.get($config, a, b, c); // d

占位符选择器%作用

定义

Sass 额外提供了一种特殊类型的选择器:占位符选择器 (placeholder selector)。与常用的 id 与 class 选择器写法相似,只是 #. 替换成了 %

比如:

%heading {margin-top: 0; // 1margin-bottom: $headings-margin-bottom;font-family: $headings-font-family;font-style: $headings-font-style;font-weight: $headings-font-weight;line-height: $headings-line-height;color: $headings-color;
}

应用场景

其实使用%在大多数(~所有~)场景下,我的理解就是和@mixin是一样的效果。使用%占位符选择器的样式,只能被@extend进行调用

需要注意的是,如果使用占位符选择器%定义的样式,单独使用的时候(未通过extend)进行调用,那么这段样式是不会编译到css的输出结果之后的。

Partials import

定义

css类似scss支持@import命令,但cssimport命令每次调用都会创建一个额外的html请求,但scssimport命令是编译时将文件包含在css中,不需要额外发起请求。

如果我们需要导入 SCSS 或者 Sass 文件,但又不希望将其编译为 CSS,只需要在文件名前添加下划线,这样会告诉 Sass 不要单独编译这些文件,但导入语句中却不需要添加下划线。

简单来说,项目目录中的所有scss文件在编译阶段都会被编译成为一个个css文件。

但是对于一个公用样式文件,此时我们并不需要将它编译成为单独的css文件,而是希望将公用文件中的样式插入到对应引入样式文件中,我们只需要在引入它的文件中将它编译进入引入的css文件中就可以。

此时给文件名称以_开头就可以告诉scss在编译阶段并不会将它编译成为单独的css文件,而是仅仅会将它的样式编译进入引入它的样式文件中去。

比如一个文件夹两个 scss 文件,一个 root.scss,一个 _vars.scss。

// 第一个 scss 文件夹名 -o 是输出文件夹名称``npx node-sass scss -o output``// 只会有一个文件生成
rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/root.css //将 _vars 该名称为 vars.scss 再执行一遍
Rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/root.css
Rendering Complete, saving .css file...
Wrote CSS to /Users/liusha/Public/vikingship/output/vars.css
会有两个文件生成

应用场景

这在组件库的开发中是非常有用的,定义单独组件的样式文件以Partials import进行定义,不单独打包成为css文件,在最终导入的样式文件中统一进行合并管理而不打包出单独的css文件。

变量声明globaldefault

!default 默认变量

可以在变量的结尾添加 !default 给一个未通过 !default 声明赋值的变量赋值,此时,如果变量已经被赋值,不会再被重新赋值,但是如果变量还没有被赋值,则会被赋予新的值。

比如这样一段代码:

$color:red;
$color:blue !default;.modules-a {color: $color; // red
}

我们可以看到即使是先声明的red,因为blue !default,所以红色覆盖了蓝色。!default声明变量的意思就是说如果项目中存在相同的声明则优先使用别的声明,如果不存在则使用!default的值,可以理解为默认值

!global全局声明

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

scss中我们都清楚局部变量的定义是无法影响同名的global变量的。但是我们可以通过!global在局部作用域中去定义一个全局都可以使用的变量同样也可以通过!default在局部作用域中去覆盖一个全局变量的值

#main {$width: 5em !global;width: $width;
}#sidebar {// 同样可以使用$width全局变量width: $width;
}

编译为

#main {width: 5em;
}#sidebar {width: 5em;
}

mixin

参数变量...

有时,不能确定混合指令需要使用多少个参数,比如一个关于 box-shadow 的混合指令不能确定有多少个 'shadow' 会被用到。这时,可以使用参数变量  声明(写在参数的最后方)告诉 Sass 将这些参数视为值列表处理.

其实就类似于js中的...rest运算符。

@mixin box-shadow($shadows...) {-moz-box-shadow: $shadows;-webkit-box-shadow: $shadows;box-shadow: $shadows;
}
.shadows {@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}

编译后:

.shadowed {-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

使用分隔为.shadowed元素添加多个阴影。

@content-- 向混合样式中导入内容

在引用混合样式mixin的时候,可以先将一段代码导入到混合指令中,然后再输出混合样式,额外导入的部分将出现在 @content 标志的地方

比如这样的代码,我们在include中填充了对应的样式,在mixin中可以通过@content使用。

@mixin apply-to-ie6-only {* html {@content;}
}
@include apply-to-ie6-only {#logo {background-image: url(/logo.gif);}
}

编译为

// mixin中接受了include 可以理解为插槽
* html #logo {background-image: url(/logo.gif);
}

为便于书写,@mixin 可以用 = 表示,而 @include 可以用 + 表示,所以上面的例子可以写成:

// = 简写mixin
=apply-to-ie6-only* html@content// + 简写include
+apply-to-ie6-only#logobackground-image: url(/logo.gif)

注意:  当 @content 在指令中出现过多次或者出现在循环中时,额外的代码将被导入到每一个地方。

@at-root

常规用法

@at-root指令可以使一个或多个规则被限定输出在文档的根层级上,而不是被嵌套在其父选择器下。

比如

.parent {...@at-root .child { ... }
}

编译之后.child并不会嵌套在任何规则之下,因为使用了@at-root选择符

.parent { ... }
.child { ... }

@at-root同样也可以当作一个作用域给多个选择器去使用:

.parent {...@at-root {.child1 { ... }.child2 { ... }}.step-child { ... }
}

编译后:

.parent { ... }
.child1 { ... }
.child2 { ... }
.parent .step-child { ... }

支持参数

@at-root (without: ...) and @at-root (with: ...)

默认使用@at-root不传递任何时,他的作用为跳出选择器的作用域嵌套,当然可以传递参数去使用。

比如下面的@at-root意为跳出@media的嵌套:

@media print {.page {width: 8in;@at-root (without: media) {color: red;}}
}
@media print {.page {width: 8in;}
}
.page {color: red;
}

默认 @at-root 只会跳出选择器嵌套,而不能跳出@media@support,如果要跳出这两种,则需使用 @at-root(without: media)@at-root(without: support)。这个语法的关键词有

四个:

  • all(表示所有)

  • rule(表示常规,默认行为。

  • media(表示 media

  • support(表示 support )。

我们默认的 @at-root 其实就是 @at-root( without: rule ):跳出作用域嵌套规则。

  1. @at-root(without: rule)

rule 关键词只能跳出选择器嵌套,不能跳出 @media@support

  1. @at-root(without: media)

可以跳出 @media ,但是没有跳出父级选择器

  1. @at-root(without: support)

@at-root(without: support)@at-root(without: media) 相似,只是跳出的是 @support。

  1. @at-root(without: all)

@at-root(without: all) 是跳出所的指令和规则,如上面的代码里 @at-root(without: media rule) 我们可以换成 @at-root(without: all),效果是一样的。

@each in

maps数据格式

首先我们来说说在scss中定义类似js中的对象。

$map: (key1: value1, key2: value2, key3: value3);

我们通过()就可以定义了。比如这样的Maps结构定义。

$blue: #0d6efd !default;
$indigo: #6610f2 !default;
$purple: #6f42c1 !default;
$pink: #d63384 !default;
$red: #dc3545 !default;
$orange: #fd7e14 !default;
$yellow: #fadb14 !default;
$green: #52c41a !default;
$teal: #20c997 !default;
$cyan: #17a2b8 !default;$primary: $blue !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $cyan !default;
$warning: $yellow !default;
$danger: $red !default;
$light: $gray-100 !default;
$dark: $gray-800 !default;$theme-colors: ('primary': $primary,'secondary': $secondary,'success': $success,'info': $info,'warning': $warning,'danger': $danger,'light': $light,'dark': $dark,
);

我们定义了一个maps的主题,分别存在对应的名称和对应的颜色值。

@each in

@each 指令的格式是 $var in <list>$var 可以是任何变量名,比如 $length 或者 $name,而 <list> 是一连串的值,也就是值列表。

"数组"迭代

@each 将变量 $var 作用于值列表中的每一个项目,然后输出结果,例如:

@each $animal in puma, sea-slug, egret, salamander {.#{$animal}-icon {background-image: url('/images/#{$animal}.png');}
}

编译为

.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'); }

此时类似于js中的数组迭代。

对象迭代

当然@each $val,$key in maps,也支持"迭代"一个对象(maps)。比如:

@each $key, $value in $theme-colors {.#{$prefix}-icon--#{$key} {color: $value;}
}

这样我们就迭代了上边定义的$theme-colors这个对象,并且取得了他的key,value

多个值迭代

The @each directive can also use multiple variables, as in @each v a r 1 , var1, var1,var2, ... in . If is a list of lists, each element of the sub-lists is assigned to the respective variable. For example:

@each 指令也可以使用多个变量,如@each $var1, $var2, ... in 。如果是列表列表,则子列表的每个元素都分配给相应的变量。例如

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

is compiled to:

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

css :scope选择器

偶然在写jest中看到别人使用xxx.querySelect(':scope')。感到比较新奇随机查阅记录一番。

在JavaScript中,当用于`Element.querySelector`[3],`Element.querySelectorAll`[4]或`Element.closest`[5]时,:scope是指调用这些方法的元素。例如,document.body.querySelector(":scope")返回body元素。尽管CSS对 :scope的支持已被移除,但 :scope 的这种用法仍然被支持

使用:scope选择器可以匹配对应的方法比如element.querySelector(':scope')则会返回element元素本身。

需要主要的是:scope伪类在css中已经不被大多数浏览器支持,甚至已经废弃。但是在js这些方法中仍然被主流浏览器支持。

参考资料

[1]

https://sass-lang.com/documentation/at-rules/mixin: https://link.juejin.cn?target=https%3A%2F%2Fsass-lang.com%2Fdocumentation%2Fat-rules%2Fmixin

[2]

https://sass-lang.com/documentation/at-rules/function: https://link.juejin.cn?target=https%3A%2F%2Fsass-lang.com%2Fdocumentation%2Fat-rules%2Ffunction

[3]

https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelector: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FElement%2FquerySelector

[4]

https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FElement%2FquerySelectorAll

[5]

https://developer.mozilla.org/en-US/docs/Web/API/Element/closest: https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.mozilla.org%2Fen-US%2Fdocs%2FWeb%2FAPI%2FElement%2Fclosest

【SCSS】1300- 这些 SCSS 使用技巧真好用~相关推荐

  1. 【SCSS】vue3+vite项目引入SCSS及使用SCSS全局变量

    vue3+vite项目引入SCSS及使用SCSS全局变量

  2. uniapp 添加scss全局变量、scss公共类

    一.创建scss变量文件variable.scss和公共类文件common.scss,放在目录/src/static/css/下 variable.scss // 主题色 $primary-color ...

  3. 在VUE项目中使用SCSS ,对SCSS的理解和使用(简单明了)

    首先要了解什么是CSS 预处理器? SCSS是一种CSS预处理语言 定义了一种新的专门的编程语言,编译后形成正常的css文件,为css增加一些编程特性,无需考虑浏览器的兼容性(完全兼容css3),让c ...

  4. SCSS 中这些技巧,你可能还不知道!

    大厂技术  高级前端  Node进阶 点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 作者:19组清风 链接:https://juejin.cn/post/69968554685 ...

  5. SCSS 中这些实用技巧,你可能还不知道!

    大厂技术  高级前端  Node进阶 点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 作者:19组清风 链接:https://juejin.cn/post/69968554685 ...

  6. scss 变量_SCSS和Sass使用这种样式语言所需的所有CSS和SCSS代码

    我们来看一下SCSS和Sass,浏览一下所有CSS和SCSS代码,您需要从这种样式语言开始. 在这篇文章中,我想介绍并讨论SCSS的功能.如果您是SCSS的新手并且您真的没有阅读过很多内容,那么您一定 ...

  7. Sass、Scss、Less和Stylus区别总结

    Sass.Scss.Less.Stylus CSS 预处理器技术已经非常的成熟了,而且也涌现出了越来越多的 CSS 的预处理器框架.本文便总结下 Sass.Less CSS.Stylus这三个预处理器 ...

  8. Sass和Scss的区别

    区别: Sass 和 SCSS 其实是同一种东西,我们平时都称之为 Sass,两者之间不同之处有以下两点: Sass是以".sass"后缀为扩展名,Scss是以scss后缀为扩展名 ...

  9. CSS预处理器 Sass/Scss

    文章目录 介绍 Sass是什么 Scss是什么 Scss 与 Sass异同 为什么使用 Sass? Sass 安装 NPM 安装(推荐使用) Windows 上安装 Mac OS X (Homebre ...

最新文章

  1. SPOJ 694 不同子串个数
  2. 文献阅读|Dynamic-SLAM
  3. 基因组组装的那些困扰,用单倍体基因组一一破解!
  4. Hierarchy of Log-Cauchy
  5. 怎么往integer型数组添加数据_面试中经常问到的Redis七种数据类型,你都真正了解吗?...
  6. 腾讯云cloudlite认证_【腾讯云】考个证...大数据开发工程师认证
  7. [渝粤教育] 西南科技大学 现代企业管理 在线考试复习资料
  8. 计算机专业大学排名_U.S.News全美大学排名出炉:UCLA超越伯克利;计算机MIT排第一,斯坦福跌出前四...
  9. unity3d 剧情制作_游戏设计作品集干货:跨专业如何入门 Unity3D 游戏引擎?
  10. 获取当前周和前一周周一和周天,下一周周一和周天
  11. java final 函数_JAVA中Final的用法
  12. MySQL Workbench 导入导出乱码解决方法
  13. xp系统计算机无法用搜索功能,XP系统搜索功能无法使用的六种解决方法
  14. 青鸟影院的最后一部分
  15. 为什么要购买域名?如何购买域名?
  16. 高速公路自动驾驶测试场景库
  17. JS 下载 URL 链接文件(点击按钮、点击a标签、支持代理与非代理下载)
  18. PacBio相关知识
  19. 集线器、交换机和路由器(图解)
  20. ChatGPT:开启智能对话的未来

热门文章

  1. 2020校招搜狗笔试
  2. 学生学习时长统计--python程序设计
  3. C语言简单直观打印二叉树
  4. html中表格行删除的方法,HTML删除表格行中的空格
  5. 随笔之与潇哥交谈1h12min内容//2021-1-28【最后一个寒假作业】
  6. 黑马程序员-java基础8--IO流(一)
  7. mac常见问题(五) Mac 无法开机
  8. Windows Postman中文版
  9. 【C语言训练】自由落体问题
  10. 第7章第30节:四图排版:四张图片交错对齐排列 [PowerPoint精美幻灯片实战教程]