sass的基本语法整理

整理下sass的常用语法

1、变量

sass中可以使用变量,变量名以$开头:

$c: #fff;

body {
  color: $c;
}
/* 编译成css */
body {
  color: #fff;
}

注意变量声明遵循实现了块级作用域,如果在选择器内声明的变量,只能在选择器内部使用:

// 正确案例
body {
  width: 100%;
  height: 100%;
  $c: red;

  #app {
    color: $c;
  }
}
/* 编译成css */
body {
  width: 100%;
  height: 100%;
}

body #app {
  color: red;
}
// 错误案例
body {
  width: 100%;
  height: 100%;
  $c: red;
}

.box {
    color: $c;
}
// 错误 Error: Undefined variable: "$c"

如果要在选择器内声明全局变量,需要使用!global

body {
  width: 100%;
  height: 100%;
  $c: red !global;
}

.box {
    color: $c;
}
/* 编译成css */
body {
  width: 100%;
  height: 100%;
}

.box {
  color: red;
}

变量除了在属性值内使用,也可用于属性名或者注释中,但是需要使用#{}包裹:

$c: color;

#app {
    background-#{color}: red;
}
/* 编译成css */
#app {
  background-color: red;
}
$lang: css;
/* 编译成#{$lang} */
/* 编译成css */

2、嵌套语法

sass中可以将子标签嵌套在父标签中,避免了使用父子选择器时重复书写父标签:

$c: #fff;

body {
    color: $c;

    #app {
        width: 100%;
        height: 100%;
    }
}
/* 编译成css */
body {
  color: #fff;
}

body #app {
  width: 100%;
  height: 100%;
}

如果要在嵌套语法中使用父级选择器,使用&即可,它会被替换成父级选择器,常用于:hover::before等:

a {
    &:hover {
        color: red;
    }
}
/* 编译成css */
a:hover {
  color: red;
}

3、继承

使用@extend可以继承样式:

body {
    .flex {
        display: flex;
        justify-content: space-around;
        align-items: center;
        flex-wrap: wrap;
    }

    .container {
        @extend .flex;
        width: 100%;
        height: 100%;
        color: #000;
    }
}
/* 编译成css */
body .flex, body .container {
  display: flex;
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
}

body .container {
  width: 100%;
  height: 100%;
  color: #000;
}

如果要继承多个样式,可以使用多次@extend,也可以使用逗号分隔:

body {
    #app {
        width: 100%;
        height: 100%;
    }

    .container {
        color: pink;
    }

    .box {
        @extend #app, .container;
    }
}
/* 编译成css */
body #app, body .box {
  width: 100%;
  height: 100%;
}

body .container, body .box {
  color: pink;
}

注意:使用媒体响应时,只能继承@media内的样式,不能继承外部样式,因为这样会编译出很多不必要的样式,因此sass编译时会报错
正确做法:

@media screen {
    body {
        width: 100%;
    }

    #app {
        @extend body;
    }
}
/* 编译成css */
@media screen {
  body, #app {
    width: 100%;
  }
}

错误做法:

body {
    width: 100%;
}

@media screen {
    #app {
        @extend body;
    }
}
// 报错 You may not @extend an outer selector from within @media.
//      You may only @extend selectors within the same directive.

有时候我们只是想提取一个公共样式,但是并不想它作为选择器出现在编译后的css中。这时可以使用占位符,占位符用%开头:

// 案例1
%center {
    width: 200px;
    height: 200px;
    margin: 0 auto;
}

#app {
    @extend %center;
    color: #000;
}
/* 编译成css */
#app {
  width: 200px;
  height: 200px;
  margin: 0 auto;
}

#app {
  color: #000;
}
// 案例2
body %center {
    width: 200px;
    height: 200px;
    margin: 0 auto;
}

#app {
    @extend %center;
    color: #000;
}
/* 编译成css */
body #app {
  width: 200px;
  height: 200px;
  margin: 0 auto;
}

#app {
  color: #000;
}

4、注释

sass提供了三种注释,分别是///**//*!*/,第一种注释在编译后会被去掉,后两种不会,且第三种在压缩后仍会保留,通常用于表示版权信息。

/* 编译成css */
// 我会被去掉
/*! 压缩后我也在 */
body {
  width: 100%;
  height: 100%;
}

/* 编译成css */
/*! 压缩后我也在 */
body {
  width: 100%;
  height: 100%;
}

5、根选择器@at-root

实际不应该叫根选择器(css中有个叫根选择器的::root),而是将被@at-root包裹的样式放在最顶层。

body {
  width: 100%;
  height: 100%;

  #app {
    color: red;
  }

  @at-root {
    .container {
      background-color: #fff;
    }
  }
}
/* 编译成css */
body {
  width: 100%;
  height: 100%;
}

body #app {
  color: red;
}

.container {
  background-color: #fff;
}

