sass教程

sass教程

1. 使用变量;

sass让人们受益的一个重要特性就是它为css引入了变量。你能够把反复使用的css属性值 定义成变量,而后经过变量名来引用它们,而无需重复书写这一属性值。或者,对于仅使用过一 次的属性值,你能够赋予其一个易懂的变量名,让人一眼就知道这个属性值的用途。css

sass使用$符号来标识变量(老版本的sass使用!来标识变量。改为$是多半由于!highlight-color看起来太丑了。),好比$highlight-color$sidebar-width。为何选择$ 符号呢?由于它好认、更具美感,且在CSS中并没有他用,不会致使与现存或将来的css语法冲突。html

1-1. 变量声明;

sass变量的声明和css属性的声明很像:web

$highlight-color: #F90;

这意味着变量$highlight-color如今的值是#F90。任何能够用做css属性值的赋值都 能够用做sass的变量值,甚至是以空格分割的多个属性值,如$basic-border: 1px solid black;,或以逗号分割的多个属性值,如$plain-font: "Myriad Pro"、Myriad、"Helvetica Neue"、Helvetica、"Liberation Sans"、Arial和sans-serif; sans-serif;。这时变 量尚未生效,除非你引用这个变量——咱们很快就会了解如何引用。浏览器

CSS属性不一样,变量能够在css规则块定义以外存在。当变量定义在css规则块内,那么该变量只能在此规则块内使用。若是它们出如今任何形式的{...}块中(如@media或者@font-face块),状况也是如此:sass

$nav-color: #F90; nav { $width: 100px; width: $width; color: $nav-color; } //编译后 nav { width: 100px; color: #F90; } 

在这段代码中,$nav-color这个变量定义在了规则块外边,因此在这个样式表中均可以像 nav规则块那样引用它。$width这个变量定义在了nav{ }规则块内,因此它只能在nav规则块 内使用。这意味着是你能够在样式表的其余地方定义和使用$width变量,不会对这里形成影响。ide

只声明变量其实没啥用处,咱们最终的目的仍是使用它们。上例已介绍了如何使用 $nav-color$width这两个变量,接下来咱们将进一步探讨变量的使用方法。函数

1-2. 变量引用;

凡是css属性的标准值(好比说1px或者bold)可存在的地方,变量就可使用。css生成时,变量会被它们的值所替代。以后,若是你须要一个不一样的值,只须要改变这个变量的值,则全部引用此变量的地方生成的值都会随之改变。工具

$highlight-color: #F90; .selected { border: 1px solid $highlight-color; } //编译后 .selected { border: 1px solid #F90; } 

看上边示例中的$highlight-color变量,它被直接赋值给border属性,当这段代码被编译输出css时,$highlight-color会被#F90这一颜色值所替代。产生的效果就是给selected这个类一条1像素宽、实心且颜色值为#F90的边框。性能

在声明变量时,变量值也能够引用其余变量。当你经过粒度区分,为不一样的值取不一样名字时,这至关有用。下例在独立的颜色值粒度上定义了一个变量,且在另外一个更复杂的边框值粒度上也定义了一个变量:学习

$highlight-color: #F90; $highlight-border: 1px solid $highlight-color; .selected { border: $highlight-border; } //编译后 .selected { border: 1px solid #F90; }

这里,$highlight-border变量的声明中使用了$highlight-color这个变量。产生的效 果就跟你直接为border属性设置了一个1px $highlight-color solid的值是同样的。 最后,咱们来了解一下变量命名的实用技巧,以结束关于变量的介绍。

1-3. 变量名用中划线仍是下划线分隔;

sass的变量名能够与css中的属性名和选择器名称相同,包括中划线和下划线。这彻底取决于我的的喜爱,有些人喜欢使用中划线来分隔变量中的多个词(如$highlight-color),而有些人喜欢使用下划线(如$highlight_color)。使用中划线的方式更为广泛,这也是compass和本文都用的方式。

不过,sass并不想强迫任何人必定使用中划线或下划线,因此这两种用法相互兼容。用中划线声明的变量可使用下划线的方式引用,反之亦然。这意味着即便compass选择用中划线的命名方式,这并不影响你在使用compass的样式中用下划线的命名方式进行引用:

$link-color: blue; a { color: $link_color; } //编译后 a { color: blue; }

在上例中,$link-color$link_color其实指向的是同一个变量。实际上,在sass的大 多数地方,中划线命名的内容和下划线命名的内容是互通的,除了变量,也包括对混合器和Sass函数的命名。可是在sass中纯css部分不互通,好比类名、ID或属性名。

