Sass常用特性

Sass中文官网

CSS功能拓展

嵌套规则(核心)

Sass 允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器

例如有这么一段 CSS 代码:

css 复制代码
.container {width:1200px; margin: 0 auto;}
.container .header {height: 90px; line-height: 90px;}
.container .header .log {width:100px; height:60px;}
.container .center {height: 600px; background-color: #F00;}
.container .footer {font-size: 16px;text-align: center;}

改成写 Sass:

scss 复制代码
.container {
    width: 1200px;
    margin: 0 auto;
    .header {
        height: 90px;
        line-height: 90px;
        .log {
            width: 100px;
            height: 60px;
        }
    }
    .center {
        height: 600px;
        background-color: #F00;
    }
    .footer {
        font-size: 16px;
        text-align: center;
    }
}

嵌套功能避免了重复输入父选择器,而且令复杂的 CSS 结构更易于管理

父选择器 &

在嵌套 CSS 规则时,有时也需要直接使用嵌套外层的父选择器,可以用 & 代表嵌套规则外层的父选择器

& 必须作为选择器的第一个字符,其后可以跟随后缀生成复合的选择器,例如:

scss 复制代码
#main {
  color: black;
  &-sidebar { border: 1px solid; }
}

编译为

css 复制代码
#main {
  color: black; }
  #main-sidebar {
    border: 1px solid; }

编译后的 CSS 文件中 & 将被替换成嵌套外层的父选择器,如果含有多层嵌套,最外层的父选择器会一层一层向下传递

属性嵌套

有些 CSS 属性遵循相同的命名空间,比如 font-family, font-size, font-weight 都以 font 作为属性的命名空间。为了便于管理这样的属性,同时也为了避免了重复输入,Sass 允许将属性嵌套在命名空间中,例如:

例如:

css 复制代码
.container a {
    color: #333;
    font-size: 14px;
    font-family: sans-serif;
    font-weight: bold;
}

改成写 Sass:

scss 复制代码
.container {
    a {
        color: #333;
        font: {
            size: 14px;
            family: sans-serif;
            weight: bold;
        }
    }
}

此处font:后要加一个空格

占位符选择器 %foo

Sass 额外提供了一种特殊类型的选择器:占位符选择器 。与常用的 idclass 选择器写法相似,只是 #. 替换成了 %。必须通过 @extend 指令调用

占位符选择器不会在CSS中生成具体的类名,直到它们被@extend到其他选择器时才会生成。这可以减少生成的CSS文件大小,因为不会有多余的类名(用于扩展其他选择器,但不会被编译成最终的CSS)

scss 复制代码
%my-placeholder {
  color: blue;
  font-weight: bold;
}

.my-element {
  @extend %my-placeholder;
  background-color: yellow;
}

注释 /* *///

Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 //,前者会被完整输出到编译后的 CSS 文件中,而后者则不会,例如:

scss 复制代码
/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body { color: black; }

// These comments are only one line long each.
// They won't appear in the CSS output,
// since they use the single-line comment syntax.
a { color: green; }

编译为

css 复制代码
/* This comment is
 * several lines long.
 * since it uses the CSS comment syntax,
 * it will appear in the CSS output. */
body {
  color: black; }

a {
  color: green; }

此处单行注释没有编译进css文件

此外,将 ! 作为多行注释的第一个字符表示在压缩输出模式下保留这条注释并输出到 CSS 文件中,通常用于添加版权信息

Sass变量

CSS变量

CSS定义变量:

css 复制代码
:root {
    --color: #F00;
}

body {
    --border-color: #f2f2f2;
}

.header {
    --background-color: #f8f8f8;
}

p {
    color: var(--color);
    border-color: var(--border-color);
}

.header {
    background-color: var(--background-color);
}

CSS变量必须以--开头,通过var()使用

:root 表示<html>,除了优先级更高之外,与 html 选择器相同

Sass的写法:

scss 复制代码
$font-size:14px;
.container {
    font-size: $font-size;
}

Sass变量定义

定义规则:

  • 变量一定要先定义,后使用,以美元符号$开头,后面跟变量名
  • 变量名是不以数字开头的可包含字母、数字、下划线、横线(连接符)
  • 写法同css,即变量名和值之间用冒号:分隔

连接符与下划线

通过连接符与下划线 定义的同名变量为同一变量,建议使用连接符

scss 复制代码
$font-size:14px;
$font_size:16px;
.container{font-size: $font-size;}

变量作用域

Sass 变量支持块级作用域,嵌套规则内定义的变量只能在嵌套规则内使用(局部变量),不在嵌套规则内定义的变量则可在任何地方使用(全局变量)。将局部变量转换为全局变量可以添加 !global 声明

scss 复制代码
#main {
  $width: 5em !global;
  width: $width;
}

#sidebar {
  width: $width;
}

编译为:

css 复制代码
#main {
  width: 5em;
}

#sidebar {
  width: 5em;
}

在选择器外面的最前面定义的变量为全局变量

变量数据类型

SassScript 支持六种主要的数据类型:

  • 数字:1, 2, 13, 10px
  • 字符串:有引号字符串与无引号字符串,"foo", 'bar', baz
  • 颜色:blue, #04a3f9, rgba(255,0,0,0.5)
  • 布尔型:true, false
  • 空值:null,值null是其类型的唯一值。它表示缺少值,通常由函数返回以指示缺少结果
  • 数组 (list):用空格或逗号作分隔符,1.5em 1em 0 2em, Helvetica, Arial, sans-serif
  • maps:相当于 JavaScript 的 object,(key1: value1, key2: value2)

SassScript 也支持其他 CSS 属性值,比如 Unicode 字符集,或 !important 声明。然而 Sass 不会特殊对待这些属性值,一律视为无引号字符串

字符串

SassScript 支持 CSS 的两种字符串类型:

  • 有引号字符串,如 "Lucida Grande" 'http://sass-lang.com'
  • 与无引号字符串,如 sans-serif bold

