Sass基础人门-学习笔记

一、Sass的语法格式及编译调试

1. Sass和scss的区别

本质上来说是同一个东西,只是语法上有细微的差异:
现有一段基础CSS代码:

body {
  font: 100% Helvetica, sans-serif;
  color: #333;
}

使用Sass语法编译如下:

$font-stack: Helvetica, sans-serif
$primary-color: #333

body
  font: 100% $font-stack
  color: $primary-color

Sass 语法是 Sass 的最初语法格式,他是通过 tab 键控制缩进的一种语法规则,而且这种缩进要求非常严格。另外其不带有任何的分号和大括号。常常把这种格式称为 Sass 老版本,其文件名以“.sass”为扩展名。

使用Scss语法编译如下:

$fon-stack: Helvetica,sans-serif;
$primary-color: #333;

body{
   font: 100% $font-stack;
   color: $primary-color;
}

SCSS 是 Sass 的新语法格式,从外形上来判断他和 CSS 长得几乎是一模一样,代码都包裹在一对大括号里,并且末尾结束处都有一个分号。其文件名格式常常以“.scss”为扩展名。

2. Sass 编译

在项目中还是引用“.css”文件,Sass 只不过是做为一个预处理工具,提前帮你做事情,只有你需要时候,他才有攻效。所以Sass 的编译 就出现了。因为 Sass 开发之后,要让 Web 页面能调用 Sass 写好的东西,就得有这么一个过程,这个过程就称之为 Sass 编译过程。Sass 的编译有多种方法:

  • 命令编译
  • GUI工具编译
  • 自动化编译

2.1 Sass命令编译

  • 单文件编译:↓
sass sass/style.scss:css/style.css
  • 多文件编译:↓
sass sass/:css/

上面的命令表示将项目中“sass”文件夹中所有“.scss”(“.sass”)文件编译成“.css”文件,并且将这些 CSS 文件都放在项目中“css”文件夹中。

  • 监测代码变化,实时编译:↓
sass --watch sass/style.scss: css/style.css
sass--watch.jpg

一旦我的 sacc/style.scss 文件有任何修改,只要我重新保存了修改的文件,命令终端就能监测,并重新编译出文件。

2.2 Sass GUI工具编译
实用性完全比不上命令行,我直接跳过了。

2.3 Sass 自动化编译
现在还不会用,留着后面来看。

  • Grunt 配置 Sass编译的示例代码:↓
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: {
            dist: {
                files: {
                    'style/style.css' : 'sass/style.scss'
                }
            }
        },
        watch: {
            css: {
                files: '**/*.scss',
                tasks: ['sass']
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default',['watch']);
}
  • Gulp 配置 Sass 编译的示例代码:↓
var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    gulp.src('./scss/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./css'));
});

gulp.task('watch', function() {
    gulp.watch('scss/*.scss', ['sass']);
});

gulp.task('default', ['sass','watch']);

3. [Sass]不同样式风格的输出方法

3.1 [Sass]嵌套输出方式 nested

例如这样一段sass:

$bg-color: #f0f0f0;
$red-color: #ff5050;
.nav {
  background-color: $bg-color;
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
    color: $red-color;
  }
}

这段代码在编译的时候需要带上参数:--style nested (默认以这个参数编译)↓

sass --watch sass/style.scss:css/style.css --style nested

编译以后的css样式如下:↓

.nav {
  background-color: #f0f0f0; }
  .nav ul {
    margin: 0;
    padding: 0;
    list-style: none; }
  .nav li {
    display: inline-block; }
  .nav a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
    color: #ff5050; }
默认以nested方式编译.png

3.2 [Sass]展开输出方式 expanded
这个输出的 CSS 样式风格和 nested 类似,只是大括号在另起一行,同样上面的代码,在编译时需要带参数--style expanded

sass --watch sass/style.scss:css/style.css --style expanded

编译出来:↓

.nav{
    background-color: #f0f0f0;
}
.nav ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.nav li {
  display: inline-block;
}
.nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none;
}
以expanded方式编译.png

3.3 [Sass]紧凑输出方式 compact
在编译的时候带上参数--style compact:

sass --watch sass/style.scss:css/style.css --style compact

编译出来:↓

