上一篇详述了Sass如何嵌套、导入和注释这3个基本方式来保持条理性和可读性,这一篇更进一步地阐述sass保持样式复用和简洁的方式——混合器和选择器继承——这两种方式都能复用样式,使用它们也不难,但一定要注意什么时候该用什么。

零. 混合器——样式层上复用

当你需要一直复用大段样式的时候,可以考虑下混合器。

1. 基本用法

混合器使用@mixin标识符定义,然后通过@include引入,简单的说就是用@mixin定义一个混合器,它具有一个名字和一堆包含在花括号中的规则,用@include引入这个混合器(通过混合器的名字),混合器中的样式规则就会被提取到调用@include的地方。

此外,混合器中也可以包含CSS规则,可以包含选择器和选择器中的规则,甚至可以用父选择器标识符&

@mixin rounded-corners{
    -moz-border-radius:5px;
    -webkit-border-redius:5px;
    border-radius:5px;
}

.notice{
    background-color:green;
    border:2px solid #0a0;
    @include rounded-corners;
}

//导出的css如下
.notice{
    background-color:green;
    border:2px solid #0a0;
    -moz-border-radius:5px;
    -webkit-border-redius:5px;
    border-radius:5px;
}

2. 可以给混合器传参

混合器复用样式的时候,可以通过传参改变混合器中的具体属性值,和function很像。

混合器定义时,参数名称必须以变量名形式指定,此外,可选的是,参数可以有默认值,只需要在参数名后面以冒号:分隔后写上默认属性值,如果你了解各类编程语言函数的默认参数值,这应该不会陌生。

引入含有参数的选择器时,有两种传入参数的形式,一种是仅仅传入参数值,这要求传入参数值的顺序和混合器定义的参数顺序一致,另一种则是通过$name:value的形式指定传入参数的名字和值,这就不要求顺序。

以下代码定义了一个有3个参数的选择器来设置一个链接各个状态的颜色样式,其中常规样式的颜色$normal有一个默认值#233,另外两个参数没有默认值:

@mixin link-col($hover, $visited, $normal:#233){
    color:$normal;
    &:hover { color:$hover; }
    &:visited { color:$visited; }
}

当引入这个混合器的时候,可以有以下两种方式引入:

//可以这么引入,因为最后一个参数默认,可以不传入
a{
    @include link-col(red, gray);
}
//也可以这样,就不用管顺序
a{
    @include link-col($visited:gray, $hover:red);
}

3. 混合器的使用场景——注意和类的区别

如果发现一直在不停复用一段样式,应该考虑把这段样式构造成一个混合器,尤其是它本身可能是一组有意义的样式组合,并且考虑进参数的设置,让混合器更加智能。

判断一组选择器是否应该组合在一起组成一个混合器,一条经验法则:能否为这个混合器想出一个能概括它的好名字。如果能想出一个短名字来描述这几条样式组合的作用,那么往往能构造出一个合适的混合器。

混合器和CSS类很像,css类也可以复用样式,一段样式给一个类,然后那里需要这一段样式去修饰,就在哪里添加这个类。

区别在于,类是在HTML中运用的,混合器是在样式表中使用的。这意味着,“类”具有语义化的含义,而混合器仅仅是有关样式的,仅仅是描述展示出来是什么样子的。

能区分这两者微妙的区别,并且有意地去选择更合适的方式去复用样式,这能让你的代码保持可读性和可维护性。诚然,现在很多流行框架,依旧在用类去复用样式,但是语义和样式的解耦绝对是趋势。

一. 选择器继承——语义化关系上复用样式

刚描述完混合器和类的差别,在于“语义”和“展示样式”,又突然到了建立在语义化关系上复用样式的选择器继承,似乎有点绕,为什么不用类而要用选择器继承呢?

实际上,选择器继承最常用的场景就是和类一起工作的。

1. 基本用法

选择器继承,用@extend去继承一个选择器定义的所有样式。以下代码,.seriousError将会继承.error定义的所有样式。

.error{
    border: 1px red;
    background-color: #fdd;
}
.seriousError{
    @extend .error;
    border-width: 3px;
}

//输出的CSS代码是这样的
.error, .seriousError{
    border: 1px red;
    background-color: #fdd;
}
.seriousError{
    border-width: 3px;
}

是的,平时我们完全可以写输出的纯CSS代码,多写一个选择器名字和多写一行@extend命令,我们觉得差不多。

但是,在上面的例子中,.seriousError不仅会继承.error自身的所有样式(就像上面的那样),任何和.error有关的组合选择器样式也会被.seriousError以组合选择器的形式继承。

比如,在上面的样式代码是这样的:

.error{
    border: 1px red;
    background-color: #fdd;
}
.seriousError{
    @extend .error;
    border-width: 3px;
}
.error a{
    color:red;
    font-weight:bold;
}
h1.error{
    font-size:1.3em;
}