尽管变量自身提供了不少有用的地方,可是sass基于变量提供的更为强大的工具才是咱们关注的焦点。只有当变量与sass的其余特性一块儿使用时,才能发挥其所有的潜能。接下来,咱们将探讨其中一个很是重要的特性,即规则嵌套。

2. 嵌套CSS 规则;

css中重复写选择器是很是恼人的。若是要写一大串指向页面中同一块的样式时,每每须要 一遍又一遍地写同一个ID

#content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }

像这种状况,sass可让你只写一遍,且使样式可读性更高。在Sass中,你能够像俄罗斯套娃那样在规则块中嵌套规则块。sass在输出css时会帮你把这些嵌套规则处理好,避免你的重复书写。

#content { article { h1 { color: #333 } p { margin-bottom: 1.4em } } aside { background-color: #EEE } } 
/* 编译后 */ #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }

上边的例子,会在输出css时把它转换成跟你以前看到的同样的效果。这个过程当中,sass用了两步,每一步都是像打开俄罗斯套娃那样把里边的嵌套规则块一个个打开。首先,把#content(父级)这个id放到article选择器(子级)和aside选择器(子级)的前边:

#content { article { h1 { color: #333 } p { margin-bottom: 1.4em } } #content aside { background-color: #EEE } } 
/* 编译后 */ #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }

而后,#content article里边还有嵌套的规则,sass重复一遍上边的步骤,把新的选择器添加到内嵌的选择器前边。

一个给定的规则块,既能够像普通的CSS那样包含属性,又能够嵌套其余规则块。当你同时要为一个容器元素及其子元素编写特定样式时,这种能力就很是有用了。

#content { background-color: #f5f5f5; aside { background-color: #eee } }

容器元素的样式规则会被单独抽离出来,而嵌套元素的样式规则会像容器元素没有包含任何属性时那样被抽离出来。

#content { background-color: #f5f5f5 } #content aside { background-color: #eee }

大多数状况下这种简单的嵌套都没问题,可是有些场景下不行,好比你想要在嵌套的选择器 里边马上应用一个相似于:hover的伪类。为了解决这种以及其余状况,sass提供了一个特殊结 构&

2-1. 父选择器的标识符&;