使用@at-root的好处是无论嵌套多深,都可以直接在@at-root中书写顶层样式。

6、运算

sass中可以使用运算,配合变量可以大幅度避免需要手动计算的情况:

$w: 100px;
$h: 300px;
$bw: 1px;

body {
  width: $w + 100px;
  height: $h - 100px;
  border-bottom-width: $bw * 1;
  border-top-width: $bw / 1;
}
/* 编译成css */
body {
  width: 200px;
  height: 200px;
  border-bottom-width: 1px;
  border-top-width: 1px;
}

注意以下情况/会被解释成除法:

  • 如果值,或值的一部分,是变量或者函数的返回值
  • 如果值被圆括号包裹
  • 如果值是算数表达式的一部分
p {
 font: 10px/8px; // 普通的css,不会被转化
 $width: 1000px;
 width: $width/2; // 使用了变量,会被转化
 width: round(1.5) / 2; // 使用了函数,会被转化
 height: (500px/2); // 使用了括号,会被转化
 margin-left: 5px + 8px/2px; // 使用了加号,会被转化
}
/* 编译成css */
p {
  font: 10px/8px;
  width: 500px;
  width: 1;
  height: 250px;
  margin-left: 9px;
}

如果要确保/被解释为除法,使用括号包裹即可。如果不想让/被解释成除法,可以使用#{}包裹:

p {
  $font-size: 12px;
  $line-height: 30px;
  font: #{$font-size}/#{$line-height};
}
/* 编译成css */
p {
  font: 12px/30px;
}

使用+可以拼接字符串,字符串是否带引号以左边为准:

p:before {
  content: "Foo " + Bar;
  font-family: sans- + "serif";
}
/* 编译成css */
p:before {
  content: "Foo Bar";
  font-family: sans-serif;
}

如果字符串带引号,则可以使用#{}插入动态的值:

p:before {
  content: "I ate #{5 + 10} pies!";
}
/* 编译成css */
p:before {
  content: "I ate 15 pies!";
}

JavaScript一样,使用圆括号可以改变运算顺序:

p {
  height: 1em + 2em * 3;
  width: (1em + 2em) * 3;
}
/* 编译成css */
p {
  height: 7em;
  width: 9em;
}

除了四则运算以外,还可以使用关系判断语句:><>=<===!=。其中前四个只能用于数值,后两个可用于任意类型。它们都返回布尔值,常用于判断语句。
sass中的数据类型如下:

  • 数字,1, 2, 13, 10px
  • 字符串,有引号字符串与无引号字符串,"foo", 'bar', baz
  • 颜色,blue, #04a3f9, rgba(255,0,0,0.5)
  • 布尔型,true, false
  • 空值,null
  • 数组 (list),用空格或逗号作分隔符,1.5em 1em 0 2em, Helvetica, Arial, sans-serif
  • maps, 相当于 JavaScript 的 object,(key1: value1, key2: value2)

7、导入(import)

sass提供了导入功能,使用@import即可:

@import "common.scss";

需要注意的是,如果没有提供后缀名,sass会尝试按照后缀名scsssass查找文件。以下情况sass不会进行解析,而是原样导入:

  • 指定了文件扩展名为css
  • 文件路径以http://开头
  • 使用的是css的导入语法@import url(路径)
  • @import包含媒体查询
@import "normalize.css";
@import "http://foo.com/bar";
@import url(common.css);
@import "foo" screen;
/* 编译成css */
@import "normalize.css";
@import "http://foo.com/bar";
@import url(common.css);
@import "foo" screen;

8、控制语句

在sass中提供了一些条件判断语句和循环语句:@if@else-if@else@for@each@while

$type: monster;

p {
  @if $type == ocean {
    color: blue;
  } @else if $type == matador {
    color: red;
  } @else if $type == monster {
    color: green;
  } @else {
    color: black;
  }
}
/* 编译成css */
p {
  color: green;
}

@for的使用有两种格式,一种是@for 变量名 from 开始 through 结束@for 变量名 from 开始 to 结束,它们的区别在于第一种范围是包含开始和结束,而第二种不包括结束。用数学中的开区间和闭区间来表示就是[开始, 结束][开始, 结束)的区别:

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

@for $i from 1 to 3 {
  .item-#{$i} { height: 2em * $i; }
}
/* 编译成css */
.item-1 {
  width: 2em;
}

.item-2 {
  width: 4em;
}

.item-3 {
  width: 6em;
}

.item-1 {
  height: 2em;
}

.item-2 {
  height: 4em;
}

@for只能表示数值范围,如果要循环非数值,需要使用@each,它可以遍历list

@each $var in top, bottom, left, right {
  body {
    border-#{$var}-width: 1px;
  }
}
/* 编译成css */
body {
  border-top-width: 1px;
}

body {
  border-bottom-width: 1px;
}

body {
  border-left-width: 1px;
}