//输出的CSS是这样的,注意看下面的选择器
.error, .seriousError{
    border: 1px red;
    background-color: #fdd;
}
.seriousError{
    border-width: 3px;
}
.error a, .seriousError a{
    color:red;
    font-weight:bold;
}
h1.error, h1.seriousError{
    font-size:1.3em;
}

这个时候,如果我们不借助Sass的选择器继承,而用纯CSS来写,是不是就会有一些繁琐了。

我们再来想一下这几段代码的含义:我们描述了一个.error类来整体修饰错误提示都应该有的样式,然后.seriousError.error类的细化,描述了一个严重的错误应该有的进一步的样式。所以.seriousError应该有.error相关的所有样式,而这就是选择器继承帮助我们做的事。

2. 继承背后的基本实现思路

@extend背后最基本的想法是,如果.seriousError继承了.error,那么样式表中的任何一处.error选择器都会用.error, .seriousError这一选择器组进行替换和打开。

3. 继承的使用场景

继承是建立在语义化的关系上的,当一个元素拥有的类表明它是属于另一个类时(是另一个类的细化时),在这种情况下需要复用样式时使用,它的本质作用还是样式复用。

它和混合器相比,继承生成的代码量会相对较少,因为继承仅仅重复选择器,而混合器是重复一段样式。

另外,可以看到,一般它和类一起协同工作,当你在构建一些有关系的类时,在写这些具有层级关系的类的样式的时候,选择器继承可以帮你严谨地完成某些样式的复用,无论是这个选择器本身,还是隐藏在其他复杂选择器中的目标选择器。

4. 继承的高级用法

既然这被称为选择器继承,不是“类”继承,那么必然继承是可以针对类之外的选择器使用的,只是继承类是最常用的使用场景。

还有一种场景是,继承一个HTML元素的样式,如定一个.disabled类,样式修饰让它看上去像一个灰掉的链接,通过继承a这一元素实现:

.disabled{
    color: gray;
    @extend a;
}

