走进Sass殿堂

最近在学习sass,从sass新手的角度做一个简单的总结,总结的不对的地方期望各位大大们能多多指点,本文是针对sass3.4做的一个总结~

一、变量篇

1.1 变量的使用

sass的变量以$开头,类似php里变量的写法

 $blue : #1875e7; 
 div {
     color : $blue;
 }

上面那个例子是把变量用在属性值上,如果要用在选择器或属性名上呢?如果我们简单的这样写:

$name: test;
$attr: border;
p.$name {
  $attr-color: red;
}

编译出错了,正确使用方式应该是用#{}包裹,上面的这个例子正确用法是:

$name: test;
$attr: border;
p.#{$name} {
  #{$attr}-color: red;
}

了解了变量的简单使用,要用好变量,息息相关的就是作用域了。

1.2 变量的作用域

sass支持局部变量和全局变量。定义在选择器内的我们称为局部变量,反之为全局变量。简单的在sass3.4中看一个例子

$width: 10px;

.wrap{
    $width: 20px;
    $width: 40px;
    .main{
        width: $width;
    }
    .sidebar{
        $width: 30px;
        width: $width;
    }
}

.content{
    width: $width;
}

编译出来的结果是:

.wrap .main {
     width: 40px; 
}
.wrap .sidebar {
     width: 30px; 
}
.content {
     width: 10px; 
}

后定义的会覆盖前面定义的,选择器内的同名变量不加特殊声明不会影响选择器外的。

如果期望后面定义的不要覆盖前面的呢?!default可以做到这一点。

$height: 10px;
$height: 20px !default;

div {
    height: $height;  //结果为10
}

这时候假设我们又遇到一个情况,希望选择器里覆盖外面的全局变量,应该怎么写? !global可以帮助我们做到:

$height: 10px;

div {
    $height: 20px !global;
    height: $height;
}

h1 {
    height: $height;
}

编译结果是:

div {
  height: 20px; }

h1 {
  height: 20px; }

二、运算符篇

有了变量,如果没有运算符就像是一个个散落的珍珠,缺少一根线把它们串成一个项链。所以sass也提供了简单的四则运算。看一个四则运算的例子:

$base: 2px;

.a {
    height: $base * 2;
    // height: $base * 2px; error
    // height: 2px * 2px; error

    width: $base / 2;
    width: $base / 2px;
    width: 2px / 2;
    width: 2 / 2px;
    width: 2 / 2;

    margin-left: $base + 2px;
    margin-left: $base + 2;

    margin-right: $base - 2px;
    margin-right: $base - 2;
    margin-right: 2 - 2;
}

编译结果:

.a {
  height: 4px;
  width: 1px;
  width: 1;
  width: 2px / 2;
  width: 2 / 2px;
  width: 2 / 2;
  margin-left: 4px;
  margin-left: 4px;
  margin-right: 0px;
  margin-right: 0px;
  margin-right: 0; }

看上面的例子,加法和减法相对简单,除法和乘法有些特殊:

  1. 除法和乘法的单位会参加运算,所以当 1px 乘 1px = 1px px,然后就会挂了。
  2. 除法/符号因为在比如font的缩写中会用到,所以例子中/当是直接量相除的时候会把原封不动都输出来,不会运算。

简单的总结如下:

  • 加法:都没有单位输出纯数字;一方有单位,则结果输出该单位;两方相同单位,结果输出该单位;双方单位不同,报错。
  • 减法:类似加法。
  • 除法:两方相同单位,结果无单位;都没有单位,结果无单位;一方有单位另一方无单位,结果输出该单位。
  • 乘法:两方相同单位,报错;一方有单位,结果输出该单位;两方都无单位,输出无单位。

了解完变量和运算符,我们就可以看看sass的语句啦~

三、语句篇

3.1 条件语句

我们所熟悉的if语句:

p {
    @if 1 + 1 == 2 { border: 1px solid black; }
    @if 5 < 3 { border: 2px dotted black; }
}

3.2 循环语句

sass支持for循环,while循环,each循环:

[@for](/user/for) $i from 1 to 10 {
   .width-#{$i} {
        border: #{$i}px solid blue;
    }
}

$i: 6;
[@while](/user/while) $i > 0 {
   .item-#{$i} { 
        width: 2em * $i; 
    }
    $i: $i - 2;
}

[@each](/user/each) $member in a, b, c, d {
    .#{$member} {
       background-image: url("/image/#{$member}.jpg");
    }
}

四、模块化篇

css开发中,我的习惯经常是,比如给外层容器去个class叫‘abc’,它的子集容器就会取名诸如'abc-title'、'abc-content' 等。这样一定程度上看起来似乎这些class都有所关联了,但是代码一多还是看起来非常混乱。

假设现在别人要复用我的代码了,就算看懂估计也得琢磨半天。有什么更好的模块化的方法呢。

4.1 嵌套和&

sass可以使用{}进行嵌套书写,使用&进行引用父元素。比如:

div {
    a {
        color: #f00;
        &:hover {
            color: #0f0;
        };
    }
}

编译结果是:

div a {
  color: #f00; 
}
div a:hover {
    color: #0f0; 
}

看完了这两个属性的用法我们之前那个例子就可以写成:

.abc {
    &-title {
         ...
    }
    $-content {
         ...
    }
}