body {
  border-right-width: 1px;
}

注意list既可以用,分隔,也可以使用空格分隔,将其理解为数组即可。因此也存在二维的list

@each $animal, $color, $cursor in (puma, black, default),
                                  (sea-slug, blue, pointer),
                                  (egret, white, move) {
  .#{$animal}-icon {
    background-image: url('/images/#{$animal}.png');
    border: 2px solid $color;
    cursor: $cursor;
  }
}
/* 编译成css */
.puma-icon {
  background-image: url("/images/puma.png");
  border: 2px solid black;
  cursor: default;
}

.sea-slug-icon {
  background-image: url("/images/sea-slug.png");
  border: 2px solid blue;
  cursor: pointer;
}

.egret-icon {
  background-image: url("/images/egret.png");
  border: 2px solid white;
  cursor: move;
}

上面的用法有点类似JavaScript中同时使用循环和解构:

const list = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
]
for (const [a, b, c] of list) {
  console.log(a, b, c)
}
// 输出
// 1, 2, 3
// 4, 5, 6
// 7, 8, 9

除了可以遍历listeach还可以遍历map:

@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
  #{$header} {
    font-size: $size;
  }
}
/* 编译成css */
h1 {
  font-size: 2em;
}

h2 {
  font-size: 1.5em;
}

h3 {
  font-size: 1.2em;
}

sass里面的 map 类似于JavaScript中的对象:

const map = { a: 1, b: 2, c: 3 }
for (const [key, value] of Object.entries(map)) {
  console.log(key, value)
}
// 输出
// a 1
// b 2
// c 3

最后是while循环,和JavaScript类似:

$i: 6;
@while $i > 0 {
  .item-#{$i} { width: 2em * $i; }
  $i: $i - 2;
}
/* 编译成css */
.item-6 {
  width: 12em;
}

.item-4 {
  width: 8em;
}

.item-2 {
  width: 4em;
}

9、混入(mixin)

mixin通常用于抽离公共样式到独立的文件中,类似于JavaScript中常见的将工具方法抽离到utils文件夹中一样,用法类似于函数声明,只是使用时需要借助@include

@mixin clearfix {
  display: inline-block;

  &:after {
    content: ".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
  }

  * html & { height: 1px }
}

.box {
  @include clearfix; 
}
/* 编译成css */
.box {
  display: inline-block;
}

.box:after {
  content: ".";
  display: block;
  height: 0;
  clear: both;
  visibility: hidden;
}

* html .box {
  height: 1px;
}

也可以给mixin传参:

@mixin set-border($w, $c) {
  border: solid $w $c;
}

.box {
  @include set-border(1px, pink);
}
/* 编译成css */
.box {
  border: solid 1px pink;
}

也可以给mixin设置默认值:

@mixin set-border($dir: top, $w: 1px, $c: pink) {
  border-#{$dir}: solid $w $c;
}

.box1 {
  @include set-border(); // 不传参数时括号也可省略
}

.box2 {
  @include set-border(bottom, 2px, purple);
}
/* 编译成css */
.box1 {
  border-top: solid 1px pink;
}

.box2 {
  border-bottom: solid 2px purple;
}

当不确定参数数量时,可以使用...

@mixin box-shadow($shadows...) {
  -moz-box-shadow: $shadows;
  -webkit-box-shadow: $shadows;
  box-shadow: $shadows;
}

.shadows {
  @include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
/* 编译成css */
.shadows {
  -moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  -webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
  box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}

mixin也可以接受一个列表list,配合...,可以一次传入多个参数:

@mixin colors($text, $background, $border) {
  color: $text;
  background-color: $background;
  border-color: $border;
}

$values: #ff0000, #00ff00, #0000ff;
.primary {
  @include colors($values...);
}
/* 编译成css */
.primary {
  color: #ff0000;
  background-color: #00ff00;
  border-color: #0000ff;
}

有时候也需要从外部传入一段代码到mixin,传入的样式代码可以通过@content得到,这种用法类似于vue中的默认插槽:

@mixin apply-to-ie6-only {
  * html {
    @content;
  }
}

@include apply-to-ie6-only {
  #logo {
    background-image: url(/logo.gif);
  }
}
/* 编译成css */
* html #logo {
  background-image: url(/logo.gif);
}

10、自定义函数

虽然mixin已经足够强大,但有时我们不需要指定属性名而只是单纯的想要返回属性值,此时可以通过自定义函数,它和mixin类似,不同点在于它必须有返回值,使用@return返回。自定义函数使用@function声明:

$grid-width: 40px;
$gutter-width: 10px;

@function grid-width($n) {
  @return $n * $grid-width + ($n - 1) * $gutter-width;
}

#sidebar {
  width: grid-width(5);
}
/* 编译成css */
#sidebar {
  width: 240px;
}

参考文献

sass官方文档

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值