基本了解
SASS是成熟,稳定,强大的 CSS预处理器 ,而 SCSS 是SASS3版本当中引入的新语法特性,完全兼容CSS3的同时继承了CSS强大的动态功能。(官网说了很多..um…总之SCSS 是 Sass 的其中一种语法规则而已,即 SCSS 是 Sass 的子集)
之前的笔记也写过另外一个css预处理器 -Less - 看这里
安装
基于webpack (Vue)
如果是在 vue-cli 项目中,可以使用以下命令安装
npm install node-sass --save-dev
npm install sass-loader --save-dev
或者
yarn add sass-loader node-sass --dev
vue-cli生成的项目,已经默认加入了处理sass的loader
只需要在需要的地方加入lang=scss
即可
<style lang='scss' scope>
...
</style>
是基于webpack
按照官网教程,手动把 scss
编译成 css
文件,然后自己引入。
确认版本
$ sass -v
文件生成
在屏幕上显示.scss文件转化的css代码。(假设文件名为test。)
sass test.scss
如果要将显示结果保存成文件,后面再跟一个.css文件名。
sass test.scss test.css
SASS监听文件/目录
生产环境当中,一般使用最后一个选项。
sass --style compressed test.sass test.css
你也可以让SASS监听某个文件或目录,一旦源文件有变动,就自动生成编译后的版本 - 监听 app/sass
目录下所有文件的变动,并 编译 CSS 到 public/stylesheets
目录下。
// watch a file
sass --watch input.scss:output.css
// watch a directory
sass --watch app/sass:public/stylesheets
语法
变量- $
// _variables.scss
$basic-font-size: 16px;
$primary-color:#fa0;
// layout.scss
body{
font-size:$basic-font-size;
}
// layout.css
body {
font-size: 16px;
}
计算
div {
margin: 12px * 2;
top: 50px + 100px;
right: $var * 10%;
}
article[role="main"] {
float: left;
width: 600px / 960px * 100%;
}
aside[role="complementary"] {
float: right;
width: 300px / 960px * 100%;
}
条件判断 if else
@if lightness($color) > 30% {
background-color: #000;
} @else {
background-color: #fff;
}
进阶会变成
//SCSS
@mixin blockOrHidden($boolean:true) {
@if $boolean {
@debug "$boolean is #{$boolean}";
display: block;
}
@else {
@debug "$boolean is #{$boolean}";
display: none;
}
}
.block {
@include blockOrHidden;
}
.hidden{
@include blockOrHidden(false);
}
/*编译后*/
.block {
display: block;
}
.hidden {
display: none;
}
#{}
插值
遍历写法 for
基本语法
@for $i from <start> through <end>
@for $i from <start> to <end>
简单例子
through
// 生成 .f12 {font-size: 12px} .... .f30 {font-size: 30px}
@for $i from 12 through 30 {
.f_#{$i} {
font-size: #{$i}px;
}
}
@each $member in a, b, c, d {
.#{$member} {
background-image: url("/image/#{$member}.jpg");
}
}
// 在列表里面用下标取数据
$colors: #7FA0FF, #98BDFF, #A1D2B6, #FFDB46, #FFB63E, #F77C7A, #696CC9, #787EF3;
@for $i from 1 through 8 {
.label:nth-child(#{$i}):before {
background: nth($pieColors, $i);
}
}
to
@for $i from 1 to 3 {
.item-#{$i} { width: 2em * $i; }
}
/*编译后*/
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
嵌套 {}
div {
h1 {
color:red;
}
}
//属性也可嵌套(用的较少)
div {
border: {
color: red;
}
}
//在嵌套的代码块内,可以使用&引用父元素。比如a:hover伪类,可以写成:
a {
&:hover { color: #f00; }
}
@while循环
//SCSS
$types: 4;
$type-width: 20px;
@while $types > 0 {
.while-#{$types} {
width: $type-width + $types;
}
$types: $types - 1;
}
.while-4 {
width: 24px;
}
.while-3 {
width: 23px;
}
.while-2 {
width: 22px;
}
.while-1 {
width: 21px;
}
@each循环
基本语法
var in <list>
$
基本例子
$list: a b c d e;/*$list 就是一个列表*/
@mixin author-images {
@each $author in $list {
.photo-#{$author} {
background: url("/images/avatars/#{$author}.png") no-repeat;
}
}
}
.author-bio {
@include author-images;
}
.author-bio .photo-a {
background: url("/images/avatars/a.png") no-repeat; }
.author-bio .photo-b {
background: url("/images/avatars/b.png") no-repeat; }
.author-bio .photo-c {
background: url("/images/avatars/c.png") no-repeat; }
.author-bio .photo-d {
background: url("/images/avatars/d.png") no-repeat; }
.author-bio .photo-e {
background: url("/images/avatars/e.png") no-repeat; }
import 引入-@import
@import "reset"; // 重設css
@import "variables"; // 所有變數都存放於此
@import "mixins"; // 所有mixin相關的scss
// 本地文件
@import "filepath";
// 第三方文件
@import url("file's url")
extend 继承- @extend
有很多 css 样式需要复用,就可以用继承,语法是 @extend,可以在继承的 css 前加入 % 符號,只有被继承的 css 会被编译,原 extend 语法不會被编译,% 表佔位符,所以套用 %继承的样式位置在文件中會往前提升, 继承同一個 css 的 class,编译出的內容会放在一起。
.super {
color: red;
}
.sub {
@extend .super;
font-size: 12px;
}
%clearfix{ // 用%(佔位符)不會被scss编译 class的(.)不用写 但@extend时也要加上%
&:after{
content: '';
display: table;
clear: both;
}
}
// 垂直居中
%vertical-center{
position: relative;
top:50%; // 外层空間向下移50%
transform: translateY(-50%);//内层空間往上移50%
}
%_d-b{
display: block;
}
.box{
@extend %clearfix; // class的(.)不用写
}
._rwdimg{
@extend %_d-b;
max-width:100%;
height:auto;
margin:0 auto;
}
辅助extend的!optional
如果故意 extend 不存在的样式名称,则会编译出错, 加上「!optional」修饰词,以表示当 extend 不存在样式名称时候,就不会做 render。
.notice {
color: blue;
font-weight: bold;
font-size: 2em;
}
.important {
@extend .notice2 !optional;
}
@extend in @media
在 @media 范围里面使用 @extend 呼叫指定样式名称时候,该样式名称不能放在 @media 范围之外,否则会出错, 应该把样式名称放在 @media 范围里面才行。
// layout.scss
@media screen and (max-width:960px){
// 用 % 版本會出錯 因為本身不會被編譯
// %vertical-center{
// position: relative;
// top:50%;
// transform: translateY(-50%);/
// }
.vertical-center{
position: relative;
top:50%;
transform: translateY(-50%);
}
.box{
@extend .vertical-center;
}
}
// layout.css
@media screen and (max-width: 960px) {
.vertical-center, .box {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
}
内置函数
// 如颜色的
lighten(#cc3, 10%) // #d6d65c
darken(#cc3, 10%) // #a3a329
grayscale(#cc3) // #808080
complement(#cc3) // #33c
字符串函数-unquote()函数
unquote($string):删除字符串中的引号;
quote($string):给字符串添加引号。
unquote( ) 函数只能删除字符串最前和最后的引号(双引号或单引号),而无法删除字符串中间的引号。如果字符没有带引号,返回的将是字符串本身
使用 quote() 函数只能给字符串增加双引号,而且字符串中间有单引号或者空格时,需要用单引号或双引号括起,否则编译的时候将会报错。
.test {
content: unquote("'Hello Sass!");
}
.test {
content: unquote("'Hello Sass!'");
}
.test {
content: unquote('"Hello Sass!"');
//编译
.test {
content: unquote('Hello Sass!);
}
.test {
content: unquote('Hello Sass!');
}
.test {
content: unquote("Hello Sass!");
}
.test {
content: quote(ImWebDesigner);
}
.test {
content: quote(' ');
}
//编译
.test {
content: quote("ImWebDesigner");
}
.test {
content: quote(" ");
}
字符串函数-To-upper-case()、To-lower-case()
数字函数-percentage()
width : percentage(.2) // width : 20%
数字函数-round()函数 ceil()函数 floor()函数 abs()函数
width:round(12.3px)// width: 12px;
width:ceil(12.3px);//13px
width:floor(12.3px);//12px
width:abs(-12.3px);//12.3px
数字函数-min()函数、max()函数 random()函数
单位注意要一样的!!!!!
>> min(1,2,1%,3,300%)
1%
>> max(1,5)
5
自定义函数- @function
// _variables.scss
$basic-font-size:16px;
$primary-color:#fa0;
// _function.scss 或是 _mixins.scss
@function toRem($px){
@return ($px / basic-font-size) * 1rem;
}
// layout.scss
@import "helpers/variables";
@import "mixins/mixins";
h1{
font-size : toRem(32px);
}
.btn{
background-color: $primary-color;
&:hover{
background-color: darken($primary-color, 15%);
}
}
s
//layout.css
h1{
font-size : 2rem;// 转换单位px->rem
}
.btn {
background-color: #fa0;
}
.btn:hover {
background-color: #b37700; // hover颜色加深15%
}
混用 (Mixin) -@mixin
混用-总是混的( ╯□╰ )
Mixin 跟 extend 最大的不同 →
Mixin 是产生多个样式;extend 是将样式全部集中管理。
// _mixins.scss
@mixin svg-icon($icon, $width, $height){
background: url("images/#{$icon}.png");
background:none, url("images/#{$icon}.svg");
// ie8以下不支持 會跑上面的,新浏览器都可以支持高像素的svg
width: $width;
height: $height;
}
// _layout.scss
.icon-youtube{
@include svg-icon('icon',120px,120px)
}
// _layout.css
.icon-youtube {
background: url("images/icon.png");
background: none, url("images/icon.svg");
width: 120px;
height: 120px;
}
搭配 media
// mixins.scss
// content
@mixin mobile{
@media screen and (max-width:767px) {
@content;
}
}
// layout.scss
.container{
@include mobile{
background: #fff;
}
}
//layout.css
@media screen and (max-width: 767px) {
.container {
background: #fff;
}
}
推荐工具
vscode 中 Live Sass Compiler
!!写完scss 直接回生成css 但是记得点击右下方的watch!!!
Vue scss 踩坑
这里实践写的是 vue+element的admin
报错 TypeError
Syntax Error: TypeError: this.getOptions is not a function
@ ./node_modules/vue-style-loader??ref--8-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--8-oneOf-1-1!./node_modules/vue-loader-v16/dist/stylePostLoader.js!./node_modules/postcss-loader/src??ref--8-oneOf-1-2!./node_modules/sass-loader/dist/cjs.js??ref--8-oneOf-1-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader-v16/dist??ref--0-1!./src/App.vue?vue&type=style&index=0&id=7ba5bd90&lang=scss 4:14-419 14:3-18:5 15:22-427
@ ./src/App.vue?vue&type=style&index=0&id=7ba5bd90&lang=scss
@ ./src/App.vue
@ ./src/main.js
yarn add sass-loader@^10.1.1
报错 TypeError
TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string.
报错 UnhandledPromiseRejectionWarning
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict`
版本问题!!!这真的是 /(ㄒoㄒ)/~~ (下面是7.3.1 练习的时候用的是7.3.0)
npm install sass-loader@7.3.1 --save-dev
npm install --save-dev node-sass
报错 sass-loader@11.0.1“ has incorrect peer dependency “webpack@^5.0.0”.
Similar to what @KostDM said, in my case it seems like sass-loader@11.0.0 doesn’t work with vue@2.6.12.
I installed sass-loader@10.1.1 and it worked like a charm again.
解决: yarn add sass-loader@^10.1.1
报错 Node Sass version 5.0.0 is incompatible with ^4.0.0.
Node Sass version 5.0.0 is incompatible with ^4.0.0.
npm uninstall node-sass
npm install node-sass@4.14.1
Or, if using yarn (default in newer CRA versions)
yarn remove node-sass
yarn add node-sass@4.14.1
报错 Cannot find module ‘node-sass’
Module build failed: Error: Cannot find module 'node-sass'
npm install node-sass