这样看起来立刻觉得舒服多了,别人要复用也一目了然啦。说起模块化,特定之一就是代码复用。sass提供了哪些方便代码复用、重用的语法呢?

4.2 @extend

假设我们有个class2要继承class1,我们可以这样写:

.class1 {
    border: 1px solid #ddd;
}

.class2 {
    @extend .class1;
    font-size: 120%;
}

编译出来的结果是:

.class1, .class2 {
  border: 1px solid #ddd; }

.class2 {
  font-size: 120%; }

有了@extend,感觉我们的代码量瞬间能少掉一大截,避免了不少重复的代码。但是突然我们又想到这样一个场景,假设class1本来并不需要存在,比如我们定义了一段超长则变省略号的代码,如果要@extend我们得额外定义一个多余的类class1。于是sass又提供了@mixin

4.3 @mixin

上面的代码可以变成如下:

// 这边写的是mixin class1,自动生成了别的东西。。。
[@mixin](/user/mixin) class1 {
    border: 1px solid #ddd;
}

.class2 {
    @include class1;
    font-size: 120%;
}

.class3 {
    @include class1;
    font-size: 100%;
}

编译出来的结果是:

.class2 {
  border: 1px solid #ddd;
  font-size: 120%; }

.class3 {
  border: 1px solid #ddd;
  font-size: 100%; }

这样我们多余定义的类class1就去掉啦,但是现在新的问题来了,我们看看编译出的代码,class2和class3中有一段重复的代码,mixin只是简单的把代码嵌套进来了,假设我们有一堆class,编译出来将会有一堆重复的代码,代码将会非常冗余。有没有办法解决呢?

4.4 %placeholder

上面的代码我们通过%改造成这样:

%class1 {
    border: 1px solid #ddd;
}

.class2 {
    @extend %class1;
    font-size: 120%;
}

.class3 {
    @extend %class1;
    font-size: 100%;
}

编译出来的结果是:

.class2, .class3 {
  border: 1px solid #ddd; }

.class2 {
  font-size: 120%; }

.class3 {
  font-size: 100%; }

这正是我们所需要的!所以相比extend,能用placeholder的情况我们理论上应该优先用placeholder。

五、函数篇

sass支持用户自定义自己的函数:

// 这里写的是function double。。。
[@function](/user/function) double($n) {
    @return $n * 2;
}

.test {
    height: double(3px);
}

简单的总结就到此为止啦,不懂sass到了解sass是一个阶段,了解sass到会用sass又是另一个境界。简单的语法总结,仅仅是到了一个了解阶段,如何用好,值得探究的地方还有太多~

参考文档:

http://www.ruanyifeng.com/blog/2012/06/sass.html

http://www.w3cplus.com/sassguide/

http://www.w3cplus.com/preprocessor/sass-mixin-placeholder.html

http://www.w3cplus.com/preprocessor/sass-advanced.html

http://www.w3cplus.com/preprocessor/understanding-variable-scope-in-sass.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏土豆专栏

Java面试之数据类型(一)

封装类是引用类型,基本类型在传递参数的时候都是按值传递,而封装类型是按引用传递的(其实引用也是按值传递的,但是传递的是对象的地址)

1132
来自专栏zaking's

用js来实现那些数据结构02(数组篇02-数组方法)

    上一篇文章简单的介绍了一下js的类型,以及数组的增删方法。这一篇文章,我们一起来看看数组还有哪些用法,以及在实际工作中我们可以用这些方法来做些什么。由于...

35311
来自专栏angularejs学习篇

js中对arry数组的各种操作小结

  最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以...

481
来自专栏AI派

Numpy 修炼之道 (10)—— 结构化数组

之前我们操作Numpy的数组时,都是通过索引来操作的。针对二维数组,使用索引可以完成对行、列的操作。但是这是非常不直观的。可以把二维数组想象成一个excel表格...

4255
来自专栏云瓣

ES6的一些常用特性

由于公司的前端业务全部基于ES6开发,于是给自己开个小灶补补ES6的一些常用特性。原来打算花两天学习ES6的,结果花了3天才勉强过了一遍阮老师的ES6标准入门,...

3328
来自专栏练小习的专栏

js运算符优先级笔记

运算符的优先级决定了表达式中运算执行的先后顺序,优先级高的运算符最先被执行。 下面是一个简单的例子: 3 + 4 * 5 // 计算结果为23 乘法运算符...

1848
来自专栏软件开发 -- 分享 互助 成长

谈谈 char *num="123";和char num[4]="123";的区别

最近写程序的时候发现这样一个问题 #include<iostream> #include <string.h> using namespace std; vo...

1728
来自专栏python3

python 列表(List)

Python内置的一种数据类型是列表:list。list是一种有序的集合,可以随时添加和删除其中的元素。

811
来自专栏hrscy

(译)Swift2.2-可选链

可选链(Optional Chaining)是为了在一个可能当前值为nil的optional类型里,查询和调用属性,方法和下标脚本的一个过程。如果这个可选类型包...

813
来自专栏C/C++基础

字符数组的初始化与赋值

C语言中表示字符串有两种方式,数组和指针,字符数组是我们经常使用的方式。变量的定义包括指明变量所属类型、变量名称、分配空间以及初始化。可以看出,变量的初始化是变...

542

扫码关注云+社区