前言
以前都是用 css,自从看到有人使用了 less 之后,我就感觉,这东西用着真舒服呀,就赶紧学习了一下,后面又发现 scss 使用的场景实际上比 less 更多,主要是其他用的人比较多,还是使用 scss 吧,甚至有些场景 less 支持没有 scss 好
看了之后,你还感觉不行不好用,咱们不用就是了,对吧😂
ps:这也是我们常用的几大css工具链之一,另外的不说了吧,应该前面介绍过🤣
话不多说,直接开始讲解
sass与scss
sass 和 scss 其实是同一种东西,我们平时都称之为 sass,两者之间不同比较如下:
- 文件扩展名不同,
sass是以.sass后缀为扩展名,而scss是以.scss后缀为扩展名 - 语法书写方式不同,Sass 是以严格的缩进式语法书写,不带大括号
{}和分号;,也是最初的语法格式,不太友好 - 时间线上有关系,
scss是sass 3引入的新语法,scss的语法书写和我们的css语法书写方式非常类似
因此实际上我们项目导入的都是 sass,使用的是 scss,不用疑问哈
一般在 dev 导入我们的 sass,在打包配置文件中声明一下即可
yarn add sass --dev
以 vite 为例,简单配置一下,不多介绍了
css: {
preprocessorOptions: {
scss: {},
},
},
从这里也能看出 scss 也是一个编译时运行的辅助工具,因此一些在运行时才有的功能,他实际上是不具备的,他只是一个辅助工具,最终会生成运行时执行的 css
scss前置(回顾) -- css 变量、特殊符号
css 中变量和特殊符号想必大家也都接触过,这里也简单介绍下,避免部分没有接触过的读者到 scss这部分时懵逼
css 变量
ps:只可以在括号内声明变量,限制比较多,且声明位置和使用看着有点怪
// 两边名前加入 --变量名
// 使用 var(--变量名) 使用变量
.test-text {
//有效,且变量不允许声明到外面
--font-z: 100px;
font-size: var(--font-z);
//无效,不能拼接,只能设置最终结果
--font-z: 100;
font-size: var(--font-z)px;
}
css 特殊符号
主要介绍:逗号(,)、空格、>、+、~、*
逗号(,): 可以让多个选择器拥有相同属性,此外,同名选择器会同时应用该名字所有属性(这两个功能一起应用,可以理解为选择器的多态)
空格、>、+、~、*等: 可以给指定节点(当前节点、子节点)设置属性
/* 逗号、空格、>、+、~、* */
/* ,: 逗号隔开的选择器,同时拥有括号内声明的属性 */
/* 设置选择器的,需要通过 className 设置到对应标签中 */
.test-text, .test-text1, .test-text2 {
color: blue;
}
/* 应用于当前节点,此时他会比另外两个属性多出一个font-size属性,同名属性属性最终会被合并 */
.test-text {
font-size: 40px;
}
/* 下面的应用于所有子节点(标签选择器:div、类别选择器:.test-text) */
/* 空格: 容器内,所有 p 节点 */
.test-text p {
font-size: 20px;
}
/* 空格: 容器内,所有类别选择器为 test-text1 的 */
.test-text .test-text1 {
font-size: 20px;
}
/* 后面案例均以标签选择器,即节点为例 */
/* >: 容器内,指定第一层直接子节点 p,不会应用于孙节点以及以后节点*/
.test-text > p {
font-size: 60px;
}
/* +: 容器内的所有子节点中, 符合 p 后面紧相邻兄弟节点(下一个节点)为 div 时生效,有一组生效一组 */
.test-text p + div {
color: red;
}
/* ~: 容器内的所有子节点中,p节点后面同级节点中为 div 的兄弟节点,都生效 */
.test-text p ~ div {
color: green;
}
/* * 应用到容器内,所有子元素 */
.test-text * {
background-color: yellow;
}
顺便补充一下并列选择器、属性选择器
/* 并列选择器 连接到一起表示多个选择器作为样式筛选条件 */
div.test-text {
font-size:30;
}
[id="name"] {
font-size: 30;
}
他们是选择器的权值和顺序,如果一行css多个重复选择器,则实际根据权值相加表示优先级,优先级一致,后者代替前者
!important > style > id选择器 > class选择器 | 属性 | 伪类 > 标签选择器 | 伪元素 > 通配符选择器
scss
scss 大多数和 less 很像,学一个基本就能用了,当然一些符号是有区别的,还有很多基本平时用不到,要是忘了瞅一眼基本就能想起来😂
选择器嵌套
.content1 {
display: flex;
flex-direction: row;
//会自动生效到子选择器
.text {
color: red();
font-size: 30px;
}
//应用到直属子节点,其他一样 > + , ~ 等均生效
> .img-logo {
width: 100px;
height: 100px;
background-image: url("../images/logo192.png");
background-repeat: no-repeat;
background-size: cover;
}
}
//下面的 & 均会被替换为父类名称 div
div {
width: 20px;
height: 20px;
background-color: red;
//&会自动替换外层选择器名称,下面相当于 div:hover
//如果是类选择器存在前缀的也可以
&:hover {
background-color: green;
}
//伪类嵌套,不多说
&:after {
content: ''
}
// 相当于 div-subdiv,字符拼接了,&必须在前,因此比较适合标签选择器
&-subdiv {
background-color: green;
}
}
属性嵌套
这个有时候也是比较好用的,当然看情况,一般用不到(个人感觉多此一举哈🤣)
#css
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
#scss
.box {
border: {
top: 1px solid red;
bottom: 1px solid green;
}
}
scss变量
变量常见的就是数字(flex-grow等)、长度单位(px、em等)、度数(角度deg、trun转)、颜色 等等
$theme-color: blue;
$theme-bkg: blue;
.theme-color {
color: $theme-color;
}
.theme-bkg {
background-color: $theme-color;
}
混合宏
混合宏,也算老牌使用手段了,使用后会替换原有代码,但也会生成冗余代码块,一些重复的并不会合并,当然也可能是参数不同不好合并等原因,不合并了
声明 @mixin 使用 @include
@mixin border-radius {
border-radius: 5px;
}
.bkg {
@include border-radius;
}
@mixin border-radius($radius: 5px) {
border-radius: $radius;
}
.bkg {
@include border-radius;
}
.bkg2 {
@include border-radius(5px);
}
继承
这个也是比较常见的,其他的类似工具也基本都具备,使用 @extend 继承,编译后会在新的选择器展开继承的样式,也避免了必须要在class编写多个选择器的问题,缺点就是基类会存在,如果不适用就会额外声明
.base {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.bkg {
@extend .base;
background: green;
}
%占位
这个和 less 的虚拟节点很像(看起来 less 更好用,混合宏 + 虚拟节点更简单😂),不会占用一个样式,使用后像真的宏一样替换到指定css 样式里面(另外一个混合宏看起来似假非假了,开玩笑,这个是静态的没有参数😂)
也是使用 @extend 展开,解决了 extend 继承生成额外的基类问题,当然有些基类本身就需要用到的,就不能用占位了
%mt5 {
margin-top: 5px;
}
.btn {
@extend %mt5;
}
.block {
@extend %mt5;
}
插值
有时候我们需要 动态生成选择器,此时插值就很好用(当然一般循环中用的比较多😂),这里使用混合宏来演示
使用方式 ${name}
@mixin generateStatus($class) {
.#{$class}-success { font-size: green; }
.#{$class}-fail { font-size: red; }
.#{$class}-normal { font-size: black; }
}
//生成两组选择器,一个基础用户的,一个企业用户的
@include generate-sizes("user");
@include generate-sizes("enterprise-user");
计算
加减乘除很常见,但是很多都有单位,同样单位的加减,有单位的不能相乘,可以乘上数字,相同单位的会得到一个比例
符合数学角度的计算基本都支持(如果操作错了,那么也许补一补数学有效😂),因此不多介绍
ps:常见的单位 px、em、rem、%、deg、颜色 等都是支持的
.content {
width: $full-width - $menu-width;
}
//相加减
.content1 {
width: 100px + 100px;
height: 200px - 100px;
}
//乘除法
.content2 {
width: 100px * 2;
height: 200px / 2
}
//混合运算
.content3 {
width: 200px / 200px * 50px
}
条件语句
一些场合会用到条件语句,一般是循环、混合宏,这里混合宏介绍@if、@else
@mixin isHidden($boolean:true) {
@if $boolean {
display: none;
}
@else {
display: block;
}
}
循环
循环有 @for、@while、@each 实际使用起来差不太多,有自己的使用场景,
@for循环
through 表示包括 end 这个数,而 to 则不包括 end 这个数
使用方式
@for $i from <start> through <end>@for $i from <start> to <end>
@for $i from 1 through 3 {
.item-#{$i} {
margin-top: 100px * $i;
}
}
@for $i from 1 to 4 {
.item-#{$i} {
margin-top: 100px * $i;
}
}
@while循环
这个和我们 js 的 while 循环很像,只不过需要用到 scss变量,每次循环重新声明scss变量的值即可
使用方式 @while 条件($name > 0)
@while $types > 0 {
.while-#{$types} {
width: $type-width + $types;
}
$types: $types - 1;
}
@each循环
这个循环看起来更适合配合插值替换掉一些字符串,可以使用空格隔开字符串,使用 @each 遍历,这样可以避免使用上面循环的数字拼接了😂,有点 for in 既视感
使用方式 @each $name in <list>
@each $var in <list>
$list: success fail normal;
@mixin status-images {
@each $status in $list {
.status-images-#{$status} {
background: url("/images/status/#{$status}.png") no-repeat;
}
}
}
@include status-images;
函数
@funtion 也可以类似 js 的调用,批量或者动态生成我们想要的代码
下面一个案例
@function paddingX($x) {
$paddingx: 0px #{$x};
@return $paddingx;
}
@function paddingY($y) {
$paddingy: #{$y} 0px;
@return $paddingy;
}
.bkg {
padding: paddingX(20px);
padding: paddingY(20px);
}
使用 sass [name.scss] [name.css] 可以直接生成css查看结果
.bkg {
padding: 0px 20px;
padding: 20px 0px;
}
下面是可能会用到的一些函数,很多时候可能都不需要用到
- unquote(string) 函数只能删除字符串最前和最后的引号(双引号或单引号),而无法删除字符串中间的引号。如果字符没有带引号,返回的将是字符串本身
- quote($string):给字符串添加引号,如果字符串自身带有引号(单引号)会统一换成双引号 ""
- to-upper-case($string) 函数将字符串小写字母转换成大写字母
- to-lower-case(string) 刚好相反,将字符串转换成小写字母
- percentage() 数字转化百分比
- round() 数四舍五入
- ceil() 向数值大的一方取整
- floor() 向数值小的一方取整
- abs( ) 函数会返回一个数的绝对值
- max() /min() 多个数之中取最大/最小,有单位的需要单位一致
- random() 函数是用来获取一个随机数;
- length() 列表取数量
- nth(n) 取出列表中第几个值,从1开始,第一个代表第一个元素
- if(if-true,$if-false) 三元条件函数,还记得三目运算符么
scss中的列表:数字、字符串、颜色、变量、甚至其他列表 都可以,使用逗号、空格分隔符隔开的都是有效列表
scss内置的一些颜色函数(可能会用到)
sass的一些颜色运算函数
在Sass中,颜色运算主要通过内置的颜色函数来实现,这使得你可以对颜色进行各种操作,比如调整颜色的亮度、饱和度、透明度等。下面是一些常用的颜色运算函数:
lighten($color, $amount)
增加颜色的亮度。$color 是要操作的原始颜色,$amount 是增加的亮度百分比。
这个也是用的比较多的,例如:disable属性的时候,只需要降低亮度百分比即可,没必要定义那么多颜色
$base-color: #333;
$lighter-color: lighten($base-color, 20%); // 结果为 #666
2. darken($color, $amount)
减少颜色的亮度。$color 是要操作的原始颜色,$amount 是减少的亮度百分比。
$base-color: #ccc;
$darker-color: darken($base-color, 20%); // 结果为 #999
3. saturate($color, $amount)
增加颜色的饱和度。$color 是要操作的原始颜色,$amount 是增加的饱和度百分比。
$base-color: #85c1e9;
$saturated-color: saturate($base-color, 20%); // 结果为更鲜艳的颜色
4. desaturate($color, $amount)
减少颜色的饱和度。$color 是要操作的原始颜色,$amount 是减少的饱和度百分比。
$base-color: #85c1e9;
$desaturated-color: desaturate($base-color, 20%); // 结果为更灰暗的颜色
5. adjust-hue($color, $degrees)
调整颜色的色相。$color 是要操作的原始颜色,$degrees 是色相调整的角度(可以是负值)。
$base-color: #85c1e9;
$new-hue-color: adjust-hue($base-color, 45deg); // 结果为改变色相的颜色
6. opacity($color, $opacity)
调整颜色的透明度(仅对RGBA和HSLA颜色有效)。$color 是要操作的原始颜色,$opacity 是新的透明度值(0到1之间)。
$base-color: rgba(255, 0, 0, 0.5);
$new-opacity-color: rgba(opacity($base-color, 0.8)); // 结果为透明度调整后的颜色
注意:在Sass中,直接使用rgba()或hsla()函数也可以实现透明度的调整。例如:
$base-color: rgba(255, 0, 0, 0.5);
$new-opacity-color: rgba(red($base-color), green($base-color), blue($base-color), 0.8); // 使用rgba函数调整透明度,同时保持原有的RGB值不变。
7. mix($color1, $color2, [$weight])
混合两种颜色。$color1 和 $color2 是要混合的颜色,$weight 是混合比例(默认为50%,范围从0%到100%)。
$color1: #ff0000; // 红色
$color2: #0000ff; // 蓝色
$mixed-color: mix($color1, $color2, 50%); // 结果为紫色(红色和蓝色的混合)
通过这些函数,你可以灵活地对颜色进行各种运算和调整,实现丰富的视觉效果。
Introspection函数
个人感觉一般也用不到,可能会有场景能用到(仓库吃灰了好久,看到了补充一下😂)
type-of($value):返回一个值的类型number 为数值型。string 为字符串型。bool 为布尔型。color 为颜色型.unit($number):返回一个值的单位,unit() 函数主要是用来获取一个值所使用的单位,碰到复杂的计算时,其能根据运算得到一个“多单位组合”的值,不过只充许乘、除运算.unitless($number):判断一个值是否带有单位,unitless() 函数相对来说简单明了些,只是用来判断一个值是否带有单位,如果不带单位返回的值为 true,带单位返回的值为 false;comparable($number-1, $number-2):判断两个值是否可以做加、减和合并,comparable() 函数主要是用来判断两个数是否可以进行“加,减”以及“合并”。如果可以返回的值为 true,如果不可以返回的值是 false, comparable(2cm,1cm) true
map
对于一些需要用到 key、value 结构的,则可以通过 map以及操作方法使用,当然一般不推荐使用
$map: (
key1: value1,
key2: (
key-1: value-1,
key-2: value-2,
),
key3: value3
);
- Maps的
map-get($map,$key)函数的作用是根据 key 在 key 不存在 $map中,将返回 null 值。 - Maps的
map-has-key($map,$key)函数将返回一个布尔值,当 key,则函数返回 true,否则返回 false,可以配合 @if 等使用 - Maps的 map-keys($map) 返回一个key列表,可以根据 map-get + key 获取内容
$list: map-keys($social-colors)
$list:"dribble","facebook","github","google","twitter";
@for $i from 1 through length(map-keys($social-colors)){}
@each $name in map-keys($social-colors){}