在编译 CSS 文件时不会改变其类型。只有一种情况例外,使用 #{} 时,有引号字符串将被编译为无引号字符串,这样便于在 mixin 中引用选择器名:

scss 复制代码
@mixin firefox-message($selector) {
  body.firefox #{$selector}:before {
    content: "Hi, Firefox users!";
  }
}
@include firefox-message(".header");

编译为

css 复制代码
body.firefox .header:before {
  content: "Hi, Firefox users!"; }

Sass插值语句

通过 #{} 插值语句可以在选择器或属性名中使用变量

scss 复制代码
$name: foo;
$attr: border;
p.#{$name} {
  #{$attr}-color: blue;
}

编译为:

css 复制代码
p.foo {
  border-color: blue; }

#{} 插值语句也可以在属性值中插入 SassScript,大多数情况下,这样可能还不如使用变量方便,但是使用 #{} 可以避免 Sass 运行运算表达式,直接编译 CSS

scss 复制代码
p {
  $font-size: 12px;
  $line-height: 30px;
  font: #{$font-size}/#{$line-height};
}

编译为

css 复制代码
p {
  font: 12px/30px; }

Sass运算

等号操作符

所有数据类型都支持等号运算符

符号 说明
== 等于
!= 不等于

数字比较:

scss 复制代码
$theme:1;
.container {
    @if $theme==1 {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

字符串比较:

scss 复制代码
$theme:"blue";
.container {
    @if $theme !="blue" {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

所有数据类型均支持相等运算 ==!=,此外,每种数据类型也有其各自支持的运算方式

关系运行符

符号 说明
< (lt) 小于
> (gt) 大于
<= (lte) 小于等于
>= (gte) 大于等于

例如:

scss 复制代码
$theme:3;
.container {
    @if $theme >= 5 {
        background-color: red;
    }
    @else {
        background-color: blue;
    }
}

逻辑运行符

符号 说明
and 逻辑与
or 逻辑或
not 逻辑非

例如:

scss 复制代码
$width:100;
$height:200;
$last:false;
div {
    @if $width>50 and $height<300 {
        font-size: 16px;
    }
    @else {
        font-size: 14px;
    }
    @if not $last {
        border-color: red;
    }
    @else {
        border-color: blue;
    }
}

数字操作符

符号 说明
+
-
*
/
% 取模

例如:

scss 复制代码
// 数字与百分号或单位运算时会自动转化成相应的百分比与单位值
.container {
    // + 运算
    width: 50 + 20%; // 70%
    width: 10pt + 20px; // 25pt
    width: 10pt + 20; // 30pt
    width: 10px + 10; // 20px
    // - 运算
    height: 10 - 30%; //invalid value
    height: 60% - 30%;
    height: 50px - 20px;
    height: 50pt - 20px;
    height: 50pt - 40;
    // * 运算
    height: 50 * 30;
    height: 10 * 30%;
    /* height: 60% * 30%; 报错,出现了两个百分号*/
    /* height: 50px * 20px; 报错,出现了两个单位*/
    height: 50 * 2px;
    height: 50pt * 4;
    // / 运算 (除完后最多只能保留一种单位)
    $width: 100px;
    width: 10 / 5;
    width: 10px / 5px; // width: 10px/5px; 不进行运算
    width: 10px / 10 * 2; // 2px
    width: 20px / 2px * 5%; //50%
    width: ($width/2); // 使用变量与括号
    z-index: round(10)/2; // 使用了函数
    height: (500px/2); // 使用了括号
    // % 运算
    width: 10 % 3; // 1
    width: 50 % 3px; // 2px
    width: 50px % 4px; // 2px
    width: 50px % 7; // 1px
    width: 50% % 7; // 1%
    width: 50% % 9%; // 5%
    width: 50px % 10pt; // 10px
    width: 50px % 13.33333px; // 10.00001px
    /* width: 50px % 5%; 报错,单位不统一*/
}

/在 CSS 中通常起到分隔数字的用途,SassScript 作为 CSS 语言的拓展当然也支持这个功能,同时也赋予了/除法运算的功能。也就是说,如果/在 SassScript 中把两个数字分隔,编译后的 CSS 文件中也是同样的作用

以下三种情况 / 将被视为除法运算符号:

  • 如果值或值的一部分,是变量或者函数的返回值
  • 如果值被圆括号包裹
  • 如果值是算数表达式的一部分
scss 复制代码
$width: 1000px;
div {
    font: 16px/30px Arial, Helvetica, sans-serif; // 不运算
    width: ($width/2); // 使用变量与括号
    z-index: round(10)/2; // 使用了函数
    height: (500px/2); // 使用了括号
    margin-left: 5px + 8px/2px; // 使用了+表达式
}

如果需要使用变量,同时又要确保/不做除法运算而是完整地编译到 CSS 文件中,只需要用#{}插值语句将变量包裹

字符串运算

+ 可用于连接字符串

注意:如果有引号字符串(位于 + 左侧)连接无引号字符串,运算结果是有引号的,相反,无引号字符串(位于 + 左侧)连接有引号字符串,运算结果则没有引号

scss 复制代码
p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}

编译为

css 复制代码
p:before {
  content: "Foo Bar";
  font-family: sans-serif; }

在有引号的文本字符串中使用 #{} 插值语句可以添加动态的值:

scss 复制代码
p:before {
  content: "I ate #{5 + 10} pies!";
}

编译为

css 复制代码
p:before {
  content: "I ate 15 pies!"; }

Sass混入指令

@mixin 指令允许我们定义一个可以在整个样式表中重复使用的样式

@include 指令可以将混入(mixin)引入到文档中

定义与使用

scss 复制代码
@mixin mixin-name() {
    /* css 声明 */
}

标准形式

scss 复制代码
// 定义页面一个区块基本的样式
@mixin block {
    width: 96%;
    margin-left: 2%;
    border-radius: 8px;
    border: 1px #f6f6f6 solid;
}

使用:

scss 复制代码
// 使用混入
.container {
    .block {
        @include block;
    }
}

嵌入选择器

scss 复制代码
@mixin warning-text {
    .warn-text {
        font-size: 12px;
        color: rgb(255, 253, 123);
        line-height: 180%;
    }
}

使用:

scss 复制代码
// 使用混入
.container {
    @include warning-text;
}

使用变量(单参数)

scss 复制代码
// 定义flex布局元素纵轴的排列方式
@mixin flex-align($aitem) {
    -webkit-box-align: $aitem;
    -webkit-align-items: $aitem;
    -ms-flex-align: $aitem;
    align-items: $aitem;
}

使用:

scss 复制代码
// 只有一个参数,直接传递参数
.container {
    @include flex-align(center);
}

// 给指定参数指定值
.footer {
    @include flex-align($aitem: center);
}

使用变量(多参数)

scss 复制代码
// 定义块元素内边距
@mixin block-padding($top, $right, $bottom, $left) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

使用:

scss 复制代码
// 按照参数顺序赋值
.container {
    @include block-padding(10px, 20px, 30px, 40px);
}

// 可指定参数赋值
.container {
    @include block-padding($left: 20px, $top: 10px, $bottom: 10px, $right: 30px);
}

必须指定四个值

指定默认值

scss 复制代码
// 定义块元素内边距,参数指定默认值
@mixin block-padding($top:0, $right:0, $bottom:0, $left:0) {
    padding-top: $top;
    padding-right: $right;
    padding-bottom: $bottom;
    padding-left: $left;
}

使用:

scss 复制代码
// 可指定参数赋值
.container {
    // 不带参数
    @include block-padding;
    //按顺序指定参数值
    @include block-padding(10px,20px);
    //给指定参数指定值
    @include block-padding($left: 10px, $top: 20px)
}

可变参数

参数不固定的情况

scss 复制代码
/** 
   定义线性渐变
   @param $direction  方向
   @param $gradients  颜色过度的值列表
*/

@mixin linear-gradient($direction, $gradients...) {
    background-color: nth($gradients, 1);
    background-image: linear-gradient($direction, $gradients);
}

使用:

scss 复制代码
.table-data {
    @include linear-gradient(to right, #F00, orange, yellow);
}

@mixin混入总结

  • @mixin是可以重复使用的一组CSS声明
  • @mixin有助于减少重复代码,只需声明一次,就可在文件中引用
  • 混合指令可以包含所有的 CSS 规则,绝大部分 Sass 规则,甚至通过参数功能引入变量,输出多样化的样式。
  • 使用参数时建议加上默认值

Sass继承指令

@extend 指令告诉 Sass 一个选择器的样式从另一选择器继承。如果一个样式与另外一个样式几乎相同,只有少量的区别,则使用 @extend 就显得很有用,@extend 很好的体现了代码的复用

基本使用

以下 Sass 实例中,我们创建了一个基本的按钮样式 .button-basic,接着我们定义了两个按钮样式 .button-report.button-submit,它们都继承了 .button-basic,它们主要区别在于背景颜色与字体颜色,其他的样式都是一样的

Sass 代码:

scss 复制代码
.button-basic  {
  border: none;
  padding: 15px 30px;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
}

.button-report  {
  @extend .button-basic;
  background-color: red;
}

.button-submit  {
  @extend .button-basic;
  background-color: green;
  color: white;
}

将以上代码转换为 CSS 代码,如下所示:

css 复制代码
.button-basic, .button-report, .button-submit {
  border: none;
  padding: 15px 30px;
  text-align: center;
  font-size: 16px;
  cursor: pointer;
}

.button-report  {
  background-color: red;
}

.button-submit  {
  background-color: green;
  color: white;
}

使用 @extend 后,我们在 HTML 按钮标签中就不需要指定多个类 class="button-basic button-report" ,只需要设置 class="button-report" 类即可

此外@extend还支持多个继承,即每个类内可以使用多个@extend

多层继承

例如定义两个类,important类继承alert类的样式

scss 复制代码
.alert {
    padding: 15px;
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    font-size: 12px;
}

.important {
    @extend .alert;
    font-weight: bold;
    font-size: 14px;
}

alert-danger类继承important的样式

scss 复制代码
.alert-danger {
    @extend .important;
    color: #a94442;
    background-color: #f2dede;
    border-color: #ebccd1;
}

Sass流程控制指令

@if

@if()函数允许您根据条件进行分支,并仅返回两种可能结果中的一种,同 JavaScript 中的 if....elseif ...else

代码形式:

scss 复制代码
.container{
    // if
    @if(/* 条件 */){
        // ...
    }


    // if、else
    @if(/* 条件 */){
        // ...
    }@else{
        // ...
    }
    
    // if、else if、else
    @if(/* 条件 */){
        // ...
    }@else if(){
        // ...
    }@else{
        // ...
    }
}

例如,定义一个css的三角形@mixin声明

scss 复制代码
@mixin triangle($direction:top, $size:30px, $border-color:black) {
    width: 0px;
    height: 0px;
    display: inline-block;
    border-width: $size;
    border-#{$direction}-width: 0;
    @if ($direction==top) {
        border-color: transparent transparent $border-color transparent;
        border-style: dashed dashed solid dashed;
    }
    @else if($direction==right) {
        border-color: transparent transparent transparent $border-color;
        border-style: dashed dashed dashed solid;
    }
    @else if($direction==bottom) {
        border-color: $border-color transparent transparent transparent;
        border-style: solid dashed dashed dashed;
    }
    @else if($direction==left) {
        border-color: transparent $border-color transparent transparent;
        border-style: dashed solid dashed dashed;
    }
}

HTML部分:

html 复制代码
<p class="p0"></p>
<p class="p1"></p>
<p class="p2"></p>
<p class="p3"></p>

使用:

scss 复制代码
.p0 {
    @include triangle();
}

.p1 {
    @include triangle(right, 50px, red);
}

.p2 {
    @include triangle(bottom, 50px, blue);
}

.p3 {
    @include triangle(left, 50px, green);
}

@for

@for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动

这个指令包含两种格式:

  • @for $var from <start> through <end>
  • @for $var from <start> to <end>

区别在于 throughto 的含义:

  • 使用 through 时,条件范围包含 <start><end> 的值
  • 使用 to 时条件范围只包含 <start> 的值不包含 <end> 的值

$var 可以是任何变量,比如 $i<start><end> 必须是整数值

scss 复制代码
@for $i from 1 through 3 {
  .item-#{$i} { width: 2em * $i; }
}

编译为:

css 复制代码
.item-1 {
  width: 2em; }
.item-2 {
  width: 4em; }
.item-3 {
  width: 6em; }

@each

@each 指令的格式是 $var in <list>

  • $var 可以是任何变量名,比如 $length 或者 $name
  • <list> 是一连串的值,也就是值列表

@each 将变量 $var 作用于值列表中的每一个项目,然后输出结果,例如:

scss 复制代码
@each $animal in puma, sea-slug, egret, salamander {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
  }
}

编译为:

css 复制代码
.puma-icon {
  background-image: url('/images/puma.png'); }
.sea-slug-icon {
  background-image: url('/images/sea-slug.png'); }
.egret-icon {
  background-image: url('/images/egret.png'); }
.salamander-icon {
  background-image: url('/images/salamander.png'); }

@while

@while 指令重复输出格式直到表达式返回结果为 false。这样可以实现比 @for 更复杂的循环,只是很少会用到。例如:

scss 复制代码
$i: 6;
@while $i > 0 {
  .item-#{$i} { width: 2em * $i; }
  $i: $i - 2;
}

编译为:

scss 复制代码
.item-6 {
  width: 12em; }

.item-4 {
  width: 8em; }

.item-2 {
  width: 4em; }

Sass函数指令

Sass 支持自定义函数,并能在任何属性值或 Sass script 中使用,函数用于把一些比较复杂或经常用些的内容进行抽离(封装),以便重复使用

函数的定义与使用

函数的定义

scss 复制代码
@function function-name([$param1,$param2,...]){
    ...
    @return $value;
}

@return

它只允许在@函数体中使用,并且每个@function必须以@return结束。当遇到@return时,它会立即结束函数并返回其结果

函数的使用

例如:

scss 复制代码
@function row-cols-width($column) {
    @return percentage(1 / $column);
}


@for $i from 1 through 6 {
    .row-cols-#{$i}>* {
        width: row-cols-width($i);
    }
}

编译为:

css 复制代码
.row-cols-1 > * {
  width: 100%;
}
.row-cols-2 > * {
  width: 50%;
}
.row-cols-3 > * {
  width: 33.3333333333%;
}
.row-cols-4 > * {
  width: 25%;
}
.row-cols-5 > * {
  width: 20%;
}
.row-cols-6 > * {
  width: 16.6666666667%;
}

函数的参数与默认值

scss 复制代码
/** 
    *定义线性渐变
    *@param $direction  方向
    *@param $gradients  颜色过度的值列表
 */


@function background-linear-gradient($direction, $start-color, $end-color:blue) {
    @return linear-gradient($direction, $start-color, $end-color);
}
  • 正常传参调用
scss 复制代码
.header {
    background-image: background-linear-gradient(to right, red, green);
}
  • 省略默认值
scss 复制代码
.header {
    background-image: background-linear-gradient(to right, red);
}
  • 按照参数名传参
scss 复制代码
.header {
    background-image: background-linear-gradient($start-color: red, $direction: to bottom);
}

函数参数默认值可以是任意SassScript表达式,甚至可以引用前面的参数

任意参数

参数任意参数:

scss 复制代码
/** 
    *定义线性渐变
    *@param $direction  方向
    *@param $gradients  颜色过度的值列表
 */


@function background-linear-gradient($direction, $gradients...) {
    @return linear-gradient($direction, $gradients);
}


.header {
    background-image: background-linear-gradient(to bottom, red, green, blue);
}

调用任意参数:

scss 复制代码
$widths: 50px,30px,100px;
.logo {
    width: min($widths...);
}

mixin与function区别

  • 混入mixin主要是通过传递参数的方式输出多样化的样式,为了可以现实代码复用
  • 函数的功能主要是通过传递参数后,经过函数内部的计算,最后@return输出一个值

三元条件函数

定义:

scss 复制代码
if($condition, $if-true, $if-false);

判断$condition,如果条件成立,则返回$if-true的结果,如果条件不成立,则返回$if-false的结果

例如:if 的写法

scss 复制代码
$theme:'light';
.container {
    @if $theme=='light' {
        color: #000;
    }
    @else {
        color: #FFF;
    }
}

三元条件函数 if 改进:

scss 复制代码
$theme:'light';
.container {
    color: if($theme=='light', #000, #FFF);
}

Sass常用函数

更多函数请参考菜鸟教程

Color(颜色函数)

sass包含很多操作颜色的函数。例如:lighten()darken()函数可用于调亮或调暗颜色,opacify()函数使颜色透明度减少,transparent()函数使颜色透明度增加,mix()函数可用来混合两种颜色

scss 复制代码
p {
    height: 30px;
}

.p0 {
    background-color: #5c7a29;
}

.p1 {
    /* 
        让颜色变亮
        lighten($color, $amount)
        $amount 的取值在0% - 100% 之间
     */
    background-color: lighten(#5c7a29, 30%);
}

.p2 {
    // 让颜色变暗  通常使用color.scale()代替该方案
    background-color: darken(#5c7a29, 15%);
}

.p3 {
    // 降低颜色透明度  通常使用color.scale()代替该方案
    // background-color: opacify(#5c7a29,0.5);
    background-color: opacify(rgba(#5c7a29, 0.1), 0.5);
}

使用

html 复制代码
<p></p>
<p class="p0"></p>
<p class="p1"></p>
<p class="p2"></p>
<p class="p3"></p>

String(字符串函数)

Sass有许多处理字符串的函数,比如向字符串添加引号的quote()、获取字符串长度的str-length()和将内容插入字符串给定位置的str-insert()。Sass 字符串的起始索引值从 1 开始,不是0

函数 描述
quote(string) 给字符串添加引号
str-index(string ,substring) 返回 substring 子字符串第一次在 string 中出现的位置。如果没有匹配到子字符串,则返回 null
str-insert(string , insert , index) 在字符串 string 中 index 位置插入 insert
str-length(string) 返回字符串的长度
str-slice(string , start , end) 从 string 中截取子字符串,通过 start-at 和 end-at 设置始末位置,未指定结束索引值则默认截取到字符串末尾
to-lower-case(string) 将字符串转成小写
to-upper-case(string) 将字符串转成大写
unique-id() 返回一个无引号的随机字符串作为 id。只能保证单次的 Sass 编译中 id 的唯一性
unquote(string) 移除字符串的引号

例如:

scss 复制代码
p {
    &:after {
        content: quote(这是里面的内容);
    }
    background-color: unquote($string: "#F00");
    z-index:str-length("sass学习");
}

str-index(abcd, a)  => 1
str-index(abcd, ab) => 1
str-index(abcd, X)  => null
str-index(abcd, c)  => 3
to-lower-case("RUNOOB") //"runoob"
to-upper-case("runoob") //"RUNOOB"
unique-id() //uad053b1c
str-slice("abcd", 2, 3) //"bc"
str-slice("abcd", 2) //"bcd"
str-slice("abcd", -3, -2) //"bc"
str-slice("abcd", 2, -2) //"bc"

Math(数值函数)

数值函数处理数值计算,例如:percentage()将无单元的数值转换为百分比,round()将数字四舍五入为最接近的整数,min()max()获取几个数字中的最小值或最大值,random()返回一个随机数

函数 描述
abs(number) 返回一个数值的绝对值
ceil(number) 向上取整
comparable(num1 ,num2) 返回一个布尔值,判断 num1num2 是否可以进行比较
floor(number) 向下取整
max(number...) 返回最大值
min(number...) 返回最小值
percentage(number) 将数字转化为百分比的表达形式
random() 返回 0-1 区间内的小数
random(number) 返回 1 至 number 之间的整数,包括 1 和 limit
round(number) 返回最接近该数的一个整数,四舍五入

例如:

scss 复制代码
p {
    z-index: abs($number: -15); // 15
    z-index: ceil(5.8); //6
    z-index: max(5, 1, 6, 8, 3); //8
    opacity: random(); // 随机 0-1
}

List函数

List函数操作List,length()返回列表长度,nth()返回列表中的特定项,join()将两个列表连接在一起,append()在列表末尾添加一个值

函数 描述
append(list , value , [separator]) 将单个值 value 添加到列表尾部。separator 是分隔符,默认会自动侦测,或者指定为逗号或空格
index(list , value) 返回元素 value 在列表中的索引位置
is-bracketed(list) 判断列表中是否有中括号
join(list1 , list2 , [separator, bracketed]) 合并两列表,将列表 list2 添加到列表 list1 的末尾。separator 是分隔符,默认会自动侦测,或者指定为逗号或空格。 bracketed 默认会自动侦测是否有中括号,可以设置为 true 或 false
length(list) 返回列表的长度
list-separator(list) 返回一列表的分隔符类型。可以是空格或逗号
nth(list , n) 获取第 n 项的值
set-nth(list , n , value) 设置列表第 n 项的值为 value
zip(lists) 将多个列表按照以相同索引值为一组,重新组成一个新的多维度列表

例如:

scss 复制代码
p {
    z-index: length(12px); //1
    z-index: length(12px 5px 8px); //3
    z-index: index(a b c d, c); //3
    padding: append(10px 20px, 30px); // 10px 20px 30px
    color: nth($list: red blue green, $n: 2); // blue
}

append((a b c), d) //a b c d 
append((a b c), (d), comma) //a, b, c, d
zip(1px 2px 3px, solid dashed dotted, red green blue) //1px solid red, 2px dashed green, 3px dotted blue
set-nth(a b c, 2, x) //a x c

Map函数

Sass Map(映射)对象是以一对或多对的 key/value 来表示

Sass Map 是不可变的,因此在处理 Map 对象时,返回的是一个新的 Map 对象,而不是在原有的 Map 对象上进行修改

函数 描述
map-get(map , key) 返回 Map 中 key 所对应的 value(值)。如没有对应的 key,则返回 null 值
map-has-key(map , key) 判断 map 是否有对应的 key,存在返回 true,否则返回 false
map-keys(map) 返回 map 中所有的 key 组成的队列
map-merge(map1 , map2) 合并两个 map 形成一个新的 map 类型,即将 map2 添加到 map1的尾部
map-remove(map , keys...) 移除 map 中的 keys,多个 key 使用逗号隔开
map-values(map) 返回 map 中所有的 value 并生成一个队列

例如:

scss 复制代码
$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-get($font-sizes, "small") //12px

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-has-key($font-sizes, "big") //false

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-keys($font-sizes) //"small", "normal, "large"

$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

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-remove($font-sizes, "small") //("normal": 18px, "large": 24px)
map-remove($font-sizes, "small", "large") //("normal": 18px)

$font-sizes: ("small": 12px, "normal": 18px, "large": 24px)
map-values($font-sizes) //12px, 18px, 24px

Selector选择器函数

Sass 选择器函数用于查看与处理选择器。选择符相关函数可对CSS选择进行一些相应的操作,例如:selector-append()可以把一个选择符附加到另一个选择符,selector-unify()将两组选择器合成一个复合选择器

函数 描述
is-superselector(super , sub) 比较两个选择器匹配的范围,即判断 super 选择器是否包含了 sub 选择器所匹配的范围,是的话返回 true,否则返回 false
selector-append(selectors) 将第二个 (也可以有多个) 添加到第一个选择器的后面
selector-nest(selectors) 返回一个新的选择器,该选择器通过提供的列表选择器生成一个嵌套的列表
selector-parse(selector) 将字符串的选择符 selector 转换成选择器队列
selector-replace(selector , original , replacement) 给定一个选择器,用replacement 替换 original 后返回一个新的选择器队列
selector-unify(selector1 , selector2) 将两组选择器合成一个复合选择器。如两个选择器无法合成,则返回 null 值
simple-selectors(selectors) 将合成选择器拆为单个选择器

例如:

scss 复制代码
.header {
    background-color: #000;
    content: selector-append(".a", ".b", ".c") + '';
    content: selector-unify("a", ".disabled") + '';
}

is-superselector("div", "div.myInput") //true
is-superselector("div.myInput", "div") //false
is-superselector("div", "div") //true

selector-append("div", ".myInput") //div.myInput
selector-append(".warning", "__a") //.warning__a

selector-nest("ul", "li") //ul li
selector-nest(".warning", "alert", "div") //.warning div, alert div

selector-parse("h1 .myInput .warning") //('h1' '.myInput' '.warning')

selector-replace("p.warning", "p", "div") //div.warning

selector-unify("myInput", ".disabled") //myInput.disabled
selector-unify("p", "h1") //null

simple-selectors("div.myInput") //div, .myInput
simple-selectors("div.myInput:before") //div, .myInput, :before

调试函数

自检相关函数,例如:feature-exists()检查当前Sass版本是否存在某个特性,variable-exists()检查当前作用域中是否存在某个变量,mixin-exists()检查某个mixin是否存在

函数 描述
call(function , arguments...) 函数的动态调用,即调用函数 function 参数为 arguments,并返回结果
content-exists() 查看当前的混入是否传递 @content 块
feature-exists(feature) 检查当前的 Sass 实现是否支持该特性
function-exists(functionname) 检测指定的函数是否存在
get-function(functionname, css: false) 返回指定函数。如果 css 为 true,则返回纯 CSS 函数。
global-variable-exists(variablename) 检测某个全局变量是否定义
inspect(value) 返回一个字符串的表示形式,value 是一个 sass 表达式。
mixin-exists(mixinname) 检测指定混入 (mixinname) 是否存在
type-of(value) 返回值类型。返回值可以是 number, string, color, list, map, bool, null, function, arglist
unit(number) 返回传入数字的单位(或复合单位)
unitless(number) 返回一个布尔值,判断传入的数字是否带有单位
variable-exists(variablename) 判断变量是否在当前的作用域下

例如:

scss 复制代码
$color:#F00;
@mixin padding($left:0, $top:0, $right:0, $bottom:0) {
    padding: $top $right $bottom $left;
}


.container {
    @if variable-exists(color) {
        color: $color;
    }
    @else {
        content: "$color不存在";
    }
    @if mixin-exists(padding) {
        @include padding($left: 10px, $right: 10px);
    }
}

type-of(15px) //number
type-of(#ff0000) //color

unit(15px) //px

unitless(15px) //false
unitless(15) //true

自检函数通常用在代码的调试上

Sass@import

@import导入

Sass 拓展了@import的功能,允许其导入 SCSS 或 Sass 文件。被导入的文件将合并编译到同一个 CSS 文件中,另外,被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用,例如:

public.scss

scss 复制代码
$font-base-color:#333;

index.scss里面使用

scss 复制代码
@import "public";
$color:#666;
.container {
    border-color: $color;
    color: $font-base-color;
}

在普通的 CSS 中,@import 是用来导入一个外部 CSS 文件,它会下载并解析所导入的文件

在 Sass 中,@import 不仅可以导入外部的 CSS 文件,还可以导入其他 Sass 文件

其区别在于 Sass 的 @import 指令在处理时会将所导入的文件合并到当前文件中,并生成一份完整的 CSS 文件,因此需要注意多个 Sass 文件中可能存在命名冲突的情况。此外,Sass 中的 @import 指令支持路径变量、CSS 扩展名和通配符

如下几种方式,都将作为普通的 CSS 语句,不会导入任何 Sass 文件

  • 文件拓展名是 .css
  • 文件名以 http:// 开头
  • 文件名是 url()
  • @import 包含 media queries
css 复制代码
@import "public.css";
@import url(public);
@import "http://xxx.com/xxx";
@import 'landscape' screen and (orientation:landscape);

局部文件

Sass源文件中可以通过@import指令导入其他Sass源文件,被导入的文件就是局部文件,局部文件让Sass模块化编写更加容易

如果一个目录正在被Sass程序监测,目录下的所有scss/sass源文件都会被编译,但通常不希望局部文件被编译,因为局部文件是用来被导入到其他文件的。如果不想局部文件被编译,文件名可以以下划线 (_)开头

例如:

_theme.scss

scss 复制代码
$border-color:#999;
$background-color:#f2f2f2;

使用

scss 复制代码
@import "theme";
.container {
    border-color: $border-color;
    background-color: $background-color;
}

@import 引入的theme.scss,可以没有,这是允许的,这也就意味着,同一个目录下不能同时出现两个相关名的sass文件(一个不带下划线,一个带下划线),添加下划线的文件将会被忽略

嵌套 @import

大多数情况下,一般在文件的最外层(不在嵌套规则内)使用 @import,其实,也可以将 @import 嵌套进 CSS 样式或者 @media 中,与平时的用法效果相同,只是这样导入的样式只能出现在嵌套的层中

例如

_base.scss

scss 复制代码
.main-color {
    color: #F00;
}

使用:

scss 复制代码
.container {
    @import "base";
}

注意:@import不能嵌套使用在控制指令或混入中

Sass@use

从其他Sass样式表加载mixin,function和变量,并将来自多个样式表的CSS组合在一起,@use加载的样式表被称为模块,多次引入只包含一次

@use也可以看作是对 @import 的增强

语法:

scss 复制代码
@use '<url>' [as alias|namespace] 

加载普通SCSS、CSS

use/_common.scss

scss 复制代码
$font-size:14px !default;
* {
    margin: 0;
    padding: 0;
    font-size: $font-size;
    color: #333;
}         


@function column-width($col, $total) {
    @return percentage($col/$total);
}


@mixin bgColor($bg-color:#f2f2f2) {
    background-color: $bg-color;
}

use/about.css

css 复制代码
h1 {
    font-size: 24px;
}

使用:

scss 复制代码
@use 'use/common';
@use 'use/about';

加载模块

新增_global.scss

scss 复制代码
$font-size:28px;
@mixin base($color:#F00) {
    color: $color;
}


.gclass {
    background-color: #F00;
}

@import的方式

scss 复制代码
@import 'use/common';
@import 'use/global';
@import 'use/global';
body {
    font-size: $font-size;
    @include base('#FFF');
    @include base('#000');
    width: column-width(3, 12);
    @include bgColor('#F00');
}

@use引入同一个文件多次,不会重复引入,而@import会重复引入

@use的方式

scss 复制代码
@use 'use/common';
@use 'use/global' as g1;
@use 'use/global' as g2;
body {
    font-size: common.$font-size;
    @include g1.base('#FFF');
    @include g2.base('#000');
    width: common.column-width(3, 12);
    @include common.bgColor('#F00');
}

通过@use引入的样式默认把文件名作为模块名使用,你可以通过as的形式重新取一个别名

@use引入多个文件时,每个文件都是单独的模块,相同变量名不会覆盖,通过模块名访问,而@import变量会被覆盖

@use取消别名

可能@use "" as * 来取消命名空间,这种方式加载的模块被提升为全局模块

scss 复制代码
@use 'use/common';
@use 'use/global' as *;
@use 'use/global' as g2;
body {
    font-size: $font-size;
    @include base('#FFF');
    @include g2.base('#000');
    width: common.column-width(3, 12);
    @include common.bgColor('#F00');
}

定义私有成员

如果加载的模块内部有变量只想在模块内使用,可使用-_定义在变量头即可

例如:

scss 复制代码
$-font-size:14px;
* {
    margin: 0;
    padding: 0;
    font-size: $-font-size;
    color: #333;
}
@use 'use/common';
@use 'use/global' as *;
@use 'use/global' as g2;
body {
    font-size: common.$-font-size; 
    // 报错 Error: Private members can't be accessed from outside their modules.
    @include base('#FFF');
    @include g2.base('#000');
}

定义默认值

!default能为变量定义默认值

scss 复制代码
$font-size:14px !default;
* {
    margin: 0;
    padding: 0;
    font-size: $font-size;
    color: #333;
}

@use引入时可通过with(...)修改默认值

scss 复制代码
@use 'use/common' with ( $font-size:16px, );
@use 'use/global' as *;
@use 'use/global' as g2;
common.$font-size:28px; // 也可能通过这种方式覆盖
body {
    font-size: common.$font-size;
    @include base('#FFF');
    @include g2.base('#000');
}

默认加载index.scss

创建_index.scss,见同级的.scss文件样式引入到_index.scss,后面只需要引入_index.scss即可

Sass @forward

通过 @forward加载一个模块的成员,并将这些成员当作自己的成员对外暴露出去,类似于 es6 的 export通常用于跨多个文件组织 Sass 库

转发、合并scss

转发

创建_common.scss

scss 复制代码
$font-size:14px !default;
* {
    margin: 0;
    padding: 0;
    font-size: $font-size;
    color: #333;
}

@function column-width($col, $total) {
    @return percentage($col/$total);
}

@mixin bgColor($bg-color:#f2f2f2) {
    background-color: $bg-color;
}

创建merge.scss

scss 复制代码
@forward 'uses/common';

使用:

scss 复制代码
@use 'merge';
.body {
    font-size: merge.$font-size;
    width: merge.column-width(3, 12);
    @include merge.bgColor('#F00');
}

可以使用到_common.scss中的变量、函数以及样式,转发成功

合并

新增一个_global.scss

scss 复制代码
$font-size:28px;
@mixin base($color:#F00) {
    color: $color;
}

.gclass {
    background-color: #F00;
}

统一转发merge.scss

scss 复制代码
@forward 'uses/common';
@forward 'uses/global';

使用:

scss 复制代码
@use 'merge';
.body {
    font-size: merge.$font-size;
    width: merge.column-width(3, 12);
    @include merge.bgColor('#F00');
    @include merge.base('#000');
}

添加前缀

语法: @forward "<url>" as <prefix>-*

将给定的前缀添加到模块转发的每个mixin,函数和变量名称的开头。例如,如果模块定义了一个名为的成员reset并进行了转发as list-*,则下游样式表会将其称为 list-reset

实例

scss 复制代码
// src/_list.scss
@mixin reset {
  margin: 0;
  padding: 0;
  list-style: none;
}
// bootstrap.scss
@forward "src/list" as list-*;

// styles.scss
@use "bootstrap";

li {
  @include bootstrap.list-reset;
}

编译为 CSS 结果:

css 复制代码
li {
  margin: 0;
  padding: 0;
  list-style: none;
}

选择性转发

默认情况下,@forward 会将一个模块中所有成员都转发,如果只想转发某些成员,可使用:

  • @forward "module" hide $var, mixinName, fnName 禁止转发某些成员
  • @forward "module" show $var, mixinName, fnName 只转发某些成员

各个成员通过逗号 , 分隔开,如果成员是变量,不能省略 $ 符号

scss 复制代码
@forward 'uses/common' as com-* hide com-bgColor,$com-font-size;
@forward 'uses/global' as glob-* show glob-base;

转发前加上前缀,用于避免相同变量造成的问题

使用:

scss 复制代码
@use 'merge';
.body {
    font-size: merge.$com-font-size; //报错,不能使用
    width: merge.com-column-width(3, 12); //报错,不能使用
    @include merge.com-bgColor('#000');
    @include merge.glob-base('#000');
}

配置模块

@forward规则还可以使用configuration加载模块:

SCSS

scss 复制代码
// _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;
}

// _opinionated.scss
@forward 'library' with (
  $black: #222 !default,
  $border-radius: 0.1rem !default
);

// style.scss
@use 'opinionated' with ($black: #333);

编译为 CSS 结果:

css 复制代码
code {
  border-radius: 0.1rem;
  box-shadow: 0 0.5rem 1rem rgba(51, 51, 51, 0.15);
}

Sass@at-root

@at-root可以使被嵌套的选择器或属性跳出嵌套

语法:

scss 复制代码
@at-root <selector>{
    ...
}

普通嵌套

scss 复制代码
.parent {
    font-size: 12px;
    .child {
        font-size: 14px;
        .son {
            font-size: 16px;
        }
    }
}
  • 作用某个选择器使其跳出嵌套
scss 复制代码
.parent {
    font-size: 12px;
    @at-root .child {
        font-size: 14px;
        @at-root .son {
            font-size: 16px;
        }
    }
}

编译为:

css 复制代码
.parent {
  font-size: 12px;
}
.child {
  font-size: 14px;
}
.son {
  font-size: 16px;
}
  • 作用某些选择器使其跳出嵌套
scss 复制代码
.parent {
    font-size: 12px;
    @at-root {
        .child-1 {
            font-size: 14px;
        }
        .child-2 {
            font-size: 16px;
        }
    }
}

编译为:

css 复制代码
.parent {
  font-size: 12px;
}
.child-1 {
  font-size: 14px;
}

.child-2 {
  font-size: 16px;
}

@at-root与&的结合

&的使用:

css 复制代码
.foo {
    & .bar {
        color: gray;
    }
}

.foo {
    & {
        color: gray;
    }
}

.foo {
    .bar & {
        color: gray;
    }
}

&@at-root效果一样

@at-root结合#{&}实现BEM效果

理解BEM:zhuanlan.zhihu.com/p/122214519

官网学习:en.bem.info/methodology...

BEM完整命名规则:block-name__element-name--modifier-name (也可以换成驼峰式命名)

比较BEM的一则样式

css 复制代码
.block{width: 1000px;}
.block__element{font-size: 12px;}
.block--modifier{font-size: 14px;}
.block__element--modifier{font-size: 16px;} 

@at-root结合#{&}实现:

scss 复制代码
.block {
    width: 1000px;
    @at-root #{&}__element {
        font-size: 12px;
        @at-root #{&}--modifier {
            font-size: 16px;
        }
    }
    @at-root #{&}--modifier {
        font-size: 14px;
    }
}

//或
.block {
    width: 1000px;
    @at-root {
        #{&}__element {
            font-size: 12px;
            @at-root #{&}--modifier {
                font-size: 16px;
            }
        }
        #{&}--modifier {
            font-size: 14px;
        }
    }
}

实现上也能直接用&实现:

scss 复制代码
.block {
    width: 1000px;
    &__element {
        font-size: 12px;
        &--modifier {
            font-size: 16px;
        }
    }
    &--modifier {
        font-size: 14px;
    }
}

超越样式规则

就其本身而言,@at-root不仅摆脱的样式规则。任何类似@media或的规则@supports都将保留

但如果这不是想要的,则可以使用诸如媒体查询功能:

  • @at-root (with: <rules...>) { ... } :查询将排除 列出的规则以外的所有规则
  • @at-root (without: <rules...>) { ... }:查询告诉Sass应该排除哪些规则

除了规则名称外,还有两个可以在查询中使用的特殊值:

  • rule指样式规则。例如,@at-root (with: rule) 排除所有规则,但保留样式规则
  • all指所有规则*,*应排除样式规则
scss 复制代码
@media screen {
  .parent {
    font-size: 12px;
    @at-root (without: media) {
      .child {
        font-size: 14px;
        .son {
          font-size: 16px;
        }
      }
    }
  }
}

@supports (display: flex) {
  .parent {
      font-size: 12px;
      @at-root (with: supports) {
          .child {
              font-size: 14px;
              .son {
                  font-size: 16px;
              }
          }
      }
  }
}

编译为:

css 复制代码
@media screen {
  .parent {
    font-size: 12px;
  }
}
.parent .child {
  font-size: 14px;
}
.parent .child .son {
  font-size: 16px;
}

@supports (display: flex) {
  .parent {
    font-size: 12px;
  }
  .child {
    font-size: 14px;
  }
  .child .son {
    font-size: 16px;
  }
}

宝藏学习网分享给大家(适合萌新),大家有好的学习资源网也可以推荐,感谢!

千古图文教程老姚项目实战代码随想录绿叶学习网freeCodeCamp前端面试宝典前端学习路线

相关推荐
九旬2 分钟前
亲测有效!Cursor限制访问的破解方法,程序员必看!
前端·后端
摘笑10 分钟前
Husky + Commitlint + ESLint:打造前端项目的铁三角护城河
前端·代码规范·前端工程化
冻咸鱼11 分钟前
Ajax简单介绍及Axios请求方式的别名
前端·javascript·笔记·ajax
葡萄城技术团队14 分钟前
在 Angular 应用程序中使用 Genkit 的完整指南
前端·angular.js
逆向APP27 分钟前
swiftui使用String Catalog文件实现语言本地化
前端
欧阳天羲30 分钟前
金融大前端中的 AI 应用:智能投资顾问与风险评估
前端·人工智能·金融
24kHT31 分钟前
2.4 组件间通信Props(父传子)
前端·javascript·vue.js
xcx665734 分钟前
mspm0系列入门——基础
前端
每天开心1 小时前
别再怕 useRef 了!一篇文章讲清楚它和 DOM 的关系
前端·面试·前端框架