还有一些关于复杂选择器的继承规则:

  1. 如果继承了一个复杂的选择器,那么只会继承这个复杂选择器命中的样式, 比如.seriousError @extend .important.error,那么被继承的.important.error被看做一个整体,单独的.important或者.error是不会被继承的;
  2. 如果一个选择器序列继承了另一个选择器,那么只会完全命中序列选择器的才会继承,比如(#main .seriousError) @extend .error最好不要这么做),那么前者的#main .seriousError也被看做一个整体,只有完全命中这个选择器的才会继承;
  3. 以逗号分隔的选择器序列是不能被继承的,因为这和继承其中任何一个选择器效果一样。

5. 使用继承时注意后代选择器

可以放心地继承有后代选择器修饰的选择器,但不用用后代选择器去继承别的选择器。即放心地用.serious { @extend (.main .error) },但是不要用.something .serious { @exten .error }

为什么,因为不这么做可能会导致继承迅速变复杂,sass可能会遗漏一些情况,考虑:

.foo .bar { @extend .baz; }
.bip .baz { a:b; }

当下面那条规则应用到.foo .bar时,有3种情况:

<div class="foo">
    <div class="bip">
        <div class="bar">...</div>
    </div>
</div>

<div class="bip">
    <div class="foo">
        <div class="bar">...</div>
    </div>
</div>

<div class="bip foo">
    <div class="bar">...</div>
</div>

所以sass必须要生成3种组合选择器才能覆盖这3种情况,但遗憾的是,sass并不总是会生成所有情况,另外,这样做,选择器的个数会迅速增加,所以最好的方式是不要这么用。

三. 小结

Sass保持样式复用和简洁的两个方式,一是混合器,混合器主要用于样式展示层的复用,可以给混合器传参从而在复用代码的同时保持灵活性,二是选择器继承,一般和类一起使用,主要用于建立在语义化关系上的样式复用,注意继承可能引发的问题。

sass笔记-3|Sass基础语法之样式复用和保持简洁的更多相关文章

  1. Sass的使用和基础语法

    sass安装 官网下载ruby的windows安装包,安装时勾选上添加到环境变量add ruby executables to your path.安装完成后打开命令行,ruby -v输出内容则安装完 ...

  2. 风变编程笔记(一)-Python基础语法

    第0关  print()函数与变量 1. print()函数print()函数:告诉计算机,把括号的内容显示在屏幕上 # 不带引号 print(1+1) # 让计算机读懂括号里的内容,打印最终的结果 ...

  3. Scala学习教程笔记一之基础语法,条件控制,循环控制,函数,数组,集合

    前言:Scala的安装教程:http://www.cnblogs.com/biehongli/p/8065679.html 1:Scala之基础语法学习笔记: :声明val变量:可以使用val来声明变 ...

  4. Java编程基础阶段笔记 day04 Java基础语法(下)

    day04 Java基础语法 (下) 笔记Notes要点 switch-case语句注意 switch-case题目(switchTest5) 循环执行顺序 if-else 实现3个整数排序 Stri ...

  5. <学习笔记 之 JQuery 基础语法>

    jQuery 库 - 特性 jQuery 是一个 JavaScript 函数库. jQuery 库包含以下特性: HTML 元素选取 HTML 元素操作 CSS 操作 HTML 事件函数 JavaSc ...

  6. sass笔记-2|Sass基础语法之让样式表更具条理性和可读性

    这一篇主要详述保持sass条理性和可读性的3个最基本方法--嵌套.导入和注释. 零. 变量 变量本身的作用是为了保持属性值的可维护性,把所有需要维护的属性值放在同一个地方,快速更改,处处生效,可谓售后 ...

  7. sass的安装和基础语法

    安装 下载ruby安装包[官网非常慢ruby官网] ruby-2.3.3-x64-mingw32.7z 下载sass sass-3.7.4.gem 方法一: ruby压缩包,解压即可,在bin目录下, ...

  8. sass笔记-1|Sass是如何帮你又快又好地搞定CSS的

    Sass学习笔记持续整理中,开篇不讲怎么安装,sass是什么,这些搜索引擎会告诉你,我们从sass的作用开始讲起,知道sass用来干什么,有什么作用,我们才能相信用sass的好处,并且时时刻刻想着sa ...

  9. Java 学习笔记(1)——java基础语法

    最近抽时间在学习Java,目前有了一点心得,在此记录下来. 由于我自己之前学过C/C++,而Java的语法与C/C++基本类似,所以这一系列文章我并不想从基础一点点的写,我想根据我已有的C/C++经验 ...

随机推荐

  1. 你好,C++(32) 类是对现实世界的抽象和描述 6.2.1 类的声明和定义

    6.2  类:当C++爱上面向对象 类这个概念是面向对象思想在C++中的具体体现:它既是封装的结果,同时也是继承和多态的载体.因此,要想学习C++中的面向对象程序设计,也就必须从“类”开始. 6.2. ...

  2. 【USACO 3.2.4】饲料调配

    [描述] 农夫约翰从来只用调配得最好的饲料来喂他的奶牛.饲料用三种原料调配成:大麦,燕麦和小麦.他知道自己的饲料精确的配比,在市场上是买不到这样的饲料的.他只好购买其他三种混合饲料(同样都由三种麦子组 ...

  3. (转)你知道Android也有安全模式吗?(地球人都知道了吧)

    使用PC时,我们习惯在安全模式下解决驱动的各种兼容性问题.而你是否又知道,Android手机同样存在安全模式,帮你解决APP的各种冲突问题. 很多Android手机用户都遇到过下面这种极端情况:因为第 ...

  4. Extjs中grid表格中去掉红三角

    在编辑Extjs的gridpanel的时候,数据有错误或是修改在每个单元格上都会出现红色的小三角,在每个列上面可以配置allowBlank: false来标识这个不可以为空 有的时候在保存数据时如果不 ...

  5. sublime2开发Python的编码问题

    在sublime2文本编辑器直接开发python程序会出现错误 Traceback (most recent call last): File ".\sublime_plugin.py&qu ...

  6. 适应手机端的jQuery图片滑块动画

    一款比较特别的jQuery图片滑块插件,它不仅在PC浏览器上可以使用,而且更适合在手机端的网页中使用.这款jQuery插件不仅可以定义图片切换的方向,而且可以即时切换图片切换的动画方式,可以有平移.翻 ...

  7. eval函数

    eval()函数中的eval是evaluate的简称,这个函数的作用就是把一段字符串当作PHP语句来执行 <?php $a=100;eval("echo $a;");     ...

  8. MongoDB-启动的时候出现了问题

    之前MongoDB启动的时候是正常的,不知道后来启动报错了,就把粘贴出来查询了.最后才知道是由于自己不正常的关闭导致的这个情况. --摘录:MongoDB非正常关闭后修复记录 mongod没有后台执行 ...

  9. linux 命令——PS命令

    首先要明白什么是进程进程是一个正在运行的程序.也就是说在Linux系统上运行的所有东西都是进程.和进程相比较,作业是一系列按一定顺序执行的命令.一条简单的命令可能会涉及多个进程,尤其是当使用管道和重定 ...

  10. 2、vs2012无法从模型更新到数据库的问题

    在模型设计视图空白处选择“从模型生成到数据库…”:不出意外的话应该是打开生成的脚本,当然也可能出现如下的错误,请下载最新的SQL Server Data Tool(我本地VS2012,数据库SQLSe ...