scss语法

159 阅读9分钟

前言

以前都是用 css,自从看到有人使用了 less 之后,我就感觉,这东西用着真舒服呀,就赶紧学习了一下,后面又发现 scss 使用的场景实际上比 less 更多,主要是其他用的人比较多,还是使用 scss 吧,甚至有些场景 less 支持没有 scss

看了之后,你还感觉不行不好用,咱们不用就是了,对吧😂

ps:这也是我们常用的几大css工具链之一,另外的不说了吧,应该前面介绍过🤣

话不多说,直接开始讲解

sass与scss

sassscss 其实是同一种东西,我们平时都称之为 sass,两者之间不同比较如下:

  • 文件扩展名不同,sass 是以 .sass 后缀为扩展名,而 scss 是以.scss后缀为扩展名
  • 语法书写方式不同,Sass 是以严格的缩进式语法书写,不带大括号{}和分号;,也是最初的语法格式,不太友好
  • 时间线上有关系,scsssass 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 * 2height: 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):删除字符串中的引号;unquote(string): 删除字符串中的引号;unquote(string) 函数只能删除字符串最前和最后的引号(双引号或单引号),而无法删除字符串中间的引号。如果字符没有带引号,返回的将是字符串本身
  • quote($string):给字符串添加引号,如果字符串自身带有引号(单引号)会统一换成双引号 ""
  • to-upper-case($string) 函数将字符串小写字母转换成大写字母
  • to-lower-case(string)函数与touppercase(string) 函数 与 to-upper-case(string) 刚好相反,将字符串转换成小写字母
  • percentage() 数字转化百分比
  • round() 数四舍五入
  • ceil() 向数值大的一方取整
  • floor() 向数值小的一方取整
  • abs( ) 函数会返回一个数的绝对值
  • max() /min() 多个数之中取最大/最小,有单位的需要单位一致
  • random() 函数是用来获取一个随机数;
  • length() 列表取数量
  • nth(list,list,n) 取出列表中第几个值,从1开始,第一个代表第一个元素
  • if(condition,condition,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 参数,返回 key 在 map中对应的value值,如果map 中对应的 value 值,如果 key 不存在 $map中,将返回 null 值。
  • Maps的 map-has-key($map,$key) 函数将返回一个布尔值,当 map中有这个map 中有这个 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){}