安装Sass和Compass
sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby。(注:mac下自带Ruby无需在安装Ruby!)
window下安装SASS首先需要安装Ruby,先从官网下载Ruby并安装。安装过程中请注意勾选Add Ruby executables to your PATH添加到系统环境变量。
安装完成后需测试安装有没有成功,运行CMD输入以下命令:
ruby -v
//如安装成功会打印
ruby 2.2.2p95 (2015-04-13 revision 50295) [i386-mingw32]
如上已经安装成功。但因为国内网络的问题导致gem源间歇性中断因此我们需要更换gem源。(使用淘宝的gem源https://ruby.taobao.org/)如下:
//1.删除原gem源
gem sources –remove https://rubygems.org/
//2.添加国内淘宝源
gem sources -a https://ruby.taobao.org/
上面的淘宝镜像已经换地址了,新的地址https://gems.ruby-china.org/
//3.打印是否替换成功
gem sources -l
//4.安装sass
1、通过命令安装 Sass
打开电脑的命令终端,输入下面的命令:
gem install sass
提醒一下,在使用 Mac 的同学,可能需要在上面的命令前加上”sudo”,才能正常安装:
sudo gem install sass
如果上面的方法没有安装成功,可以使用下面的两种方法。
2、通过 Compass 来安装 Sass
除了使用 gem 命令来安装 Sass 之外,还可以通过安装 compass 来安装 Sass,因为 Compass 是基于 Sass 开发的一个框架。也就是说,你安装了 Compass,也就同时安装好了 Sass。
同样的在你的命令终端输入下面的命令:
sudo gem install sass
执行完上面的命令之后,就开始安装 Compass 和 Sass。
注:Compass 是一个成熟的、基于 Sass 开发的一个框架,这里面集成了很多写好的 mixins 和 Sass 函数。不过在此暂不做过多阐述。
3、本地安装 Sass
由于有时候直接使用上面的命令安装会让你无法正常实现安装(网络受限原因),当碰到这种情况之时,那么安装需要特殊去处理,可以通过下面的方法来实现 Sass 的正常安装:
可以到 Rubygems(http://rubygems.org/) 网站上将 Sass 的安装包(http://rubygems.org/gems/sass)下载下来,然后在命令终端输入:
gem install <把下载的安装包拖到这里>
直接回车即可安装成功。
注:在 iOSX 系统平台,可以直接将下载的安装包拖到 “gem install” 后面,如果在是 Windows 系统,需要手功输入安装的文件路径。
//5.检查是否安装成功
sass -v
//6.升级sass
gem update sass
这个时候你看到类似下面这样的信息,表示你的 Sass 已更新到最新版本。
//7.卸载sass
gem uninstall sass
这样就卸载了 Sass ,但这行命令基本上是使用不上。
Sass 和 SCSS 有什么区别?
Sass 和 SCSS 其实是同一种东西,我们平时都称之为 Sass,两者之间不同之处有以下两点:
文件扩展名不同,Sass 是以“.sass”后缀为扩展名,而 SCSS 是以“.scss”后缀为扩展名
语法书写方式不同,Sass 是以严格的缩进式语法规则来书写,不带大括号({})和分号(;),而 SCSS 的语法书写和我们的 CSS 语法书写方式非常类似。
Sass/SCSS 和纯 CSS 写法差很多吗?
写法差很多吗?这是很多初学者会问的一个问题。那么借此机会简单了解一下。
Sass 和 CSS 写法有差别:
Sass 和 CSS 写法的确存在一定的差异,由于 Sass 是基于 Ruby 写出来,所以其延续了 Ruby 的书写规范。在书写 Sass 时不带有大括号和分号,其主要是依靠严格的缩进方式来控制的。如:
Sass写法:
body
color: #fff
background: #f36
而在 CSS 我们是这样书写:
body{
color:#fff;
background:#f36;
}
SCSS 和 CSS 写法无差别:
SCSS 和 CSS 写法无差别,这也是 Sass 后来越来越受大众喜欢原因之一。简单点说,把你现有的“.css”文件直接修改成“.scss”即可使用。
sass编译
1.命令编译
命令编译是指使用你电脑中的命令终端,通过输入 Sass 指令来编译 Sass。这种编译方式是最直接也是最简单的一种方式。因为只需要在你的命令终端输入:
单文件编译:
sass <要编译的Sass文件路径>/style.scss:<要输出CSS文件路径>/style.css
这是对一个单文件进行编译,如果想对整个项目所有 Sass 文件编译成 CSS 文件,可以这样操作:
多文件编译:
sass sass/:css/
上面的命令表示将项目中“sass”文件夹中所有“.scss”(“.sass”)文件编译成“.css”文件,并且将这些 CSS 文件都放在项目中“css”文件夹中。
缺点及解决方法:
在实际编译过程中,你会发现上面的命令,只能一次性编译。每次个性保存“.scss”文件之后,都得重新执行一次这样的命令。如此操作太麻烦,其实还有一种方法,就是在编译 Sass 时,开启“watch”功能,这样只要你的代码进行任保修改,都能自动监测到代码的变化,并且给你直接编译出来:
sass –watch <要编译的Sass文件路径>/style.scss:<要输出CSS文件路径>/style.css
$ sass -h
Usage: sass [options] [INPUT] [OUTPUT]
Description:
Converts SCSS or Sass files to CSS.
Common Options:
-I, --load-path PATH Specify a Sass import path.
-r, --require LIB Require a Ruby library before running Sass.
--compass Make Compass imports available and load project configuration.
-t, --style NAME Output style. Can be nested (default), compact, compressed, or expanded.
-?, -h, --help Show this help message.
-v, --version Print the Sass version.
Watching and Updating:
--watch Watch files or directories for changes.
The location of the generated CSS can be set using a colon:
sass --watch input.sass:output.css
sass --watch input-dir:output-dir
--update Compile files or directories to CSS.
Locations are set like --watch.
-f, --force Recompile every Sass file, even if the CSS file is newer.
Only meaningful for --update.
--stop-on-error If a file fails to compile, exit immediately.
Only meaningful for --watch and --update.
Input and Output:
--scss Use the CSS-superset SCSS syntax.
--sourcemap=TYPE How to link generated output to the source files.
auto (default): relative paths where possible, file URIs elsewhere
file: always absolute file URIs
inline: include the source text in the sourcemap
none: no sourcemaps
-s, --stdin Read input from standard input instead of an input file.
This is the default if no input file is specified.
-E, --default-encoding ENCODING Specify the default encoding for input files.
--unix-newlines Use Unix-style newlines in written files.
-g, --debug-info Emit output that can be used by the FireSass Firebug plugin.
-l, --line-numbers Emit comments in the generated CSS indicating the corresponding source line.
--line-comments
Miscellaneous:
-i, --interactive Run an interactive SassScript shell.
-c, --check Just check syntax, don't evaluate.
--precision NUMBER_OF_DIGITS How many digits of precision to use when outputting decimal numbers.
Defaults to 5.
--cache-location PATH The path to save parsed Sass files. Defaults to .sass-cache.
-C, --no-cache Don't cache parsed Sass files.
--trace Show a full Ruby stack trace on error.
-q, --quiet Silence warnings and status messages during compilation.
2.GUI工具编译
Koala (http://koala-app.com/)
Compass.app(http://compass.kkbox.com/)
Scout(http://mhs.github.io/scout-app/)
CodeKit(https://incident57.com/codekit/index.html)
Prepros(https://prepros.io/)
相比之下,我比较推荐使用以下两个:
Koala (http://www.w3cplus.com/preprocessor/sass-gui-tool-koala.html)
CodeKit (http://www.w3cplus.com/preprocessor/sass-gui-tool-codekit.html)
3.自动化编译
1、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']);
}
想了解 Grunt 同学请单击这里学习《Grunt-beginner前端自动化工具》。
2、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']);
!!!sass文件的命名不能有中文,sass只支持utf-8编码
众所周知,每个人编写的 CSS 样式风格都不一样,有的喜欢将所有样式代码都写在同一行,而有的喜欢将样式分行书写。在 Sass 中编译出来的样式风格也可以按不同的样式风格显示。其主要包括以下几种样式风格:
嵌套输出方式 nested
1、嵌套输出方式 nested
Sass 提供了一种嵌套显示 CSS 文件的方式。例如
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
在编译的时候带上参数“ --style nested”:
sass --watch test.scss:test.css --style nested
编译出来的 CSS 样式风格:
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
2、展开输出方式 expanded
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
在编译的时候带上参数“ --style expanded”:
sass --watch test.scss:test.css --style expanded
这个输出的 CSS 样式风格和 nested 类似,只是大括号在另起一行,同样上面的代码,编译出来:
nav ul {
margin: 0;
padding: 0;
list-style: none;
}
nav li {
display: inline-block;
}
nav a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
紧凑输出方式 compact
紧凑输出方式 compact
nav {
ul {
margin: 0;
padding: 0;
list-style: none;
}
li { display: inline-block; }
a {
display: block;
padding: 6px 12px;
text-decoration: none;
}
}
在编译的时候带上参数“ --style compact”:
sass --watch test.scss:test.css --style compact
该方式适合那些喜欢单行 CSS 样式格式的朋友,编译后的代码如下:
nav ul { margin: 0; padding: 0; list-style: none; }
nav li { display: inline-block; }
nav a { display: block; padding: 6px 12px; text-decoration: none; }
压缩输出方式 compressed
sass --watch test.scss:test.css --style compressed
压缩输出方式会去掉标准的 Sass 和 CSS 注释及空格。也就是压缩好的 CSS 代码样式风格
Sass 调试一直以来都是一件头痛的事情,使用 Sass 的同学都希望能在浏览器中直接调试 Sass 文件,能找到对应的行数。值得庆幸的是,现在实现并不是一件难事,只要你的浏览器支持“sourcemap”功能即可。早一点的版本,需要在编译的时候添加“–sourcemap” 参数:
sass –watch –scss –sourcemap style.scss:style.css
在 Sass3.3 版本之上(我测试使用的版本是 3.4.7),不需要添加这个参数也可以:
sass –watch style.scss:style.css
在命令终端,你将看到一个信息:
Change detected to: style.scss
write style.css
write style.css.map
这时你就可以像前面展示的 gif 图一样,调试你的 Sass 代码。
Sass 的变量包括三个部分:
声明变量的符号“$”
变量名称
赋予变量的值
来看一个简单的示例,假设你的按钮颜色可以给其声明几个变量:
$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;
如果值后面加上!default则表示默认值。(在默认值前声明同样的名字就会覆盖默认值)
注:了解 Bootstrap 的 Sass 版本的同学,就一眼能看出,上面的示例代码是 Bootstrap 定义 primarybutton 的颜色。
[Sass]变量的调用
在 Sass 中声明了变量之后,就可以在需要的地方调用变量。调用变量的方法也非常的简单。
比如在定义了变量
$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;
在按钮 button 中调用,可以按下面的方式调用
.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;
}
sass中不能有中文的注释,不然会报错
[Sass]局部变量和全局变量
Sass 中变量的作用域在过去几年已经发生了一些改变。直到最近,规则集和其他范围内声明变量的作用域才默认为本地。如果已经存在同名的全局变量,从 3.4 版本开始,Sass 已经可以正确处理作用域的概念,并通过创建一个新的局部变量来代替。
全局变量与局部变量
先来看一下代码例子:
//SCSS
$color: orange !default;//定义全局变量(在选择器、函数、混合宏...的外面定义的变量为全局变量)
.block {
color: $color;//调用全局变量
}
em {
$color: red;//定义局部变量
a {
color: $color;//调用局部变量
}
}
span {
color: $color;//调用全局变量
}
css 的结果:
//CSS
.block {
color: orange;
}
em a {
color: red;
}
span {
color: orange;
}
上面的示例演示可以得知,在元素内部定义的变量不会影响其他元素。如此可以简单的理解成,全局变量就是定义在元素外面的变量,如下代码:
$color:orange !default;
color就是一个全局变量,而定义在元素内部的变量,比如 c o l o r 就 是 一 个 全 局 变 量 , 而 定 义 在 元 素 内 部 的 变 量 , 比 如 color:red; 是一个局部变量。
除此之外,Sass 现在还提供一个 !global 参数。!global 和 !default 对于定义变量都是很有帮助的。我们之后将会详细介绍这两个参数的使用以及其功能。
全局变量的影子
当在局部范围(选择器内、函数内、混合宏内…)声明一个已经存在于全局范围内的变量时,局部变量就成为了全局变量的影子。基本上,局部变量只会在局部范围内覆盖全局变量。
上面例子中的 em 选择器内的变量 $color 就是一个全局变量的影子。
//SCSS
$color: orange !default;//定义全局变量
.block {
color: $color;//调用全局变量
}
em {
$color: red;//定义局部变量(全局变量 $color 的影子)
a {
color: $color;//调用局部变量
}
}
什么时候声明变量?
我的建议,创建变量只适用于感觉确有必要的情况下。不要为了某些骇客行为而声明新变量,这丝毫没有作用。只有满足所有下述标准时方可创建新变量:
该值至少重复出现了两次;
该值至少可能会被更新一次;
该值所有的表现都与变量有关(非巧合)。
基本上,没有理由声明一个永远不需要更新或者只在单一地方使用变量。
温馨小提示:您在学习 sass 时,除了在我们网页上可以做练习,还有一个便利在线编辑器网址如下:
[Sass]嵌套-选择器嵌套
Sass 中还提供了选择器嵌套功能,但这也并不意味着你在 Sass 中的嵌套是无节制的,因为你嵌套的层级越深,编译出来的 CSS 代码的选择器层级将越深,这往往是大家不愿意看到的一点。这个特性现在正被众多开发者滥用。
选择器嵌套为样式表的作者提供了一个通过局部选择器相互嵌套实现全局选择的方法,Sass 的嵌套分为三种:
选择器嵌套
属性嵌套
伪类嵌套
1、选择器嵌套
假设我们有一段这样的结构:
<header>
<nav>
<a href=“##”>Home</a>
<a href=“##”>About</a>
<a href=“##”>Blog</a>
</nav>
<header>
想选中 header 中的 a 标签,在写 CSS 会这样写:
nav a {
color:red;
}
header nav a {
color:green;
}
那么在 Sass 中,就可以使用选择器的嵌套来实现:
nav {
a {
color: red;
header & {
color:green;
}
}
}
[Sass]嵌套-属性嵌套
Sass 中还提供属性嵌套,CSS 有一些属性前缀相同,只是后缀不一样,比如:border-top/border-right,与这个类似的还有 margin、padding、font 等属性。
假设你的样式中用到了:
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
在 Sass 中我们可以这样写:
.box {
border: {
top: 1px solid red;
bottom: 1px solid green;
}
}
[Sass]嵌套-伪类嵌套
其实伪类嵌套和属性嵌套非常类似,只不过他需要借助&
符号一起配合使用。我们就拿经典的“clearfix”为例吧:
.clearfix{
&:before,
&:after {
content:"";
display: table;
}
&:after {
clear:both;
overflow: hidden;
}
}
编译出来的 CSS:
clearfix:before, .clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
overflow: hidden;
}
避免选择器嵌套:
选择器嵌套最大的问题是将使最终的代码难以阅读。开发者需要花费巨大精力计算不同缩进级别下的选择器具体的表现效果。
选择器越具体则声明语句越冗长,而且对最近选择器的引用(&)也越频繁。在某些时候,出现混淆选择器路径和探索下一级选择器的错误率很高,这非常不值得。
为了防止此类情况,我们应该尽可能避免选择器嵌套。然而,显然只有少数情况适应这一措施。
[Sass]混合宏-声明混合宏
如果你的整个网站中有几处小样式类似,比如颜色,字体等,在 Sass 可以使用变量来统一处理,那么这种选择还是不错的。但当你的样式变得越来越复杂,需要重复使用大段的样式时,使用变量就无法达到我们目了。这个时候 Sass 中的混合宏就会变得非常有意义。在这一节中,主要向大家介绍 Sass 的混合宏。
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;
}
复杂的混合宏:
上面是一个简单的定义混合宏的方法,当然, Sass 中的混合宏还提供更为复杂的,你可以在大括号里面写上带有逻辑关系,帮助更好的做你想做的事情,如:
@mixin box-shadow($shadow...) {
@if length($shadow) >= 1 {
@include prefixer(box-shadow, $shadow);
} @else{
$shadow:0 0 4px rgba(0,0,0,.3);
@include prefixer(box-shadow, $shadow);
}
}
这个 box-shadow 的混合宏,带有多个参数,这个时候可以使用“ … ”来替代。简单的解释一下,当 $shadow 的参数数量值大于或等于“ 1 ”时,表示有多个阴影值,反之调用默认的参数值“ 0 0 4px rgba(0,0,0,.3) ”。
[Sass]混合宏-调用混合宏
在 Sass 中通过 @mixin 关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏。
$radius:5px !default;
@mixin border-radius{
border-radius:$radius;
}
.ee{
@include border-radius
}
编译后
.ee {
border-radius: 5px;
}
[Sass]混合宏的参数–传一个不带值的参数
Sass 的混合宏有一个强大的功能,可以传参,那么在 Sass 中传参主要有以下几种情形:
A) 传一个不带值的参数
在混合宏中,可以传一个不带任何值的参数,比如:
@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]混合宏的参数–传一个带值的参数
在 Sass 的混合宏中,还可以给混合宏的参数传一个默认值,例如:
@mixin border-radius($radius:3px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
[Sass]混合宏的参数–传多个参数
Sass 混合宏除了能传一个参数之外,还可以传多个参数,如:
@mixin center($width,$height){
width: $width;
height: $height;
position: absolute;
top: 50%;
left: 50%;
margin-top: -($height) / 2;
margin-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;
margin-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);
}
[Sass]混合宏的参数–混合宏的不足
混合宏在实际编码中给我们带来很多方便之处,特别是对于复用重复代码块。但其最大的不足之处是会生成冗余的代码块。比如在不同的地方调用一个相同的混合宏时。如
@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 的混合宏最不足之处。
[Sass]扩展/继承
在 Sass 中也具有继承一说,也是继承类中的样式代码块。在 Sass 中是通过关键词 “@extend”来继承已存在的类样式块,从而实现代码的继承。如下所示:
//SCSS
.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 会将选择器合并在一起,形成组合选择器:
.btn, .btn-primary, .btn-second {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
[Sass]占位符 %placeholder
%placeholder 声明的代码,如果不被 @extend 调用的话,不会产生任何代码。来看一个演示:
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
这段代码没有被 @extend 调用,他并没有产生任何代码块,只是静静的躺在你的某个 SCSS 文件中。只有通过 @extend 调用才会产生代码:
//SCSS
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
.btn {
@extend %mt5;
@extend %pt5;
}
.block {
@extend %mt5;
span {
@extend %pt5;
}
}
编译出来的CSS
//CSS
.btn, .block {
margin-top: 5px;
}
.btn, .block span {
padding-top: 5px;
}
从编译出来的 CSS 代码可以看出,通过 @extend 调用的占位符,编译出来的代码会将相同的代码合并在一起。这也是我们希望看到的效果,也让你的代码变得更为干净。
[Sass]混合宏 VS 继承 VS 占位符
什么时候用混合宏,什么时候用继承,什么时候使用占位符?其实他们各有各的优点与缺点,先来看看他们使用效果:
1.混合宏总结:编译出来的 CSS 清晰告诉了大家,他不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余,这也是 CSSer 无法忍受的一件事情。不过他并不是一无事处,他可以传参数。
个人建议:如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。
2.继承总结:使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,比如 .mt, .block, .block span, .header, .header span。这样编译出来的代码相对于混合宏来说要干净的多,也是 CSSer 期望看到。但是他不能传变量参数。
个人建议:如果你的代码块不需要专任何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。
3.占位符总结:编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。”
[Sass]插值#{}
使用 CSS 预处理器语言的一个主要原因是想使用 Sass 获得一个更好的结构体系。比如说你想写更干净的、高效的和面向对象的 CSS。Sass 中的插值(Interpolation)就是重要的一部分。让我们看一下下面的例子:
$properties: (margin, padding);
@mixin set-value($side, $value) {
@each $prop in $properties {
#{$prop}-#{$side}: $value;
}
}
.login-box {
@include set-value(top, 14px);
}
它可以让变量和属性工作的很完美,上面的代码编译成 CSS:
.login-box {
margin-top: 14px;
padding-top: 14px;
}
它可以让变量和属性工作的很完美,上面的代码编译成 CSS:
.login-box {
margin-top: 14px;
padding-top: 14px;
}
这是 Sass 插值中一个简单的实例。当你想设置属性值的时候你可以使用字符串插入进来。另一个有用的用法是构建一个选择器。可以这样使用:
@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);
编译出来的 CSS:
.header-text-small { font-size: 12px; }
.header-text-medium { font-size: 20px; }
.header-text-big { font-size: 40px; }
一旦你发现这一点,你就会想到超级酷的 mixins,用来生成代码或者生成另一个 mixins。然而,这并不完全是可能的。第一个限制,这可能会很删除用于 Sass 变量的插值。
$margin-big: 40px;
$margin-medium: 20px;
$margin-small: 12px;
@mixin set-value($size) {
margin-top: $margin-#{$size};
}
.login-box {
@include set-value(big);
}
上面的 Sass 代码编译出来,你会得到下面的信息:
error style.scss (Line 5: Undefined variable: “$margin-".)
所以,#{}语法并不是随处可用,你也不能在 mixin 中调用:
@mixin updated-status {
margin-top: 20px;
background: #F00;
}
$flag: "status";
.navigation {
@include updated-#{$flag};
}
上面的代码在编译成 CSS 时同样会报错:
error style.scss (Line 7: Invalid CSS after "...nclude updated-": expected "}", was "#{$flag};")
//总结:差值方法不能用作变量名的调用,也不能用作宏的调用
幸运的是,可以使用 @extend 中使用插值。例如:
%updated-status {
margin-top: 20px;
background: #F00;
}
.selected-status {
font-weight: bold;
}
$flag: "status";
.navigation {
@extend %updated-#{$flag};
@extend .selected-#{$flag};
}
上面的 Sass 代码是可以运行的,因为他给了我们力量,可以动态的插入 .class 和 %placeholder。当然他们不能接受像 mixin 这样的参数,上面的代码编译出来的 CSS:
.navigation {
margin-top: 20px;
background: #F00;
}
.selected-status, .navigation {
font-weight: bold;
}
[Sass]注释
注释对于一名程序员来说,是极其重要,良好的注释能帮助自己或者别人阅读源码。在 Sass 中注释有两种方式,我暂且将其命名为:
1、类似 CSS 的注释方式,使用 ”/* ”开头,结属使用 ”*/ ”
2、类似 JavaScript 的注释方式,使用“//”
两者区别,前者会在编译出来的 CSS 显示,后者在编译出来的 CSS 中不会显示,来看一个示例:
[Sass]数据类型
Sass 和 JavaScript 语言类似,也具有自己的数据类型,在 Sass 中包含以下几种数据类型:
数字: 如,1、 2、 13、 10px;
字符串:有引号字符串或无引号字符串,如,”foo”、 ‘bar’、 baz;
颜色:如,blue、 #04a3f9、 rgba(255,0,0,0.5);
布尔型:如,true、 false;
空值:如,null;
值列表:用空格或者逗号分开,如,1.5em 1em 0 2em 、 Helvetica, Arial, sans-serif。
SassScript 也支持其他 CSS 属性值(property value),比如 Unicode 范围,或 !important 声明。然而,Sass 不会特殊对待这些属性值,一律视为无引号字符串 (unquoted strings)。
在编译 CSS 文件时不会改变其类型。只有一种情况例外,使用 #{ }插值语句 (interpolation) 时,有引号字符串将被编译为无引号字符串,这样方便了在混合指令 (mixin) 中引用选择器名。
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
@include firefox-message(".header");
编译为:
body.firefox .header:before {
content: "Hi, Firefox users!"; }
需要注意的是:当 deprecated = property syntax 时 (暂时不理解是怎样的情况),所有的字符串都将被编译为无引号字符串,不论是否使用了引号。
[Sass]值列表
所谓值列表 (lists) 是指 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 3px
1px 2px null 3px//这样写是错的,编译后null还是存在!!!
[Sass运算]加法
程序中的运算是常见的一件事情,但在 CSS 中能做运算的,到目前为止仅有 calc() 函数可行。但在 Sass 中,运算只是其基本特性之一。在 Sass 中可以做各种数学计算,在接下来的章节中,主要和大家一起探讨有关于 Sass 中的数学运算。
(一)、加法
加法运算是 Sass 中运算中的一种,在变量或属性中都可以做加法运算。如:
.box {
width: 20px + 8in;
}
编译出来的 CSS:
.box {
width: 788px;
}
但对于携带不同类型的单位时,在 Sass 中计算会报错,如下例所示:
.box {
width: 20px + 1em;
}
编译的时候,编译器会报错:“Incompatible units: 'em' and ‘px'.”
//也可以这样使用
.dd{
width:1px+1;
}
[Sass运算]减法
Sass 的减法运算和加法运算类似,我们通过一个简单的示例来做阐述:
$full-width: 960px;
$sidebar-width: 200px;
.content {
width: $full-width - $sidebar-width;
}
编译出来的 CSS 如下:
.content {
width: 760px;
}
同样的,运算时碰到不同类型的单位时,编译也会报错,如:
$full-width: 960px;
.content {
width: $full-width - 1em;
}
编译的时候,编译器报“Incompatible units: ‘em’ and ‘px’.”错误。
[Sass运算]乘法
Sass 中的乘法运算和前面介绍的加法与减法运算还略有不同。虽然他也能够支持多种单位(比如 em ,px , %),但当一个单位同时声明两个值时会有问题。比如下面的示例:
.box {
width:10px * 2px;
}
编译的时候报“20px*px isn't a valid CSS value.”错误信息。
如果进行乘法运算时,两个值单位相同时,只需要为一个数值提供单位即可。上面的示例可以修改成:
.box {
width: 10px * 2;
}
编译出来的 CSS:
.box {
width: 20px;
}
Sass 的乘法运算和加法、减法运算一样,在运算中有不同类型的单位时,也将会报错。如下面的示例:
.box {
width: 20px * 2em;
}
编译时报“40em*px isn’t a valid CSS value.”错误信息。
[Sass运算]除法
Sass 的乘法运算规则也适用于除法运算。不过除法运算还有一个特殊之处。众所周知“/”符号在 CSS 中已做为一种符号使用。因此在 Sass 中做除法运算时,直接使用“/”符号做为除号时,将不会生效,编译时既得不到我们需要的效果,也不会报错。一起先来看一个简单的示例:
.box {
width: 100px / 2;
}
编译出来的 CSS 如下:
.box {
width: 100px / 2;
}
这样的结果对于大家来说没有任何意义。要修正这个问题,只需要给运算的外面添加一个小括号( )即可:
.box {
width: (100px / 2);
}
编译出来的 CSS 如下:
.box {
width: 50px;
}
除了上面情况带有小括号,“/”符号会当作除法运算符之外,如果“/”符号在已有的数学表达式中时,也会被认作除法符号。如下面示例:
.box {
width: 100px / 2 + 2in;
}
编译出来的CSS:
.box {
width: 242px;
}
另外,在 Sass 除法运算中,当用变量进行除法运算时,“/”符号也会自动被识别成除法,如下例所示:
$width: 1000px;
$nums: 10;
.item {
width: $width / 10;
}
.list {
width: $width / $nums;
}
编译出来的CSS:
.item {
width: 100px;
}
.list {
width: 100px;
}
综合上述,”/ ”符号被当作除法运算符时有以下几种情况:
• 如果数值或它的任意部分是存储在一个变量中或是函数的返回值。
• 如果数值被圆括号包围。
• 如果数值是另一个数学表达式的一部分。
如下所示:
//SCSS
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;
height: 250px;
margin-left: 9px;
}
Sass 的除法运算还有一个情况。我们先回忆一下,在乘法运算时,如果两个值带有相同单位时,做乘法运算时,出来的结果并不是我们需要的结果。但在除法运算时,如果两个值带有相同的单位值时,除法运算之后会得到一个不带单位的数值。如下所示:
.box {
width: (1000px / 100px);
}
编译出来的CSS如下:
.box {
width: 10;
}
[Sass运算]变量计算
在 Sass 中除了可以使用数值进行运算之外,还可以使用变量进行计算,其实在前面章节的示例中也或多或少的向大家展示了。在 Sass 中使用变量进行计算,这使得 Sass 的数学运算功能变得更加实用。一起来看一个简单的示例:
$content-width: 720px;
$sidebar-width: 220px;
$gutter: 20px;
.container {
width: $content-width + $sidebar-width + $gutter;
margin: 0 auto;
}
编译出来的CSS
.container {
width: 960px;
margin: 0 auto;
}
[Sass运算]数字运算
在 Sass 运算中数字运算是较为常见的,数字运算包括前面介绍的:加法、减法、乘法和除法等运算。而且还可以通过括号来修改他们的运算先后顺序。和我们数学运算是一样的,一起来看个示例。
.box {
width: ((220px + 720px) - 11 * 20 ) / 12 ;
}
编译出来的 CSS:
.box {
width: 60px;
}
上面这个简单示例是一个典型的计算 Grid 单列列宽的运算。
[Sass运算]颜色运算
所有算数运算都支持颜色值,并且是分段运算的。也就是说,红、绿和蓝各颜色分段单独进行运算。如:
p {
color: #010203 + #040506;
}
计算公式为 01 + 04 = 05、02 + 05 = 07 和 03 + 06 = 09, 并且被合成为:
如此编译出来的 CSS 为:
p {
color: #050709;
}
算数运算也能将数字和颜色值 一起运算,同样也是分段运算的。如:
p {
color: #010203 * 2;
}
计算公式为 01 * 2 = 02、02 * 2 = 04 和 03 * 2 = 06, 并且被合成为:
p {
color: #020406;
}
[Sass运算]字符运算
在 Sass 中可以通过加法符号“+”来对字符串进行连接。例如:
$content: "Hello" + "" + "Sass!";
.box:before {
content: " #{$content} ";
}
编译出来的CSS:
.box:before {
content: " Hello Sass! ";
}
除了在变量中做字符连接运算之外,还可以直接通过 +,把字符连接在一起:
div {
cursor: e + -resize;
}
编译出来的CSS:
div {
cursor: e-resize;
}
注意,如果有引号的字符串被添加了一个没有引号的字符串 (也就是,带引号的字符串在 + 符号左侧), 结果会是一个有引号的字符串。 同样的,如果一个没有引号的字符串被添加了一个有引号的字符串 (没有引号的字符串在 + 符号左侧), 结果将是一个没有引号的字符串。 例如:
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
编译出来的 CSS:
p:before {
content: "Foo Bar";
font-family: sans-serif; }
本文学习自慕课