Sass学习记录

135 阅读4分钟

Sass是一种css的预编译语言。提供变量,嵌套,混合,函数等功能;Sass提供了css中还不存在的特性(如嵌套、mixin、继承和其他使用的功能)

变量

Sass使用$符号作为变量的标识;scss中的变量也存在作用域,类似于js中的局部变量

$font-stack:Helvetica, sans-serif;
$bgColor:#ffffff;
body{
    font:100% $font-stack;
    background-color:$bgColor;
}

CSS有自己的变量,与Sass变量完全不同。 Sass变量都被Sass编译掉了。Css变量包含在CSS的输出中。 CSS变量对于不同的元素可以有不同的值,但是Sass变量一次只能有一个值。 Sass变量是命令式的,这意味着如果您使用了一个变量,然后更改了它的值,那么之前的使用将保持不变。CSS变量是声明式的,这意味着如果更改值,他将影响早期使用和后期使用。 css样式中定义变量以-开头即可,在需要用到的地方以var()函数调用定义的变量名即可获取对应的值。

body{
 --bg-color:#8ab945;
}
.btn-default{
 background-color:var(--bg-color)
}

嵌套

Sass允许嵌套Css选择器,嵌套的方式与HTML的视觉层次结构相同。请注意,过度的嵌套规则将导致过度限定的CSS。 另外,许多css属性以相同的前缀开始,作为一种命名空间,如font-size,font-family,和font-weight都是以font开头,通过允许嵌套属性声明,Sass使这变得更容易,并且减少了冗余。外部属性名称被添加到内部属性名称中,中间用连字符分隔。

.info-page{
 margin: auto {
  bottom:10px;
  top:2px;
 }
}

上述等同于如下css

.info-page{
 margin:auto;
 margin-bottom: 10px;
 margin-top:2px;
}

Module

可以在一个A.scss文件中引入B.scss文件以使用其中的变量、mixin和函数;

// _base.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}
// styles.scss
@use 'base'

.inverse {
  background-color: base.$primary-color;
  color: white;
}

mixin

mixin允许创建一组css声明,以便在整个站点中重复使用这些声明。如下的例子表示声明了一个mixin函数,命名为theme参数变量为$theme,然后在其他选择器中使用@include加上mixin的名字,

@mixin theme($theme: DarkGray){
   background: $theme;
   box-shadow: 0 0 1ps rgba($theme,.25);
   color:#fff;
}

.info{
  @include theme;
}
.alert{
  @include theme($theme:DarkRed);
}
.success {
  @include theme($theme: DarkGreen)
}

Extend

使用@extend可以让一个选择器继承另一个选择器的css属性;下面的例子

这个将会被转译,因为%message-shared被继承了
%message-shared{
 border: 1px solid #ccc;
 padding:10px;
 color:#333;
}

%equal-heights {
 dispaly:flex;
 flex-wrap:wrap;
}
.message{
 @extend %message-shared;
}
.success{
 @extend %message-shared;
 border-color:green;
}
.error{
 @exrend %message-shared;
 border-color:red;
}
.warning {
 @extend %message-shared;
 border-color:yellow;

}

Sass也支持部分标准的数学运算符,如+-*、%等

@use "sass:math";

.container {
  display: flex;
}

article[role="main"] {
  width: math.div(600px, 960px) * 100%;
}

aside[role="complementary"] {
  width: math.div(300px, 960px) * 100%;
  margin-left: auto;
}

内置的模块

Sass的内置模块都是以sass:来标明这是sass内置的模块;

  • sass:math:提供用来操作数值的函数
  • sass:string:用来连接,查找,分割字符串;
  • sass:color:基于已经存在的颜色生成一个新的颜色
  • sass:list:用于访问或操作list;
  • sass:map:map模块可以在映射中查找与键相关的值,以及更多
  • sass:selector:selector模块提供了对sass强大的选择器引擎的访问。
  • sass:meta:meta模块公开了sass内部工作的细节。

隐藏声明

有些时候只想让某些属性在某些条件下显示;如果一个声明得值为null或者是一个没有引号得空字符串,Sass根本不会将该声明编译成css。

$rounded-corners:false;
.button{
border: 1ps solid black;
border-radius: if($rounded-corners,5px, null);
}

上述相当于css

.button{
border: 1ps solid black;
}

条件控制

  • @if控制是否计算这个块
@mixin avatar($size,$circle:false){
 width:$size;
 height:$size;
 @if $circle {
  border-radius:$size/2;
 }
}
.square-av{
 @include avatar(100px, $circle: false);
}
.circle-av {
@include avatar(100px,$circle:true)
}