通常状况下,sass在解开一个嵌套规则时就会把父选择器(#content)经过一个空格链接到子选择器的前边(articleaside)造成(#content article#content aside)。这种在CSS里边被称为后代选择器,由于它选择ID为content的元素内全部命中选择器articleaside的元素。但在有些状况下你却不会但愿sass使用这种后代选择器的方式生成这种链接。

最多见的一种状况是当你为连接之类的元素写:hover这种伪类时,你并不但愿之后代选择器的方式链接。好比说,下面这种状况sass就没法正常工做:

article a { color: blue; :hover { color: red } }

这意味着color: red这条规则将会被应用到选择器article a :hoverarticle元素内连接的全部子元素在被hover时都会变成红色。这是不正确的!你想把这条规则应用到超连接自身,然后代选择器的方式没法帮你实现。

解决之道为使用一个特殊的sass选择器,即父选择器。在使用嵌套规则时,父选择器能对于嵌套规则如何解开提供更好的控制。它就是一个简单的&符号,且能够放在任何一个选择器可出现的地方,好比h1放在哪,它就能够放在哪。

article a { color: blue; &:hover { color: red } }

当包含父选择器标识符的嵌套规则被打开时,它不会像后代选择器那样进行拼接,而是&被父选择器直接替换:

article a { color: blue } article a:hover { color: red }

在为父级选择器添加:hover等伪类时,这种方式很是有用。同时父选择器标识符还有另一种用法,你能够在父选择器以前添加选择器。举例来讲,当用户在使用IE浏览器时,你会经过JavaScript<body>标签上添加一个ie的类名,为这种状况编写特殊的样式以下:

#content aside { color: red; body.ie & { color: green } } 
/*编译后*/ #content aside {color: red}; body.ie #content aside { color: green }

sass在选择器嵌套上是很是智能的,即便是带有父选择器的状况。当sass遇到群组选择器(由多个逗号分隔开的选择器造成)也能完美地处理这种嵌套。

2-2. 群组选择器的嵌套;

CSS里边,选择器h1h2h3会同时命中h1元素、h2元素和h3元素。与此相似,.button button会命中button元素和类名为.button的元素。这种选择器称为群组选择器。群组选择器 的规则会对命中群组中任何一个选择器的元素生效。

.button, button { margin: 0; }

当看到上边这段代码时,你可能还没意识到会有重复性的工做。但会很快发现:若是你须要在一个特定的容器元素内对这样一个群组选择器进行修饰,状况就不一样了。css的写法会让你在群组选择器中的每个选择器前都重复一遍容器元素的选择器。

.container h1, .container h2, .container h3 { margin-bottom: .8em }

很是幸运,sass的嵌套特性在这种场景下也很是有用。当sass解开一个群组选择器规则内嵌的规则时,它会把每个内嵌选择器的规则都正确地解出来:

.container { h1, h2, h3 {margin-bottom: .8em} }

首先sass.containerh1.containerh2.containerh3分别组合,而后将三 者从新组合成一个群组选择器,生成你前边看到的普通css样式。对于内嵌在群组选择器内的嵌 套规则,处理方式也同样:

nav, aside { a {color: blue} }

首先sassnavaasidea分别组合,而后将两者从新组合成一个群组选择器:

nav a, aside a {color: blue}

处理这种群组选择器规则嵌套上的强大能力,正是sass在减小重复敲写方面的贡献之一。尤为在当嵌套级别达到两层甚至三层以上时,与普通的css编写方式相比,只写一遍群组选择器大大减小了工做量。

有利必有弊,你须要特别注意群组选择器的规则嵌套生成的css。虽然sass让你的样式表看上去很小,但实际生成的css却可能很是大,这会下降网站的速度。

关于选择器嵌套的最后一个方面,咱们看看sass如何处理组合选择器,好比>、+和~的使用。你将看到,这种场景下你甚至无需使用父选择器标识符。

2-3. 子组合选择器和同层组合选择器:>、+和~;

上边这三个组合选择器必须和其余选择器配合使用,以指定浏览器仅选择某种特定上下文中的元素。

article section { margin: 5px } article > section { border: 1px solid #ccc }

你能够用子组合选择器>选择一个元素的直接子元素。上例中,第一个选择器会选择article下的全部命中section选择器的元素。第二个选择器只会选择article下紧跟着的子元素中命中section选择器的元素。

在下例中,你能够用同层相邻组合选择器+选择header元素后紧跟的p元素:

header + p { font-size: 1.1em }

你也能够用同层全体组合选择器~,选择全部跟在article后的同层article元素,无论它们之间隔了多少其余元素:

article ~ article { border-top: 1px dashed #ccc }

这些组合选择器能够绝不费力地应用到sass的规则嵌套中。能够把它们放在外层选择器后边,或里层选择器前边:

article { ~ article { border-top: 1px dashed #ccc } > section { background: #eee } dl > { dt { color: #333 } dd { color: #555 } } nav + & { margin-top: 0 } }

sass会如你所愿地将这些嵌套规则一一解开组合在一块儿:

article ~ article { border-top: 1px dashed #ccc } article > footer { background: #eee } article dl > dt { color: #333 } article dl > dd { color: #555 } nav + article { margin-top: 0 }

sass中,不只仅css规则能够嵌套,对属性进行嵌套也能够减小不少重复性的工做。

2-4. 嵌套属性;

sass中,除了CSS选择器,属性也能够进行嵌套。尽管编写属性涉及的重复不像编写选择器那么糟糕,可是要反复写border-styleborder-widthborder-color以及border-*等也是很是烦人的。在sass中,你只需敲写一遍border

nav { border: { style: solid; width: 1px; color: #ccc; } }

嵌套属性的规则是这样的:把属性名从中划线-的地方断开,在根属性后边添加一个冒号:,紧跟一个{ }块,把子属性部分写在这个{ }块中。就像css选择器嵌套同样,sass会把你的子属性一一解开,把根属性和子属性部分经过中划线-链接起来,最后生成的效果与你手动一遍遍写的css样式同样:

nav { border-style: solid; border-width: 1px; border-color: #ccc; }

对于属性的缩写形式,你甚至能够像下边这样来嵌套,指明例外规则:

nav { border: 1px solid #ccc { left: 0px; right: 0px; } }

这比下边这种同等样式的写法要好:

nav { border: 1px solid #ccc; border-left: 0px; border-right: 0px; }

属性和选择器嵌套是很是伟大的特性,由于它们不只大大减小了你的编写量,并且经过视觉上的缩进使你编写的样式结构更加清晰,更易于阅读和开发。

即使如此,随着你的样式表变得愈来愈大,这种写法也很难保持结构清晰。有时,处理这种大量样式的惟一方法就是把它们分拆到多个文件中。sass经过对css原有@import规则的改进直接支持了这一特性。

3. 导入SASS文件;

css有一个特别不经常使用的特性,即@import规则,它容许在一个css文件中导入其余css文件。然而,后果是只有执行到@import时,浏览器才会去下载其余css文件,这致使页面加载起来特别慢。

sass也有一个@import规则,但不一样的是,sass@import规则在生成css文件时就把相关文件导入进来。这意味着全部相关的样式被概括到了同一个css文件中,而无需发起额外的下载请求。另外,全部在被导入文件中定义的变量和混合器(参见2.5节)都可在导入文件中使用。

使用sass@import规则并不须要指明被导入文件的全名。你能够省略.sass.scss文件后缀(见下图)。这样,在不修改样式表的前提下,你彻底能够随意修改你或别人写的被导入的sass样式文件语法,在sassscss语法之间随意切换。举例来讲,@import"sidebar";这条命令将把sidebar.scss文件中全部样式添加到当前样式表中。

本节将介绍如何使用sass@import来处理多个sass文件。首先,咱们将学习编写那些被导入的sass文件,由于在一个大型sass项目中,这样的文件是你最常编写的那一类。接着,了解集中导入sass文件的方法,使你的样式可重用性更高,包括声明可自定义的变量值,以及在某一个选择器范围内导入sass文件。最后,介绍如何在sass中使用css原生的@import命令。

一般,有些sass文件用于导入,你并不但愿为每一个这样的文件单独地生成一个css文件。对此,sass用一个特殊的约定来解决。

3-1. 使用SASS部分文件;

当经过@importsass样式分散到多个文件时,你一般只想生成少数几个css文件。那些专门为@import命令而编写的sass文件,并不须要生成对应的独立css文件,这样的sass文件称为局部文件。对此,sass有一个特殊的约定来命名这些文件。

此约定即,sass局部文件的文件名如下划线开头。这样,sass就不会在编译时单独编译这个文件输出css,而只把这个文件用做导入。当你@import一个局部文件时,还能够不写文件的全名,即省略文件名开头的下划线。举例来讲,你想导入themes/_night-sky.scss这个局部文件里的变量,你只需在样式表中写@import "themes/night-sky";

局部文件能够被多个不一样的文件引用。当一些样式须要在多个页面甚至多个项目中使用时,这很是有用。在这种状况下,有时须要在你的样式表中对导入的样式稍做修改,sass有一个功能恰好能够解决这个问题,即默认变量值。

3-2. 默认变量值;

通常状况下,你反复声明一个变量,只有最后一处声明有效且它会覆盖前边的值。举例说明:

$link-color: blue; $link-color: red; a { color: $link-color; }

在上边的例子中,超连接的color会被设置为red。这可能并非你想要的结果,假如你写了一个可被他人经过@import导入的sass库文件,你可能但愿导入者能够定制修改sass库文件中的某些值。使用sass!default标签能够实现这个目的。它很像css属性中!important标签的对立面,不一样的是!default用于变量,含义是:若是这个变量被声明赋值了,那就用它声明的值,不然就用这个默认值。

$fancybox-width: 400px !default; .fancybox { width: $fancybox-width; }

在上例中,若是用户在导入你的sass局部文件以前声明了一个$fancybox-width变量,那么你的局部文件中对$fancybox-width赋值400px的操做就无效。若是用户没有作这样的声明,则$fancybox-width将默认为400px

接下来咱们将学习嵌套导入,它容许只在某一个选择器的范围内导入sass局部文件。

3-3. 嵌套导入;

跟原生的css不一样,sass容许@import命令写在css规则内。这种导入方式下,生成对应的css文件时,局部文件会被直接插入到css规则内导入它的地方。举例说明,有一个名为_blue-theme.scss的局部文件,内容以下:

aside { background: blue; color: white; }

而后把它导入到一个CSS规则内,以下所示:

.blue-theme {@import "blue-theme"} //生成的结果跟你直接在.blue-theme选择器内写_blue-theme.scss文件的内容彻底同样。  .blue-theme { aside { background: blue; color: #fff; } }@import

被导入的局部文件中定义的全部变量和混合器,也会在这个规则范围内生效。这些变量和混合器不会全局有效,这样咱们就能够经过嵌套导入只对站点中某一特定区域运用某种颜色主题或其余经过变量配置的样式。

有时,可用css原生的@import机制,在浏览器中下载必需的css文件。sass也提供了几种方法来达成这种需求。

3-4. 原生的CSS导入;

因为sass兼容原生的css,因此它也支持原生的CSS@import。尽管一般在sass中使用@import时,sass会尝试找到对应的sass文件并导入进来,但在下列三种状况下会生成原生的CSS@import,尽管这会形成浏览器解析css时的额外下载:

  • 被导入文件的名字以.css结尾;
  • 被导入文件的名字是一个URL地址(好比http://www.sass.hk/css/css.css),由此可用谷歌字体API提供的相应服务;
  • 被导入文件的名字是CSS的url()值。

这就是说,你不能用sass@import直接导入一个原始的css文件,由于sass会认为你想用css原生的@import。可是,由于sass的语法彻底兼容css,因此你能够把原始的css文件更名为.scss后缀,便可直接导入了。

文件导入是保证sass的代码可维护性和可读性的重要一环。次之但亦很是重要的就是注释了。注释能够帮助样式做者记录写sass的过程当中的想法。在原生的css中,注释对于其余人是直接可见的,但sass提供了一种方式可在生成的css文件中按需抹掉相应的注释。

4. 静默注释;

css中注释的做用包括帮助你组织样式、之后你看本身的代码时明白为何这样写,以及简单的样式说明。可是,你并不但愿每一个浏览网站源码的人都能看到全部注释。

sass另外提供了一种不一样于css标准注释格式/* ... */的注释语法,即静默注释,其内容不会出如今生成的css文件中。静默注释的语法跟JavaScriptJava等类C的语言中单行注释的语法相同,它们以//开头,注释内容直到行末。

body { color: #333; // 这种注释内容不会出如今生成的css文件中 padding: 0; /* 这种注释内容会出如今生成的css文件中 */ }

实际上,css的标准注释格式/* ... */内的注释内容亦可在生成的css文件中抹去。当注释出如今原生css不容许的地方,如在css属性或选择器中,sass将不知如何将其生成到对应css文件中的相应位置,因而这些注释被抹掉。

body { color /* 这块注释内容不会出如今生成的css中 */: #333; padding: 1; /* 这块注释内容也不会出如今生成的css中 */ 0; } 

你已经掌握了sass的静默注释,了解了保持sass条理性和可读性的最基本的三个方法:嵌套、导入和注释。如今,咱们要进一步学习新特性,这样咱们不但能保持条理性还能写出更好的样式。首先要介绍的内容是:使用混合器抽象你的相关样式。

5. 混合器;

若是你的整个网站中有几处小小的样式相似(例如一致的颜色和字体),那么使用变量来统一处理这种状况是很是不错的选择。可是当你的样式变得愈来愈复杂,你须要大段大段的重用样式的代码,独立的变量就没办法应付这种状况了。你能够经过sass的混合器实现大段样式的重用。

混合器使用@mixin标识符定义。看上去很像其余的CSS @标识符,好比说@media或者@font-face。这个标识符给一大段样式赋予一个名字,这样你就能够轻易地经过引用这个名字重用这段样式。下边的这段sass代码,定义了一个很是简单的混合器,目的是添加跨浏览器的圆角边框。

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

而后就能够在你的样式表中经过@include来使用这个混合器,放在你但愿的任何地方。@include调用会把混合器中的全部样式提取出来放在@include被调用的地方。若是像下边这样写:

notice {
  background-color: green; border: 2px solid #00aa00; @include rounded-corners; } //sass最终生成: 
.notice { background-color: green; border: 2px solid #00aa00; -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }

.notice中的属性border-radius-moz-border-radius-webkit-border-radius所有来自rounded-corners这 个混合器。这一节将介绍使用混合器来避免重复。经过使用参数,你可使用混合器把你样式中的通用样式抽离出来,而后轻松地在其余地方重用。实际上,混合器 太好用了,一不当心你可能会过分使用。大量的重用可能会致使生成的样式表过大,致使加载缓慢。因此,首先咱们将讨论混合器的使用场景,避免滥用。

5-1. 什么时候使用混合器;

利用混合器,能够很容易地在样式表的不一样地方共享样式。若是你发现本身在不停地重复一段样式,那就应该把这段样式构形成优良的混合器,尤为是这段样式自己就是一个逻辑单元,好比说是一组放在一块儿有意义的属性。

判断一组属性是否应该组合成一个混合器,一条经验法则就是你可否为这个混合器想出一个好的名字。若是你能找到一个很好的短名字来描述这些属性修饰的样式,好比rounded-cornersfancy-font或者no-bullets,那么每每可以构造一个合适的混合器。若是你找不到,这时候构造一个混合器可能并不合适。

混合器在某些方面跟css类很像。都是让你给一大段样式命名,因此在选择使用哪一个的时候可能会产生疑惑。最重要的区别就是类名是在html文件中应用的,而混合器是在样式表中应用的。这就意味着类名具备语义化含义,而不只仅是一种展现性的描述:用来描述html元素的含义而不是html元素的外观。而另外一方面,混合器是展现性的描述,用来描述一条css规则应用以后会产生怎样的效果。

在以前的例子中,.notice是一个有语义的类名。若是一个html元素有一个notice的类名,就代表了这个html元素的用途:向用户展现提醒信息。rounded-corners混合器是展现性的,它描述了包含它的css规则最终的视觉样式,尤为是边框角的视觉样式。混合器和类配合使用写出整洁的htmlcss,由于使用语义化的类名亦能够帮你避免重复使用混合器。为了保持你的htmlcss的易读性和可维护性,在写样式的过程当中必定要铭记两者的区别。

有时候仅仅把属性放在混合器中还远远不够,可喜的是,sass一样容许你把css规则放在混合器中。

5-2. 混合器中的CSS规则;

混合器中不只能够包含属性,也能够包含css规则,包含选择器和选择器中的属性,以下代码:

@mixin no-bullets { list-style: none; li { list-style-image: none; list-style-type: none; margin-left: 0px; } }

当一个包含css规则的混合器经过@include包含在一个父规则中时,在混合器中的规则最终会生成父规则中的嵌套规则。举个例子,看看下边的sass代码,这个例子中使用了no-bullets这个混合器:

ul.plain { color: #444; @include no-bullets; }

sass@include指令会将引入混合器的那行代码替换成混合器里边的内容。最终,上边的例子以下代码:

ul.plain { color: #444; list-style: none; } ul.plain li { list-style-image: none; list-style-type: none; margin-left: 0px; }

混合器中的规则甚至可使用sass的父选择器标识符&。使用起来跟不用混合器时同样,sass解开嵌套规则时,用父规则中的选择器替代&

若是一个混合器只包含css规则,不包含属性,那么这个混合器就能够在文档的顶部调用,写在全部的css规则以外。若是你只是为本身写一些混合器,这并无什么大的用途,可是当你使用一个相似于Compass的库时,你会发现,这是提供样式的好方法,缘由在于你能够选择是否使用这些样式。

接下来你将学习如何经过给混合器传参数来让混合器变得更加灵活和可重用。

5-3. 给混合器传参;

混合器并不必定总得生成相同的样式。能够经过在@include混合器时给混合器传参,来定制混合器生成的精确样式。当@include混合器时,参数其实就是能够赋值给css属性值的变量。若是你写过JavaScript,这种方式跟JavaScriptfunction很像:

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

当混合器被@include时,你能够把它看成一个css函数来传参。若是你像下边这样写:

a { @include link-colors(blue, red, green); } //Sass最终生成的是: a { color: blue; } a:hover { color: red; } a:visited { color: green; }

当你@include混合器时,有时候可能会很难区分每一个参数是什么意思,参数之间是一个什么样的顺序。为了解决这个问题,sass容许经过语法$name: value的形式指定每一个参数的值。这种形式的传参,参数顺序就没必要再在意了,只须要保证没有漏掉参数便可:

a { @include link-colors( $normal: blue, $visited: green, $hover: red ); }

尽管给混合器加参数来实现定制很好,可是有时有些参数咱们没有定制的须要,这时候也须要赋值一个变量就变成很痛苦的事情了。因此sass容许混合器声明时给参数赋默认值。

5-4. 默认参数值;

为了在@include混合器时没必要传入全部的参数,咱们能够给参数指定一个默认值。参数默认值使用$name: default-value的声明形式,默认值能够是任何有效的css属性值,甚至是其余参数的引用,以下代码:

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

若是像下边这样调用:@include link-colors(red) $hover$visited也会被自动赋值为red

混合器只是sass样式重用特性中的一个。咱们已经了解到混合器主要用于样式展现层的重用,若是你想重用语义化的类呢?这就涉及sass的另外一个重要的重用特性:选择器继承。

6. 使用选择器继承来精简CSS;

使用sass的时候,最后一个减小重复的主要特性就是选择器继承。基于Nicole Sullivan面向对象的css的理念,选择器继承是说一个选择器能够继承为另外一个选择器定义的全部样式。这个经过@extend语法实现,以下代码:

//经过选择器继承继承样式 .error { border: 1px red; background-color: #fdd; } .seriousError { @extend .error; border-width: 3px; }

在上边的代码中,.seriousError将会继承样式表中任何位置处为.error定义的全部样式。以class="seriousError" 修饰的html元素最终的展现效果就好像是class="seriousError error"。相关元素不只会拥有一个3px宽的边框,并且这个边框将变成红色的,这个元素同时还会有一个浅红色的背景,由于这些都是在.error里边定义的样式。

.seriousError不只会继承.error自身的全部样式,任何跟.error有关的组合选择器样式也会被.seriousError以组合选择器的形式继承,以下代码:

//.seriousError从.error继承样式 .error a{ //应用到.seriousError a color: red; font-weight: 100; } h1.error { //应用到hl.seriousError font-size: 1.2rem; }

如上所示,在class="seriousError"html元素内的超连接也会变成红色和粗体。

本节将介绍与混合器相比,哪一种状况下更适合用继承。接下来在探索继承的工做细节以前,咱们先了解一下继承的高级用法。最后,咱们将看看使用继承可能会有哪些坑,学习如何避免这些坑。

6-1. 什么时候使用继承;

5-1节介绍了混合器主要用于展现性样式的重用,而类名用于语义化样式的重用。由于继承是基于类的(有时是基于其余类型的选择器),因此继承应该是创建在语义化的关系上。当一个元素拥有的类(好比说.seriousError)代表它属于另外一个类(好比说.error),这时使用继承再合适不过了。

这有点抽象,因此咱们从几个方面来阐释一下。想象一下你正在编写一个页面,给html元素添加类名,你发现你的某个类(好比说.seriousError)另外一个类(好比说.error)的细化。你会怎么作?

  • 你能够为这两个类分别写相同的样式,可是若是有大量的重复怎么办?使用sass时,咱们提倡的就是不要作重复的工做。
  • 你可使用一个选择器组(好比说.error.seriousError)给这两个选择器写相同的样式。若是.error的全部样式都在同一个地方,这种作法很好,可是若是是分散在样式表的不一样地方呢?再这样作就困难多了。
  • 你可使用一个混合器为这两个类提供相同的样式,但当.error的样式修饰遍及样式表中各处时,这种作法面临着跟使用选择器组同样的问题。这两个类也不是刚好有相同的 样式。你应该更清晰地表达这种关系。
  • 综上所述你应该使用@extend。让.seriousError.error继承样式,使二者之间的关系很是清晰。更重要的是不管你在样式表的哪里使用.error.seriousError都会继承其中的样式。

如今你已经更好地掌握了什么时候使用继承,以及继承有哪些突出的优势,接下来咱们看看一些高级用法。

6-2. 继承的高级用法;

任何css规则均可以继承其余规则,几乎任何css规则也均可以被继承。大多数状况你可能只想对类使用继承,可是有些场合你可能想作得更多。最经常使用的一种高级用法是继承一个html元素的样式。尽管默认的浏览器样式不会被继承,由于它们不属于样式表中的样式,可是你对html元素添加的全部样式都会被继承。

接下来的这段代码定义了一个名为disabled的类,样式修饰使它看上去像一个灰掉的超连接。经过继承a这一超连接元素来实现:

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

假如一条样式规则继承了一个复杂的选择器,那么它只会继承这个复杂选择器命中的元素所应用的样式。举例来讲, 若是.seriousError@extend.important.error , 那么.important.errorh1.important.error 的样式都会被.seriousError继承, 可是.important或者.error下的样式则不会被继承。这种状况下你极可能但愿.seriousError可以分别继承.important或者.error下的样式。

若是一个选择器序列(#main .seriousError@extend另外一个选择器(.error),那么只有彻底命中#main .seriousError这个选择器的元素才会继承.error的样式,就像单个类 名继承那样。拥有class="seriousError".main元素以外的元素不会受到影响。

#main .error这种选择器序列是不能被继承的。这是由于从#main .error中继承的样式通常状况下会跟直接从.error中继承的样式基本一致,细微的区别每每令人迷惑。

如今你已经了解了经过继承可以作些什么事情,接下来咱们将学习继承的工做细节,在生成对应css的时候,sass具体干了些什么事情。

6-3. 继承的工做细节;

跟变量和混合器不一样,继承不是仅仅用css样式替换@extend处的代码那么简单。为了避免让你对生成的css感受奇怪,对这背后的工做原理有必定了解是很是重要的。

@extend背后最基本的想法是,若是.seriousError @extend .error, 那么样式表中的任何一处.error都用.error.seriousError这一选择器组进行替换。这就意味着相关样式会如预期那样应用到.error.seriousError。当.error出如今复杂的选择器中,好比说h1.error.error a或者#main .sidebar input.error[type="text"],那状况就变得复杂多了,可是不用担忧,sass已经为你考虑到了这些。

关于@extend有两个要点你应该知道。

  • 跟混合器相比,继承生成的css代码相对更少。由于继承仅仅是重复选择器,而不会重复属性,因此使用继承每每比混合器生成的css体积更小。若是你很是关心你站点的速度,请牢记这一点。
  • 继承听从css层叠的规则。当两个不一样的css规则应用到同一个html元素上时,而且这两个不一样的css规则对同一属性的修饰存在不一样的值,css层叠规则会决定应用哪一个样式。至关直观:一般权重更高的选择器胜出,若是权重相同,定义在后边的规则胜出。

混合器自己不会引发css层叠的问题,由于混合器把样式直接放到了css规则中,而继承存在样式层叠的问题。被继承的样式会保持原有定义位置和选择器权重不变。一般来讲这并不会引发什么问题,可是知道这点总没有坏处。

6-4. 使用继承的最佳实践;

一般使用继承会让你的css美观、整洁。由于继承只会在生成css时复制选择器,而不会复制大段的css属性。可是若是你不当心,可能会让生成的css中包含大量的选择器复制。

避免这种状况出现的最好方法就是不要在css规则中使用后代选择器(好比.foo .bar)去继承css规则。若是你这么作,同时被继承的css规则有经过后代选择器修饰的样式,生成css中的选择器的数量很快就会失控:

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

在上边的例子中,sass必须保证应用到.baz的样式同时也要应用到.foo .bar(位于class="foo"的元素内的class="bar"的元素)。例子中有一条应用到.bip .baz(位于class="bip"的元素内的class="baz"的元素)的css规则。当这条规则应用到.foo .bar时,可能存在三种状况,以下代码:

<!-- 继承可能迅速变复杂 --> <!-- Case 1 --> <div class="foo"> <div class="bip"> <div class="bar">...</div> </div> </div> <!-- Case 2 --> <div class="bip"> <div class="foo"> <div class="bar">...</div> </div> </div> <!-- Case 3 --> <div class="foo bip"> <div class="bar">...</div> </div>

为了应付这些状况,sass必须生成三种选择器组合(仅仅是.bip .foo .bar不能覆盖全部状况)。若是任何一条规则里边的后代选择器再长一点,sass须要考虑的状况就会更多。实际上sass并不老是会生成全部可能的选择器组合,即便是这样,选择器的个数依然可能会变得至关大,因此若是容许,尽量避免这种用法。

值得一提的是,只要你想,你彻底能够放心地继承有后代选择器修饰规则的选择器,无论后代选择器多长,但有一个前提就是,不要用后代选择器去继承。

7. 小结;

本文介绍了sass最基本部分,你能够轻松地使用sass编写清晰、无冗余、语义化的css。对于sass提供的工具你已经有了一个比较深刻的了解,同时也掌握了什么时候使用这些工具的指导原则。

变量是sass提供的最基本的工具。经过变量可让独立的css值变得可重用,不管是在一条单独的规则范围内仍是在整个样式表中。变量、混合器的命名甚至sass的文件名,能够互换通用_-。一样基础的是sass的嵌套机制。嵌套容许css规则内嵌套css规则,减小重复编写经常使用的选择器,同时让样式表的结构一眼望去更加清晰。sass同时提供了特殊的父选择器标识符&,经过它能够构造出更高效的嵌套。

你也已经学到了sass的另外一个重要特性,样式导入。经过样式导入能够把分散在多个sass文件中的内容合并生成到一个css文件,避免了项目中有大量的css文件经过原生的css @import带来的性能问题。经过嵌套导入和默认变量值,导入能够构建更强有力的、可定制的样式。混合器容许用户编写语义化样式的同时避免视觉层面上样式的重复。你不只学到了如何使用混合器减小重复,同时学习到了如何使用混合器让你的css变得更加可维护和语义化。最后,咱们学习了与混合器相辅相成的选择器继承。继承容许你声明类之间语义化的关系,经过这些关系能够保持你的css的整洁和可维护性。

相关文章
相关标签/搜索