SaSS
全称syntactically awesome style sheets(中文翻译为“语法上很棒的样式表”),并且自喻为拥有超能力的CSS
,听着就特别臭美。SaSS
于2007年诞生,是对CSS
的功能扩展,想要帮助开发者更轻松地,更高效的写样式表。
⚠️ 浏览器是无法直接理解SaSS
的,我们需要一个编译器,把SaSS
翻译成CSS
。
SaSS开发了两种语法:
缩进语法 (Indented Syntax
):用缩进取代了冒号和花括号,文件后缀为*.sass
ScSS语法(Superset Syntax
是CSS
的超集),文件后缀为*.scss
。是对 CSS
语法的扩充。也就是说,所有符合 CSS
语法的样式表也都是具有相同语法意义的 SCSS
文件。➡️ 主流
SaSS在本地的安装
与其他包一眼,我们可以用npm
或者brew
来安装:
npm
:npm install -g sass
brew
:brew install sass/sass/sass
两者达到的效果是一样的,都是本地环境的全局安装(在你电脑所以路径都能使用)。安装之后,我们就可以用sass
命令行工具将sass
编译成css
文件了,比如:
sass index.scss index.css
参见[官方文档]{https://sass-lang.com/install}
SaSS在React项目的安装本地安装时我们一般使用全局安装(global
)。项目中sass
更偏向于局部安装。比如在某个react项目中,我会用:
npm install sass
安装成功后我能在我react项目的package.json
中看到:
ScSS的基础语法
因为scss
是css
的超集,所以所有css
的语法在scss
中都是有效的。在此之外,scss
还提供了以下功能:
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
⚠️ 现在的css
语法中也有变量了(var(--blue);
)
2. 嵌套(nesting)
特别适用大型项目。嵌套实现了代码的重用,并且大大提高了准确性。
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
li {
display: inline-block;
}
}
}
3. 模块(modules)
模块使不同的scss
文件可以相互引用
// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
使用关键词@use
,我们可以在styles.scss
文件中引用_base.scss
,比如某个变量base.$primary-color
// styles.scss
@use 'base';
.inverse {
background-color: base.$primary-color;
color: white;
}
⚠️注意到
_base.scss
文件名前面的下划线了吗?它的存在是有意义的:
一般来说,Sass 直接编译所有*.scss
文件。 但是,当你导入文件时,你并不希望scss
文件被编译成css
。不然的话,像变量base.$primary-color
之类的东西都没法用了 !
➡️ 像_base.scss
这样的文件被称为 Partials(部分)
@use VS @import⚠️注意到我们使用
_base.scss
时只提了base
吗
Sass 默认对 Partials的使用需要忽视下划线,
从根本上说,@use
和@import
这个语法都做同样的事情 --> 在另一个模块中加载另一个模块。
@import
使目标文件中的所有内容都可以全局访问。 这使得导入文件的链无穷无尽,很难追踪变量和 mixin
的来源。@import
还允许规则重写,并且很难追溯完美的 CSS 中断的原因 ➡️ 这就是SaSS不再推荐使用 @import
的原因。@use
规则使我们能够将样式表分解为更实用、更小的部分,并将它们加载到其他样式表中。用法中最重要的就是 Partials4.扩展/继承(extend/inheritance)
又是一个提高代码重用率的宝宝。
首先,用百分号%
定义要被继承的父样式shared
%shared {
font-family: sans-serif;
font-size: medium;
color: white;
}
使用:
// 不对父样式进行任何修改
.text {
@extend %shared;
}
// 以下两个选择器继承并扩展了父样式:
.warning {
@extend %shared;
background-color: red;
}
.success {
@extend %shared;
background-color: green;
}
⚠️ 父样式%xxx
的内容不会 单独 被编译成css
,无论它是否被用到。上面的scss代码编译之后应该长这样:
.text {
font-family: sans-serif;
font-size: medium;
color: white;
}
.warning {
font-family: sans-serif;
font-size: medium;
color: white;
background-color: red; // ⬅️ 扩展
}
.success {
font-family: sans-serif;
font-size: medium;
color: white;
background-color: green; // ⬅️ 扩展
}
5. 混入(mixins)
混入的目的是提高代码重用,特别适用于写“主题”。主要与两个关键词相关@mixin
和@include
。
假设我要建一个类似wordpress的网站。我想要我的整个网页有一致的设计和颜色搭配,比如导航栏(navigator
),d出框(modal
)。首先,定义一个名为myTheme
的mixin
@mixin myTheme {
background-color: lightpink;
font-size: 25px;
font-weight: bold;
}
使用mixin:
.navigator {
@include myTheme;
}
// 使用+扩展
.modal {
@include myTheme;
border: 1px solid blue;
}
混入 vs 扩展/继承❓问:这个混入和 **扩展/继承(extend/inheritance)**有什么区别,为什么需要他们同时存在?
❗️答:混入更强大,因为它能使用变量
假设我要建一个类似wordpress的网站,这个网站中应该又很多不同的主题供用户选择。与函数类似,我们先定义一个mixin的模版,名为theme
。并为参数定义默认值
@mixin theme($color: lightpink, $size: 25px) {
background-color: $color;
font-size: $size;
font-weight: bold;
}
在使用时,我们对mixin的模版进行传参,重写覆盖默认值:
// 使用原有的默认值
.navigator {
@include theme;
}
// 传入新值,覆盖默认值
.new-navigator {
@include theme($color: darkorange, $size: 20px);
border: 1px solid blue;
}
应用场景
TODO
除了我们距离用到的网页主题之外,还有一种用法也很常见,那就是vendor prefixes - 用mixins来声明浏览器相关的属性。举例:
@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
transform: $property;
}
.myBox {
@include transform(rotate(20deg));
}
6.数学 *** 作符(operators)
包括加(+
)减(-
)乘(*
)除(math.div()
),和取整(%
)。在使用前要先导入math的包
@use "sass:math";
article[role="main"] {
width: math.div(600px, 960px) * 100%;
}
ScSS的内置函数 1. 字符串相关函数(string)
…用于 *** 作和获取有关字符串的信息。
⚠️ Sass 字符串是从 1 开始数的!
函数 | 描述 | 例子 | 输出结果 |
---|---|---|---|
quote(string) | 添加字符串,并返回结果。 | quote(Hello World) | “Hello world” |
str-index(string, substring) | 返回字符串中,某子字符串第一次出现的位置。 | str-index("Hello world!", "H") | 1 |
str-insert(string, insert, index) | 在字符串的某指定位置中插入另一个字符串 | str-insert("Hello world!", " wonderful", 6) | “Hello wonderful world!” |
str-length(string) | 计算字符串的长度 | str-length("Hello world!") | 12 |
str-slice(string, start, end) | 从字符串中提取字符 | str-slice("Hello world!", 2, 5) | “ello” |
to-lower-case(string) | 返回大写的字符串 | to-lower-case("Hello World!") | “hello world!” |
to-upper-case(string) | 返回小写的字符串 | to-upper-case("Hello World!") | “HELLO WORLD!” |
unique-id() | 生成唯一随机生成的字符串 | unique-id() | tyghefnsv |
unquote(string) | 除去字符串的引号 | unquote("Hello world!") | Hello world! |
函数 | 描述 | 例子 | 输出结果 |
---|---|---|---|
abs(number) | 返回数字的绝对值。 | abs(-15) | 15 |
ceil(number) | 向上四舍五入取整 | ceil(15.20) | 16 |
comparable(num1, num2) | 查看两个值是否有可比性 | comparable(20mm, 1cm) | true |
`` | comparable(35px, 2em) | false | |
floor(number) | 向下四舍五入取整 | floor(15.80) | 15 |
max(number...) | 取最大值 | max(5, 7, 9, 0, -3, -7) | 9 |
min(number...) | 取最小值 | max(5, 7, 9, 0, -3, -7) | -7 |
percentage(number) | 将数字转换为百分比(将数字乘以 100) | percentage(1.2) | 120 |
random() | 生成 0 到 1 之间的随机数。 | random() | 0.45673 |
random(number) | 生成从1到 number之间的随机整数 | random(5) | 4 |
round(number) | 将数字四舍五入到最接近的整数 | round(15.20) | 15 |
`` | round(15.80) | 16 |
3. 数组相关函数(list)
函数 | 描述 | 例子 | 输出结果 |
---|---|---|---|
append(list, value, [separator]) | 将单个值添加到列表的末尾。(列表的分隔符可以是自动、逗号或空格) | append((a b c), d) | a b c d |
index(list, value) | 返回列表中值的索引位置。 | index(a b c, b) | 2 |
is-bracketed(list) | 检查列表是否有方括号。 | is-bracketed([a b c]) | true |
join(list1, list2, [separator, bracketed]) | 将 list2 追加到 list1 的末尾。 | join((a b c), (d e f), comma) | a, b, c, d, e, f |
length(list) | 返回列表的长度 | `` | |
list-separator(list) | 返回列表分隔符。比如是空格或逗号。 | list-separator(a, b, c) | “comma“ |
nth(list, n) | 返回列表中第n个元素 | nth(a b c, 3) | c |
set-nth(list, n, value) | 将第 n 个列表元素设置为指定的值。 | set-nth(a b c, 2, x) | a x c |
zip(lists) | 将多个列表组合成一个多维列表。 | zip(1px 2px 3px, solid dashed dotted, red green blue) | 1px solid red, 2px dashed green, 3px dotted blue |
函数 | 描述 | 例子 | 输出结果 |
---|---|---|---|
map-get(map, key) | 返回映射中指定键的值。 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) map-get($font-sizes, "small") | 12px |
map-has-key(map, key) | 检查 map 是否具有指定的键。 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) map-has-key($font-sizes, "big") | false |
map-keys(map) | 返回 map 中所有键的列表。 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) map-keys($font-sizes) | “small”, "normal, “large” |
map-merge(map1, map2) | 将 map2 追加到 map1 的末尾。 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) $font-sizes2: ("x-large": 30px, "xx-large": 36px) map-merge($font-sizes, $font-sizes2) | “small”: 12px, “normal”: 18px, “large”: 24px, “x-large”: 30px, “xx-large”: 36px |
map-remove(map, keys...) | 删除列表中指定的键。 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) map-remove($font-sizes, "small") | (“normal”: 18px, “large”: 24px) |
map-values(map) | 返回列表中所有值 | $font-sizes: ("small": 12px, "normal": 18px, "large": 24px) map-values($font-sizes) | 12px, 18px, 24px |
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)