.nav { background-color: #f0f0f0; }
.nav ul { margin: 0; padding: 0; list-style: none; }
.nav li { display: inline-block; }
.nav a { display: block; padding: 6px 12px; text-decoration: none; color: #ff5050; }
以compact方式编译.png

3.4 [Sass]压缩输出方式 compressed
在编译的时候带上参数 --style compressed:

sass --watch sass/style.scss:css/style.css --style compressed

压缩输出方式会去掉标准的 Sass 和 CSS 注释及空格。也就是压缩好的 CSS 代码样式风格:↓

.nav{background-color:#f0f0f0}.nav ul{margin:0;padding:0;list-style:none}.nav li{display:inline-block}.nav a{display:block;padding:6px 12px;text-decoration:none;color:#ff5050}
image.png

3.5 [Sass]的调试
在Chrome的开发者工具中找到Sources,在这里的修改可以及时得到反馈,和在websorem里面操作一样,保存一次编译一次。

浏览器调试.png

二、Sass的基本特性-基础

1、声明变量

Sass 变量.png

上图非常清楚告诉了大家,Sass 的变量包括三个部分:

  • 声明变量的符号“$”
  • 变量名称
  • 赋予变量的值

Bootstrap Sass版本定义primary-button的方法:↓

$brand-primary : darken(#428bca, 6.5%) !default; // #337ab7
$btn-primary-color : #fff !default;
$btn-primary-bg : $brand-primary !default;
$btn-primary-border : darken($btn-primary-bg, 5%) !default;

2、普通变量与默认变量

- 普通变量:

定义之后可以在全局使用:↓

$fontSize: 14px;
body{
    font-size: $fontSize;
}

编译后的代码:↓

body{font-size:14px;}

- 默认变量:
sass 的默认变量仅需要在值后面加上!default即可。

$baseLineHeight: 1.5 !default;
body{
    line-height: $baseLineHeight;
}

编译后的代码:↓

body{line-height:1.5;}

覆盖默认样式:只需要在默认变量之前重新声明下变量即可 ↓

$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
    line-height: $baseLineHeight;
}

编译后的代码:↓

body{line-height:2;}

默认变量的价值在进行组件化开发的时候会非常有用。

3、变量的调用

定义变量:

$brand-primary: darken(#428bca,6.5%) !default;  //#337ab7
$btn-primary-color: #fff default;
$btn-primary-bg: $brand-primary !default; 
$btn-primary-border: darken($btn-primary-bg,4%)  !default;

调用:

.btn-primary{
    background-color: $btn-primary-bg;
    color: $btn-primary-color;
    border: 1px solid $btn-primary-border;
}

编译出来的CSS:

.btn-primary{
    background-color: #337ab7;
    color: #fff;
    border: 1px solid #2e6da4;
}

4、局部变量和全局变量

- 全局变量与局部变量
示例:

$color: orange !default;  //定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量)
.block 
  color: $color;        //调用全局变量
}
em{
  $color: red;          //定义局部变量
  a {
    color: $color;      //调用局部变量
  }
}
span{
  color: $color;        //调用全局变量
}

css编译结果:↓

.block{color: orange;}
em a{color: red;}
span{color: orange;}

可以得知,在元素内部定义的变量不会影响其他元素。示例中写在元素外部的变量:$color: orange !default;是一个全局变量;而写在元素内部的变量:$color:orange !default;就是一个局部变量。

- 全局变量的影子
当在局部范围(选择器内、函数内、混合宏内...)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子。基本上,局部变量只会在局部范围内覆盖全局变量。

示例中的 em 选择器内的变量 $color 就是一个全局变量的影子。

//SCSS
$color: orange !default;  //定义全局变量
.block {
  color: $color;          //调用全局变量
}
em {
  $color: red;            //定义局部变量(全局变量 $color 的影子)
  a {
    color: $color;        //调用局部变量
  }
}

- 什么时候声明变量?
满足所有下述标准时方可创建新变量:

  • 该值至少重复出现了两次;
  • 该值至少可能会被更新一次;
  • 该值所有的表现都与变量有关(非巧合)。

基本上,没有理由声明一个永远不需要更新或者只在单一地方使用变量。

5、Sass嵌套

5.1 选择器嵌套
例如有这样的html结构:

<header>
    <nav>
        <a href=“##”>Home</a>
        <a href=“##”>About</a>
        <a href=“##”>Blog</a>
    </nav>
<header>

使用sass 方法选中header中的a标签:

nav{
  a{
    color: red;
    header &{
      coloe: green;
    }
  }
}

连体符 & 使用方法,编译结果:↓

nav a {
  color: red;
}
header nav a {
  color: green;
}

5.2 属性嵌套
CSS 有一些属性前缀相同,只是后缀不一样,比如:border-top/border-right,与这个类似的还有 margin、padding、font 等属性。假设你的样式中用到了:

.box{
  border-top: 1px solid red;
  border-bottom: 1px solid green;
}

在Sass中我们可以这样写:

.box{
  border: {      //这里border后面的" : "是关键;
    top: 1px solid red;
    bottom: 1px solid green;
  }
}

5.3 伪类嵌套
其实伪类嵌套和属性嵌套非常类似,只不过他需要借助&符号一起配合使用。我们就拿经典的“clearfix”为例吧:↓

.clearfix{
  &:before,&:after{
    content:"";
    display: table;
  }
  &:after{
    clear: both;
    overflow: hidden;
  }
}

编译后的代码:↓

.clearfix:before, .clearfix:after {
  content: "";
  display: table;
}
.clearfix:after {
  clear: both;
  overflow: hidden;
}

避免选择器嵌套:

选择器嵌套最大的问题是将使最终的代码难以阅读。开发者需要花费巨大精力计算不同缩进级别下的选择器具体的表现效果。
选择器越具体则声明语句越冗长,而且对最近选择器的引用(&)也越频繁。在某些时候,出现混淆选择器路径和探索下一级选择器的错误率很高,这非常不值得。
为了防止此类情况,我们应该尽可能避免选择器嵌套。然而,显然只有少数情况适应这一措施。

6、混合宏

当页面样式越来越复杂,需要重复使用大段的样式时,就需要使用混合宏。

6.1 声明混合宏

  • 不带参数的混合宏

在Sass中使用@mixin来声明一个混合宏,如:↓

@mixin border-radius{
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

其中 @mixin 是用来声明混合宏的关键词,有点类似 CSS 中的 @media、@font-face 一样。border-radius 是混合宏的名称。大括号里面是复用的样式代码。

  • 带参数的混合宏

除了声明一个不带参数的混合宏之外,还可以在定义混合宏时带有参数,如:↓

@mixin border-radius($radius:5px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}
  • 复杂的混合宏

可以在大括号里面写上带有逻辑关系,帮助更好的做你想做的事情,如:↓

@mixin box-shaow($shadow...){
  @if length($shadow) >= 1{
    @include prefixer(box-shadow,$shadow);
  }@else{
    $shadow: 0 0 4px rgba(0,0,0,.3);
    @include prefixer(box-shdow,$shadow);
  }
}

这个 box-shadow 的混合宏,带有多个参数,这个时候可以使用“ … ”来替代。简单的解释一下,当 $shadow 的参数数量值大于或等于“ 1 ”时,表示有多个阴影值,反之调用默认的参数值“ 0 0 4px rgba(0,0,0,.3) ”。

6.2 调用混合宏
关键词@include来调用声明好的混合宏。例如在你的样式中定义了一个圆角的混合宏“border-radius”:↓

@mixin border-radius{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

在一个按钮中要调用定义好的混合宏“border-radius”,可以这样使用:↓

button{
  @include border-radius;
}

编译后的CSS如下:↓

button {
    -webkit-border-radius: 10px;
    border-radius: 10px
}
调用混合宏@mixin.png

6.3 混合宏的参数

  • 传一个不带值的参数

在混合宏中,可以传一个不带任何值的参数,比如:↓

@mixin border-radius($radius){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}

上述混合宏中的“border-radius”中定义了一个不带任何值的参数“$radius”。在调用的时候可以给这个混合宏传一个参数值:↓

.box{
  @include border-radius(3px);
}

表示在给混合宏传递了一个“border-radius”的值为“3px”。编译后的CSS:↓

.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
  • 传一个带值的参数

在 Sass 的混合宏中,还可以给混合宏的参数传一个默认值,例如:↓

@mixin border-radius($radius: 3px){
  -webkit-border-radius: $radius;
  border-radius: $radius;
}

在混合宏“border-radius”传了一个参数“$radius”,而且给这个参数赋予了一个默认值“3px”。

在调用类似这样的混合宏时,会多有一个机会,假设你的页面中的圆角很多地方都是“3px”的圆角,那么这个时候只需要调用默认的混合宏“border-radius”:↓

.btn{
  @include border-radius;
}

编译出来的CSS:

.btn{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

但有的时候,页面中有些元素的圆角值不一样,那么可以随机给混合宏传值,如:↓

.box{
  @include border-radius(50%);
}

新的值"50%"会覆盖原有的值“3px”,编译后的CSS:

.box{
  -webkit-border-radius:50%;
  border-radius:50%;
}
  • 多个参数

sass混合宏除了能传一个参数之外,还可以穿多个参数,如:↓

@mixin center($width,$height){
  width: $width;
  height: $height;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -($height)/2;
  padding-left: -($width)/2;
}

在混合宏“center”就传了多个参数。在实际调用和其他混合宏是一样的:↓

.box-center{
  @include center(500px,300px)
}

编译后的CSS:

.box-center {
  width: 500px;
  height: 300px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -150px;
  padding-left: -250px;
}

有一个特别的参数“...”。当混合宏的参数过多之时,可以使用参数来替代,如:↓

@mixin box-shadow($shadows...){
  @if length($shadows) >= 1 {
    -webkit-box-shadow: $shadows;
    box-shadow: $shadows;
  } @else {
    $shadows: 0 0 2px rgba(#000,.25);
    -webkit-box-shadow: $shadow;
    box-shadow: $shadow;
  }
}

在调用时传参:↓

.box {
  @include box-shadow(0 0 1px rgba(#000,.5), 0 0 2px rgba(#000,.2));
}

编译出来的CSS↓

.box {
  -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.5), 0 0 2px rgba(0, 0, 0, 0.2);
}
  • 混合宏的不足

最大的不足之处是会生成冗余的代码块。比如在不同的地方调用一个相同的混合宏时。如:↓

@mixin border-radius{
  -webkit-border-radius: 3px;
  border-radius: 3px;
}
.box {
  @include border-radius;
  margin-bottom: 5px;
}
.btn {
  @include border-radius;
}

示例在“.box”和“.btn”中都调用了定义好的“border-radius”混合宏。先来看编译出来的 CSS:↓

.box {
  -webkit-border-radius: 3px;
  border-radius: 3px;
  margin-bottom: 5px;
}
.btn {
  -webkit-border-radius: 3px;
  border-radius: 3px;
}

明显可以看出,Sass 在调用相同的混合宏时,并不能智能的将相同的样式代码块合并在一起。这也是 Sass 的混合宏最不足之处。

6.4 sass 扩展/继承

  • 继承@extend
.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}
.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}
.btn-second {
  background-color: orange;
  color: #fff;
  @extend .btn;
}

编译后CSS:↓

.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}
.btn-primary {
  background-color: #f36;
  color: #fff;
}
.btn-second {
  background-clor: orange;
  color: #fff;
}

从示例代码可以看出,在 Sass 中的继承,可以继承类样式块中所有样式代码,而且编译出来的 CSS 会将选择器合并在一起,形成组合选择器。

6.5 [Sass]占位符 %placeholder

Sass中的占位符%placeholder功能很强。它可以取代以前CSS中的基类造成的代码冗余:%placeholder声明的代码,如果不被@extend调用的话,不会产生任何代码。示例:

%mt5{
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}

这段代码如果没有被@extend调用,不会产生任何代码块。只有通过@extend调用才会产生代码:↓

.btn {
  @extend %mt5;
  @extend %pt5;
}
.block {
  @extend %mt5;
  span {
    @extend %pt5;
  }
}

编译后的CSS:↓

.btn, .block {
  margin-top: 5px;
}
.btn, .block span {
  padding-top: 5px;
}

由上可知,用过@extend调用的占位符,编译出来的代码会将相同的代码合并在一起。这一点非常棒!

6.6 [Sass]混合宏 VS 继承 VS 占位符

三者如何选择,才能发挥各自最佳优势?

  • 混合宏的使用


    混合宏.png

缺点:通过编译出来的CSS可以看出,混合宏不会自动合并相同的样式代码margin-top:5px;,这样极易造成代码冗余。

优点:可以传参

总结:如果代码块中涉及到变量,建议使用混合宏来创建相同的代码块。

  • 继承


    Sass 继承.png

    继承编译出来的代码会将使用继承的代码块合并到一起,通过组合选择器的方式展现:

.mt, .block, .block span, .header, .header span {
  margin-top: 5px;
}

缺点:不能传参。

优点:代码干净不冗余。

总结:如果代码块不需要任何传参,而且有一个基类已经存在文件中,建议使用Sass的继承。

  • 占位符
    占位符.png

    对比继承和占位符,编译后的CSS基本一致,只是继承的代码块中生成了.mt的选择器,而占位符没有。那么就是说二者的主要区别是:
    占位符是独立定义的,不调用不会产任何代码;
    继承是首先由一个基类存在.mt,不管调用与否,基类样式都会被编译出来。
混合宏、继承、占位符.png

7、Sass插值 #{}

想写一个更干净的、高效的和面向对象的CSS。Sass中的插值(interpolation)就是重要的一部分。示例:

$space:(margin,padding);
@mixin set-value($side,$value){
  @each $prop in $space{
    #{$prop}-#{side}: $value;
  }
}
.container{
  @include set-value(top,20px);
}

它可以让变量和属性工作的很完美,编译后的CSS:

.container {
  margin-top: 20px;
  padding-top: 20px;
}

当你想设置属性值的时候你可以使用字符串插入进来。另一个有用的用法是构建一个选择器。可以这样使用:

@mixin generate-sizes($class,$small,$medium,$big){
  .#{$class}-small{
    font-size: $small;
  }
  .#{$class}-medium{
    font-size: $medium;
  }
  .#{$class}-big{
    font-size: $big;
  }
}
@include generate-sizes("header-text", 12px, 20px, 40px)

编译之后:

.header-text-small {
  font-size: 12px;
}
.header-text-medium {
  font-size: 20px;
}
.header-text-big {
  font-size: 40px;
}

8. 注释

sass有两种注释方式:

  • 类似CSS注释:/* 这里是注释 */
  • 类似JS注释://这里是注释

区别是,/* */会在编译的CSS中显示,//在编译的CSS里不显示。示例:

//定义占位符
%mt5{
  margin-top: 50px;
}
/*调用一个函数*/
.box{
  @extend %mt5
}

编译后:

.box {
  margin-top: 5px;
}

/*调用一个占位符*/

9. 数据类型

sass中包含以下几种数据类型:

  • 数字:如1、2、3、10px;
  • 字符串:有引号字符串或无引号字符串,如,“foo”、‘bar’、baz;
  • 颜色:blue、#ff5050、rgba(255,180,20,0.3);
  • 布尔值:true、false;
  • 空值:null;
  • 值列表:用空格或者逗号分开,如:1.5em 1em 0 2em 、Helvetice,Arial,sans-serif

10. 字符串

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

  • 有引号的字符串:“Lucida Grande”、‘http://sass-lang.com’;
  • 无引号的字符串:sans-serifbold。

在CSS编译时不会改变其类型,只有使用插值#{}时,有引号字符串将被编译为无引号字符串,这样方便了在混合宏中引用选择器名:

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

编译为:

body.firefox .header:before{
  content: "Hi,firefox user!";
}

11. 值列表

所谓值列表,是指sass如何处理CSS中 margin: 10px 15px 0 0 或者 font-face: Helvetica, Arial,sans-serif 这种通过空格或者逗号分割的一系列值。
独立的值被视为只包含一个值的值列表。

Sass列表函数(Sass list functions)赋予了值列表更多功能(Sass进级会有讲解):

  • nth函数(nth function) 可以直接访问值列表中的某一项;
  • join函数(join function) 可以将多个值列表连结在一起;
  • append函数(append function) 可以在值列表中添加值;
  • @each规则(@each rule) 则能够给值列表中的每个项目添加样式。

值列表中可以再包含值列表,比如 1px 2px, 5px 6px 是包含 1px 2px 与 5px 6px 两个值列表的值列表。如果内外两层值列表使用相同的分隔方式,要用圆括号包裹内层,所以也可以写成 (1px 2px) (5px 6px)。当值列表被编译为 CSS 时,Sass 不会添加任何圆括号,因为 CSS 不允许这样做。(1px 2px) (5px 6px)与 1px 2px 5px 6px 在编译后的 CSS 文件中是一样的,但是它们在 Sass 文件中却有不同的意义,前者是包含两个值列表的值列表,而后者是包含四个值的值列表。

可以用 () 表示空的列表,这样不可以直接编译成 CSS,比如编译 font-family: ()时,Sass 将会报错。如果值列表中包含空的值列表或空值,编译时将清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。

三、Sass的基本特性-运算

程序中的运算是常见的一件事情,但在 CSS 中能做运算的,到目前为止仅有 calc() 函数可行。但在 Sass 中,运算只是其基本特性之一。

3.1 加法

在变量或属性中都可以做加法运算:

.container{
  width: 20px + 8in;    //1in = 2.54cm = 25.4 mm = 72pt = 6pc = 96px
  height: 8in + 20px;   //按第一个值得单位计算
}

点这里查看关于单位in单位in的定义
编译后:

.container{
  width: 788px;
  height: 8.20833in;
}

单对于不同类型的单位是,在sass中计算会报错。如下所示:

.container{
  width: 20px + 1em;
}

报错:”Incompatible units: 'em' and ‘px'. “

in mm cm pt pc px等单位都能运算,ex em rem等相对于当前字体的单位不能运算。


sass加法实例.png

3.2 减法

示例:

$full-width: 960px;
$sidebar-width: 200px;
.content{
  width:{
    $full-width - $siderbar-width;
  }
}

编译的CSS代码:

.content{
  width: 760px;
}

在遇到不同单位时,编译也会报错。

3.3 乘法

Sass中乘法运算和加减法运算略有不同,当一个单位同时声明两个值时会有问题。比如:

一个单位同时声明两个值.png

在乘法运算时,两个值的单位相同时,只需要为一个数值提供单位即可:


后面的值不带单位.png

不同类型的单位进行乘法运算时也会报错:


不同类型单位不能乘法.png

实例:@for循环让icon图标的background-position的Y轴值按20px递减:
递减.png

3.4 除法

Sass的乘法运算规则也适用于除法运算,但还有一个特殊之处。CSS中”/“作为一个符号出现,因此在sass直接使用”/“作为除号,编译时即得不到我们需要的结果,也不会报错,比如:

.container{
  width: 100px / 2;
}

编译后的CSS:

.container{
  width: 100px / 2;
}

修正这个问题只需要给运算外面添加一个小括号( )即可:

.container{
  width: (100px / 2);
}

编译后的CSS:

.container{
  width: 50px;
}

另外还有其他的情况” / “符号被当做除法运算:

  • 如果数值或它的任意部分是存储在一个变量中,或是函数返回值。
  • 如果数值被圆括号包围
  • 如果数值是另外一个数学表达式的一部分。
p {
  font: 10px/8px;             // 纯 CSS,不是除法运算
  $width: 1000px;
  width: $width/2;            // 使用了变量,是除法运算
  width: round(1.5)/2;        // 使用了函数,是除法运算
  height: (500px/2);          // 使用了圆括号,是除法运算
  margin-left: 5px + 8px/2px; // 使用了加(+)号,是除法运算
}

3.5 变量计算

示例:

$content-width: 720px;
$sidebar-width: 220px;
$gutter:20px;
.container{
  width: $content-width + $sidebar-width + $gutter;
  margin: 0 auto;
}

编译结果:

.container {
  width: 960px;
  margin: 0 auto;
}

3.6 数字运算

计算 Grid 单列列宽的运算示例:

.container{
  width: ((220px + 720px) - 11 * 20) / 12;
}

编译结果:

.container{
  width: 60px;
}

3.7 颜色运算

所有算数运算都支持颜色值,并且是分段运算的,也就是说,红、绿和蓝各颜色分段进行运算。如:

p{
  color: #010203 + #040506;
}

计算方式:#( 01+04)(02+05)(03+06),编译后的CSS:

p{
   color: #050709;
}

也可以是数字和颜色值一起运算,同样也是分段运算,例如:

p{
  color: #010203 * 2
}

计算方式为:#(012)(022)(03*2),编译后的CSS:

p{
  color: #020406
}

3.8字符运算

  • Sass中可以通过”+“来对字符串进行连接,和JS类似:
$content: "Hello" + " " + "Sass!";
.box: before{
  content: " #{$content}";
}

编译出来的CSS:

.box{
  content:"Hello Sass"
}
  • 连接字符
div{
  cursor: e + -resize;
}

编译后CSS:

div{
  cursor: e-resize;
}

注意 运算的第一个值带引号,结果也带引号;第一个值没有引号,结果也不带引号:

字符运算.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342