上述转换成css如下:

.square-av{
width:100px;
height:100px;
}
.circle-av{
 width:100px;
 height:100px;
 border-radius:50px;
}

@if规则后面可以有一个@else规则,写为@else{...}。如果@if表达式返回false,则计算该规则的块;另外也有@else if

  • @each为列表中得每个元素或map中得一个键值对计算一个块
 $sizes: 40px, 50px, 80px;
 @each $size in $sizes {
  .icon-#{$size} {
   font-size:$size;
   height:$size;
   width:$size;
  }
 }

上述转换为css如下:

.icon-40px {
 font-size: 40px;
 height:40px;
 width:40px;
}
.icon-50px {
 font-size: 50px;
 height:50px;
 width:50px;
}
.icon-80px {
 font-size: 80px;
 height:80px;
 width:80px;
}

在Map中使用如下:

$icons:("eye":"\f112","start":"\f12e","stop":""\f12f)

@each $name,$glyph in $icons {
 .icon-#{$name}:before {
  display: inline-block;
  font-family:'Icon Font';
  content: $glyph;
 }
}

上述转为css为

@charset "UTF-8";
.icon-eye:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "";
}

.icon-start:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "";
}

.icon-stop:before {
  display: inline-block;
  font-family: "Icon Font";
  content: "";
}

  • @for对一个块求值一定的次数
$base-color:#036;
@for $i form 1 through 3 {
 ul:nth-child(3n+#{$i}){
   background-color:lighten($base-color,$i*5%);
  }
}

上述转换成css为:

ul:nth-child(3n + 1) {
  background-color: #004080;
}

ul:nth-child(3n + 2) {
  background-color: #004d99;
}

ul:nth-child(3n + 3) {
  background-color: #0059b3;
}
  • @while计算一个块,直到满足某个条件
@use "sass:math";
@function scale-below($value, $base,$ratio:1.618){
 @while $value>$base {
 $value: math.div($value, $ratio);
 }
 @return $value
}
$normal-font-size:16px;
sup{
font-size: scale-below(20px,16px)
}

上述转换成css为:

sup {
  font-size: 12.36094px;
}

@root

@root可以用来放弃当前的嵌套层级,让其内部的css规则到根部。比如,通常会写如下的嵌套:

.bar{
 .foo{
   color:red
 }
}

编译出来为

.bar .foo {
 color:red;
}

如果使用@root

.bar{
 @at-root .foo{
   color:red
 }
}

编译出来为

.bar {}
.foo {        
 color:red;
}
  • @at-root(with:...)
  • @at-root(without:...):移动到指令之外 //
@media p{
     div{
              overflow: hidden;
         @at-root .his_son {
             color: #000;
         }

       @at-root (with: media) { /*!不会跳出media*/
            p{
                color: red;
             }
         }

        @at-root (without:media){ /*!将会跳出media*/
             p{
                 color: red;
             }
         }
    }
  }

@use

@use主要用于加载其他样式文件中的mixins,函数,和变量以达到样式的复用。一般默认以文件路径url中的最后一个名字作为命名空间。也可以使用as来自定义命名

//src/_corners.scss
$radius:3px;

@mixin rounded {
 border-radius:$radius;
}


//style.scss
@use "src/corners"
.button {
 @include corners.rounded;
 padding: 5px +corners.$radius;
}

//style1.scss
@use "src/corners" as c
.button {
 @include c.rounded;
 padding: 5px +c.$radius;
}

或者其他情况使用@use '@/pages/subject-management/common/styles/public-style.scss' as publicStyle;

如果不想让某些变量暴露给其他文件,可以使用-_定义私有成员,这样就不会暴露出去;

// src/_corners.scss
$-radius: 3px;

@mixin rounded {
  border-radius: $-radius;
}
// style.scss
@use "src/corners";

.button {
  @include corners.rounded;

  // This is an error! $-radius isn't visible outside of `_corners.scss`.
  padding: 5px + corners.$-radius;
}

@use在引入的时候也可以对变量的值进行配置,样式表可以定义带有!default标志的变量,使其可配置。要用配置加载模块,可以写@use with (: , : )。配置的值将覆盖变量的默认值

// _library.scss
    $black:#000 !default;
    $border-radius: 0.25rem !default;
    $box-shadow: 0 0.5rem 1rem rgba($black,0.15) !default;
    code {
     border-radius:$border-radius;
     box-shadow:$box-shadow;
    }
    //style.scss
    @use 'library' with (
    $black:#222,
    $border-radius:0.1rem
    )