Sass-学习笔记【基础篇】
最下边附结构图
在线编辑器网址如下:http://sassmeister.com/
注意编写的时候,符号千万别用了中文的:、;、。...之类的,会报错,Sass也转换不成css。
less和sass的区别:
博客园文章—http://www.cnblogs.com/wangpenghui522/p/5467560.html
本章主要内容:变量 、混合宏 、继承 、占位 、插值 、运算 、数据类型
1:定义
Sass是css预处理器的一种,也是最早的css预处理语言。Sass采用Ruby语言编写,为css增加一些编程的特性,无需考虑浏览器的兼容性问题。
编程特性指:可以在css中使用变量、简单地逻辑程序、函数等等在编程语言中的一些基本特性
但是,sass无法兼容已有的css代码。即sass可以推导成css,css没变法反变回去之前的sass。
Sass是Css3的语法超级
2:其他一些css预处理器
- Sass(SCSS)
- LESS
- Stylus
- Turbine
- Swithch CSS
- CSS Cacheer
- DT CSS
3:关于Sass和SCSS之间的不同
Sass和SCSS其实是同一种东西,平时都称之为Sass。二者其实有不同
两个区别点如下
(1).文件扩展不同。
Sass用“.sass”后缀为扩展名;
SCSS用“.scss”;
(2).语法书写方式不同。
Sass以严格的缩进式语法规则来书写,不带大括号“{}”和分号“;”。
SCSS的语法书写和CSS语法书写方式非常类似。
示例如下:
Sass语法——
$font-stack: Helvetica,sans-serif //定义变量
$primary-color: #333 //定义变量
body
font: 100% $font-stack
color: $primary-color
可见这种写法是不带任何分号和大括号的,而且缩进要求非常的严格!
这种格式被称为Sass老版本,其文件名以“.sass”为扩展名
SCSS语法——
$font-stack : Helvetica, sans-serif;
$primary-color: #333;
body{
font: 100% $font-stack;
color: $primary-color;
}
SCSS是Sass的新语法格式。
SCSS从外观来看,和css几乎是一模一样的。代码都包裹在一对大括号里,并且末尾结束的地方都有一个分号。
其文件名格式常常以“.scss”为扩展名。
二者编译出来的css都是
body{
font: 100% Helvetica, sans-serif;
color: #333;
}
接下来学习的都是使用的SCSS语法方式
4:Sass和CSS的写法差别:
正如Sass和SCSS的区别一样,
css和SCSS的书写方式无差别;甚至可以把现有的css文件直接改为“.scss”都可以直接使用。
css和Sass的区别也是一样的!
Sass是基于Ruby写出来的,延续了Ruby的书写规范。
书写Sass的时候不带有大括号和分号,其主要的依靠严格的缩进方式来控制;
而css就是有大括号和分号,必不可少;而且缩进方式没有那么严格的要求,甚至可以不用缩进。
代码示例:
Sass写法
body
color: #fff
background: #fff
css写法
body{
color::#fff;
background: #fff;
}
5:sass的安装
- 安装sass先要安装ruby;因为sass是基于ruby的。
ruby安装包下载地址——Ruby 的官网http://rubyinstaller.org/downloads
慕课教程地址:http://www.imooc.com/video/7743
下载安装包下一步下一步就好,具体安装方案看慕课教程;
- 安装好ruby后调出命令终端安装sass
如何调出命令终端?两步走——
(1)win键+r调出“运行”对话框
(2)输入cmd或者command调出“命令(安装ruby后的全称叫做:Start Command Prompt with Ruby)”对话框【所以也可以根据全称去“开始”那里找一下】
在命令终端输入 “ruby-v”可以检测ruby是否安装,(一般情况下安装好ruby后,就会有Start Command Prompt with Ruby这个对话框,所以没必要检查)
在命令终端输入“gem install sass”后,回车来安装sass
等一会会提示“successfully installed sass-xx版本号 ” 这句话,就表示sass安装成功;
- 若不成功,请移步我的另一篇文章:http://www.cnblogs.com/padding1015/p/7133811.html
更新最新版的sass,同样在命令行输入:“gem update sass”即可
删除sass,同样在命令行输入:“gem uninstall sass”即可
注:在安装sass这里有些扩展知识,慕课这个老师的视频教程比较详尽:http://www.imooc.com/video/7063
2017-06-21 09:17:08
6:sass语法格式
见:第3条第(2)点
但是注意,使用了新格式的书写方式——即用了SCSS的书写方式,但是用“.sass”的后缀名就大错特错了!
".sass"只能使用Sass的老语法规则(即严格的缩进规则,且不带分号和大括号)
“.scss”使用的是Sass的新语法规则,也就是SCSS语法规则(类似CSS语法格式)
6-2:sass注释 http://www.imooc.com/video/7063
好的代码习惯,应当是注释占页面的2/3,这样维护人员后期维护和升级才会方便。
sass支持css的注释语法。
支持
/* * */
和
//
的注释方法;
但是,编译出来的css中,只有/* * */的注释可以被编译出来
介绍一个好的开发习惯:
在sass的宿主文件(即主要存放类名调用sass变量和函数等的文件内)里,通过一个块注释的方式,说明每一个被引入文件的作用。
大体就像给html页面注释一样,分几大模块。
然后每个文件分别放到大模块下边做注释
/**
*CONTENTS
*
*SETINGS
*variables.............................................................变量集中存储文件
*
*TOOLS
*
*COMPONETS
*reset............................................................Compass内置浏览器重置样式文件
*
*BUSINESS
*
*BASS
*screen.scss.............................................................针对当前站点主页的样式修饰
*
*/
7:Sass编译
使用了Sass开发,并不表示就要用link来引入“.sass”文件或者“.scss”文件,
项目文件中还是只引用.css文件就好。
Sass作为一个预处理工具,提前帮你做事情,只有需要他的时候,他才有功效。
所谓Sass编译,因为Sass开发之后,要让web页面能调用Sass写好的东西,就得有这么一个过程,这个过程就称之为Sass编译过程。
Sass编译的几种方法:
- 命令编译
- GUI工具编译
- 自动化编译
——命令编译:在你电脑的命令终端,输入Sass指令来编译Sass,(最直接、最简单)
做法:
(1)单文件编译——对一个单文件进行编译
代码语法
sass <要编译的Sass文件路径>/style.scss:<要输出CSS文件路径>/style.css
示例:
例如:本地一个项目中有一个“bootstrap.scss”文件,这个文件是放在sass文件夹下的。
把这个文件“bootstrap.scss”编译成“bootstrap.css”文件,并且放到该项目的css文件夹下
则命令终端的写法:
sass sass/bootstrap.scss:css/bootstrap.css
注意中间用冒号(:)转换。
(2)多文件编译——将整个项目所有的Sass文件编译成css文件
代码语法
sass scss/:css/
解析:命令表示将项目中“sass”文件夹中所有的“.scss”(或者".sass")文件编译成“.css”文件,
并且将这些css文件放在项目中的css文件夹中。
以上这种写法的缺点是:
只能编译一次,下次再用的时候,还得重新编译。
解决方法:开启"watch"功能(自动重新编译)
只要对代码进行了修改,都能自动检测到代码的变化,并且直接编译出来。
代码语法:
sass --watch <要编译的Sass文件路径>/style.scss:<要输出的CSS文件路径>/style.css
这样,像上边的bootstrap的例子,可以用watch来修改:
sass --watch sass/bootstrap.scss:css/bootstrap.css
这样写的话,一旦更改了bootstrap.scss文件,重新保存后,命令终端就能重新自动编译css文件
其他一些使用sass命令编译可带的参数
(图片来自慕课网教程)
——GUI界面工具编译:能看到的界面操作
几款GUI界面编译工具:
Koala (http://koala-app.com/)【开源,支持多个平台,功能同Codekit类似】
Compass.app(http://compass.kkbox.com/)
Scout(http://mhs.github.io/scout-app/)
CodeKit(https://incident57.com/codekit/index.html)【付费,only Mac】
Prepros(https://prepros.io/)
强烈推荐:
Koala (http://www.w3cplus.com/preprocessor/sass-gui-tool-koala.html)【官网:http://koala-app.com/】
CodeKit (http://www.w3cplus.com/preprocessor/sass-gui-tool-codekit.html)
【Koala是一个前端预处理器语言图形编译工具,支持Less、Sass、Compass、CoffeeScript,帮助web开发者更高效地使用它们进行开发。跨平台运行,完美兼容windows、linux、mac
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
——自动化编译:Grunt和Gulp
见慕课详解:传送带——http://www.imooc.com/code/6380
sass常见的编译错误
(1)字符编码错误
在创建Sass文件的时候,需要将文件编码设置为"utf-8",注意他不支持"GBK"编码
(2)路径中的中文字符错误
建议在项目中给文件命名或者文件目录命名不要使用中文字符。
8:Sass不同样式风格的输出方法
在 Sass 中编译出来的样式风格也可以按不同的样式风格显示。其主要包括以下几种样式风格:
- 嵌套输出方式 nested
- 展开输出方式 expanded
- 紧凑输出方式 compact
- 压缩输出方式 compressed
以下详解
——嵌套输出方式 nested
Sass提供了一种嵌套显示css文件的方式。
代码演示:
nav{
ul{
margin: 0;
padding: 0;
list-style: none;
}
li{display: inline-block;}
}
然后在编译的时候带上参数"--style nested";
如:
sass --watch test .sass:test.css --style nested
编译出来的css样式风格:
nav ul{
margin: 0;
padding: 0;
listy-style: none;}
nav li{
display: inline-block;}
nested: 闭合的大括号在最后一行的后边,不会另起一行;
——展开输出方式 expanded
所谓展开输出,就是最后的大括号会另起一行,最终格式和nested差不多;
如,.scss文件中这么写:
nav{
ul{
margin: 0;
padding: 0;
listy-style: none;
}
li{display: inline-block;}
}
在编译的时候要带上参数“--style expanded”;
sass --watch test.scss:test.css --style expanded
输出的css样式为:
nav ul{
margin: o;
padding: 0;
list-style: none;
}
nav li{
display: inline-block;
}
大括号另起一行。输出的css样式风格和nested类似;也是常用的css展开版样式风格
——紧凑输出方式 compact
sass代码示例
nav{
ul{
margin: 0;
padding: 0;
list-style: none;
}
}
li{
display: inline-block;
}
}
在编译的时候带上参数"--style compact";
sass --watch test.scss:test.css --style compact
css样式风格就会是变成单行css,如下:
nav ul { margin: 0; padding: 0; list-style: none; }
nav li { display: inline-block; }
——压缩输出方式 compressed
sass代码示例
nav{
ul{
margin: 0;
padding: 0;
list-style: none;
}
}
li{
display: inline-block;
}
}
在编译的时候带上参数"--style compressed";
sass --watch test.scss:test.css --style compressed
css样式风格:压缩输出方式会去掉标准的Sass和CSS注释及空格,也及时压缩好的css代码样式风格、
如下:
nav ul{margin:0;padding:0;list-style:none}nav li{display:inline-block}
一段时间之后,你实际上就不再需要写 CSS 代码了,只用写 Sass 代码。在这种情况下,你只需要设定输出格式为压缩格式,知道输出的 CSS 代码可以直接使用即可。
9:Sass调试
如何在浏览器中直接调试Sass文件,并找到对应的行数?
慕课教程地址:http://www.imooc.com/code/6386
-------------------------------------------------------------------Sass的基本特型篇------------------------------------------------------------------------------------
一、Sass声明变量
变量声明用"$"符号;语法如图(慕课:www.imooc.com/code/6950)
示例,给按钮颜色声明几个变量:
$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表示默认值。
二、Sass普通变量和默认变量
-普通变量-
定义之后可以在全局范围内使用。
$fontSize:12px;
body{
font-size: $fontSize;
}
编译后的css:
body{
font-size: 12px;
}
-默认变量-
sass的默认变量仅需在之后面加上!default即可
$baseLineHeight:1.5 !default;
body{
line-height: $baseLineHeight;
}
编译后的css代码:
body{
line-height : 1.5;
}
sass的默认变量一般是用来设置默认值的,然后根据需求来覆盖的。
覆盖的方式非常简单,只需要在默认的变量之前重新声明一下变量即可。
默认变量的价值在进行组件开发的时候会非常有用。
2017-06-21 13:07:57
以下是几种普通变量和默认变量的代码顺序和写法,
用来研究他们之间的关系:
——只有一个普通变量声明
$baseLineHeight: 2;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
结论:很正常、最普通的一个写法
——两个或多个普通变量声明
$baseLineHeight: 2;
$baseLineHeight: 3;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 3;
}
结论:这种多次普通声明的,就好像css一样,下边的覆盖上边的。最后展示的是最后一行声明的。
——一个默认变量声明
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 1.5;
}
结论:如果变量没有被赋值,就会被指定成!default的值,!default 表示默认值
——一个默认变量声明、一个普通变量
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
——一个默认变量声明、一个普通变量【相反声明顺序】
$baseLineHeight: 1.5 !default;
$baseLineHeight: 2;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
以上两个加一起来总结结论:
普通变量覆盖默认变量的,不受普通变量声明顺序的影响,可以看出,!default声明的变量优先级要小于普通声明的。
即使普通声明在默认变量的上边,也会显示普通变量的值。
——一个默认变量声明、两个普通变量【主要看覆盖能力、优先级】
——第一种顺序
$baseLineHeight: 1.5 !default;
$baseLineHeight: 3333;
$baseLineHeight: 2;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
——第二种顺序
$baseLineHeight: 1.5 !default;
$baseLineHeight: 2;
$baseLineHeight: 33333;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 33333;
}
——第三种顺序
$baseLineHeight: 3333;
$baseLineHeight: 1.5 !default;
$baseLineHeight: 2;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
以上几个加一起来总结结论:
普通变量覆盖默认变量且忽视顺序,
普通变量之间的覆盖是:后边的覆盖前边的。
——一个默认变量声明、一个普通变量、一个加!important的普通变量【检测important的在这里是否有用】
$baseLineHeight: 3333333!important;
$baseLineHeight: 1.5 !default;
$baseLineHeight: 2;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 2;
}
——【反顺序】
$baseLineHeight: 1.5 !default;
$baseLineHeight: 2;
$baseLineHeight: 3333333!important;
body{
line-height: $baseLineHeight;
}
编译的css为:
body{
line-height: 3333333!important;
}
以上几个加一起来总结结论:
忽视!important的作用,当成正常的普通变量
三、变量的调用
在Sass中声明了变量之后,在需要的地方调用;
调用的方法,就是把变量名写在属性对应的值得地方。
示例:
$width: 200px;
body{
width: $width;
}
编译后的css:
body{
width: 200px;
}
四、局部变量和全局变量
Sass变量有作用域这一说。
变量分为全局变量和局部变量
全局变量:在选择器、函数、混合宏...的外边定义的变量为全局变量,也就是定义在元素外边的变量。
- 有时候定义全局变量会加上"!default"符号,表示不设置都适用默认的值,同时优先级低,也容易被局部变量所覆盖,而不受代码上下文顺序的影响,一举多得。
局部变量:定义在元素内部的变量,局部范围内(选择期内、函数内、混合宏内...);
- 局部变量只会在局部范围内覆盖全局变量,在元素内部定义的变量不会影响其他元素
示例:
//SCSS
$color: orange !default;//定义全局变量(这是在选择器外部定义的)
.block{color: $color;//调用全局变量(这个.block选择器内没有再定义同名的$color变量,所以他调用的就是全局变量)}
em{
$color: red;//和全局变量"$color"同名,定义了一个局部变量(在选择器内部定义的)
a{
color: $color;//调用的是em选择器内部的局部变量。
}
}
span{color: $color;//调用全局变量,同.block的调用}
以上代码的css结果如下:
//CSS
.block{
color: orange;
}
em a{
color: red;
}
span{
color: orange;
}
全局变量的影子:当一个变量已经存在于全局范围内了,再在局部范围内声明了和他同名的变量,这个变量就称作全局变量的影子.
全局变量的影子也就是一种局部变量,其在局部范围内覆盖全局变量
如下实例中,$color就是全局变量的影子:
//SCSS
$color: orange !default;//定义全局变量
.block{
color: $color;//调用全局变量
}
em{
$color: red;//定义局部变量。$color就是全局变量$color的影子
a{
color:$color;//调用局部变量
}
}
什么时候声明变量?
不要为了某些骇客行为而声明新变量,只有满足所有下述标准时方可创建新变量:
- 该值至少重复出现了两次;
- 该值至少可能会被更新一次;
- 该值所有的表现都与变量有关(非巧合)。
基本上,没有理由声明一个永远不需要更新或者只在单一地方使用变量。
五、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;
}
}
}
"&":作用就是连接之前(或之后,根据使用位置不同其效果不同)的选择器(伪类嵌套那里也会用到,一看便明白)
header & == header nav a
(2)属性嵌套
Sass 中还提供属性嵌套,CSS 有一些属性前缀相同,只是后缀不一样,
比如:border-top/border-right,与这个类似的还有 margin、padding、font 等属性。假设你的样式中用到了:
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
在 Sass 中我们可以这样写:
.box { border : { //注意这个冒号(:)千万不能丢掉,不然是错误的,翻译出来就是.box border{}相当于选择器的嵌套了 top: 1px solid red; bottom: 1px solid green; } }
再比如:
你需要
.box { font-size: 12px; font-weight: bold; }
你可以这么写:
.box {
font: {
size: 12px;
weight: bold;
}
}
(3)伪类嵌套
其实伪类嵌套和属性嵌套非常类似,只不过他需要借助`&`符号一起配合使用。我们就拿经典的“clearfix”为例吧:
1 .clearfix{ 2 &:before, 3 &:after { 4 content:""; 5 display: table; 6 } 7 &:after { 8 clear:both; 9 overflow: hidden; 10 } 11 }
编译出来的 CSS:
1 clearfix:before, .clearfix:after { 2 content: ""; 3 display: table; 4 } 5 .clearfix:after { 6 clear: both; 7 overflow: hidden; 8 }
避免选择器嵌套:
- 选择器嵌套最大的问题是将使最终的代码难以阅读。开发者需要花费巨大精力计算不同缩进级别下的选择器具体的表现效果。
- 选择器越具体则声明语句越冗长,而且对最近选择器的引用(&)也越频繁。在某些时候,出现混淆选择器路径和探索下一级选择器的错误率很高,这非常不值得。
为了防止此类情况,我们应该尽可能避免选择器嵌套。
Sass函数有两种:
一、sass内置函数——跟代码块无关,称为functions。所有内置函数知识见进阶篇文章:【Sass-学习笔记【进阶篇】】http://www.cnblogs.com/padding1015/articles/7063242.html
二、可重用的代码块 ——mixin:可重用的代码块,可以看做是Sass中的函数,
在Sass中,用"@mixin"来声明一个混合宏。
六:Sass混合宏
变量是用来处理小段类似的样式代码的,若涉及到大量大段重复的样式时,则需要用Sass中的“混合宏”。
(变量就像js中的一个数值,而混合宏就像js中的一个数组。)
1.声明混合宏@mixin
不带参数的混合宏
@mixin border-radius{
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
其中,@mixin是用来声明混合宏的关键词,有点类似CSS中的@media、@font-face一样。
border-radius是混合宏的名称
{}里边是可以复用的样式代码。
带参数的混合宏(在定义混合宏的时候,带上参数。就像js的function(参数1){}一样)
@mixin border-radius($radius:5px){
-webkit-border-radius: $radius;
-moz-border-radius:$radius;
border-radius:$radius;
}
复杂的混合宏:
(可以在大括号里写上带有逻辑关系的代码,做更多的事。)
@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)".
2.调用混合宏@include
在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏。
例如在你的样式中定义了一个圆角的混合宏“border-radius”:
@mixin border-radius{
-webkit-border-radius: 3px;
border-radius: 3px;
}
在一个按钮中要调用定义好的混合宏“border-radius”,可以这样使用:
button {
@include border-radius;
}
这个时候编译出来的 CSS:
button {
-webkit-border-radius: 3px;
border-radius: 3px;
}
3.混合宏的传参
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;
}
B) 传一个带值的参数
在 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%);//在调用的时候再进行传值。
}
编译出来的 CSS:
.box {
-webkit-border-radius: 50%;
border-radius: 50%;
}
C)传多个带值的参数
Sass 混合宏除了能传一个参数之外,还可以传多个参数,多个参数用逗号隔开,其实照js的说法,参数也就是一个变量,也就是在括号中设了几个变量先传到大括号中。如:
@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);
}
比如,我自己做了一个实验:
@mixin gg($ma,$cs...){
margin: $ma;
box-sahdow: $cs;
}
.cs{
@include gg(10px 20px 30px 40px,0 0 0 #000,1px 1px 1px #fff);
}
编译出来的css:
.cs {
margin: 10px 20px 30px 40px;
box-sahdow: 0 0 0 #000, 1px 1px 1px #fff;
}
结论是:如果有一个参数后边带了点点点,那么,参数传值后,后边传几个值,都会被这一个参数引用,即引用了这个参数的属性,也就会把这个参数对应的值后边的值全部引用走了。
4.混合宏的优缺点
优点:
带来很多方便之处,特别是对于复用重复代码块。
缺点:
不足之处是会生成冗余的代码块。在不同的地方调用一个相同的混合宏时,并不能智能的将相同的样式代码块合并在一起。
七、[Sass]扩展/继承@extend
类似css中的属性继承
在Sass中也有继承这一说,也是继承类中的样式代码快。
在sass中是通过关键词"@extend"来继承已存在的类样式块,从而实现代码的继承。
如下所示:
//SCSS
.btn {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
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;
}
从示例代码可以看出,在 Sass 中的继承,可以继承类样式块中所有样式代码,而且编译出来的 CSS 会将选择器合并在一起,形成组合选择器:
.btn, .btn-primary {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
八、[Sass]占位符 %placeholde
占位符%placeholder是一个很强大、很实用的功能,他可以取代css中的基类造成的代码冗余的情形。
%placeholder声明的代码,如果不被@extend调用的话,不会产生任何代码。
示例:
%mt5{margin-top:5px;}
%pt5{padding-top:5px;}
通过@extend调用后:
.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 占位符
“什么时候用混合宏,什么时候用继承,什么时候使用占位符?”各有千秋
各有各的优点与缺点
a) Sass 中的混合宏使用
//SCSS中混合宏使用
@mixin mt($var){
margin-top: $var;
}
.block {
@include mt(5px);
span {
display:block;
@include mt(5px);
}
}
.header {
color: orange;
@include mt(5px);
span{
display:block;
@include mt(5px);
}
}
编译的css如下:
.block {
margin-top: 5px; }
.block span {
display: block;
margin-top: 5px; }
.header {
color: orange;
margin-top: 5px; }
.header span {
display: block;
margin-top: 5px; }
总结:编译出来的 CSS 清晰告诉了大家,他不会自动合并相同的样式代码,如果在样式文件中调用同一个混合宏,会产生多个对应的样式代码,造成代码的冗余,这也是 CSSer 无法忍受的一件事情。不过他并不是一无事处,他可以传参数。
个人(慕课老师)建议:如果你的代码块中涉及到变量,建议使用混合宏来创建相同的代码块。
b) Sass 中继承
将上面代码中的混合宏,使用类名来表示,然后通过继承来调用:
//SCSS 继承的运用
.mt{
margin-top: 5px;
}
.block {
@extend .mt;
span {
display:block;
@extend .mt;
}
}
.header {
color: orange;
@extend .mt;
span{
display:block;
@extend .mt;
}
}
编译的css如下:
.mt, .block, .block span, .header, .header span {
margin-top: 5px; }
.block span {
display: block; }
.header {
color: orange; }
.header span {
display: block; }
总结:使用继承后,编译出来的 CSS 会将使用继承的代码块合并到一起,通过组合选择器的方式向大家展现,
比如 .mt, .block, .block span, .header, .header span。
这样编译出来的代码相对于混合宏来说要干净的多,也是 CSSer 期望看到。但是他不能传变量参数。
个人建议:如果你的代码块不需要传任何变量参数,而且有一个基类已在文件中存在,那么建议使用 Sass 的继承。
c) 占位符
将上面代码中的基类 .mt 换成 Sass 的占位符格式:
//SCSS中占位符的使用
%mt{
margin-top: 5px;
}
.block {
@extend %mt;
span {
display:block;
@extend %mt;
}
}
.header {
color: orange;
@extend %mt;
span{
display:block;
@extend %mt;
}
}
编译的css代码如下:
.block, .block span, .header, .header span {
margin-top: 5px; }
.block span {
display: block; }
.header {
color: orange; }
.header span {
display: block; }
总结:编译出来的 CSS 代码和使用继承基本上是相同,只是不会在代码中生成占位符 mt 的选择器。
那么占位符和继承的主要区别的,“占位符是独立定义,不调用的时候是不会在 CSS 中产生任何代码;
继承是首先有一个基类存在,不管调用与不调用,基类的样式都将会出现在编译出来的 CSS 代码中。
表格:
十、[Sass]插值(interpolation)语句#{}
既然这么麻烦还感觉比css复杂了,为什么还用这个?
使用 CSS 预处理器语言的一个主要原因是想使用 Sass
获得一个更好的结构体系。比如说你想写更干净的、高效的和面向对象的 CSS
还有一点和字符串有关的:使用插值后,有引号字符串会被编译成无引号字符串,这样是为了方便在混合指令(mixin)中引用选择其名。
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;
}
这是 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 的注释方式,使用“//”
十二、[Sass]数据类型
Sass 和 JavaScript 语言类似,也具有自己的数据类型,在 Sass 中包含以下几种数据类型:
- 数字: 如,1、 2、 13、 10px;
- 字符串:有引号字符串或无引号字符串,如,"foo"、 'bar'、 baz;【注:!important被视为是无引号字符串的一种】
- 颜色:如,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)。也就是上边测试时"!improtant"没用的原因
2017-06-21 20:25:25
十三、[Sass]字符串
SassScript支持CSS的两种字符串类型:
- 有引号字符串(quoted strings)
- 无引号字符串(unquoted strings)
在编译css的时候,不会改变字符串的类型。即之前有引号之后也会有引号。
但有一个例外:
在使用#{ }插值语句时,有引号字符串将被编译成无引号字符串。这样是为了方便在混合指令(mixin)中引用选择器名。
@mixin firefox-message($selector){
body.firefox #{$selector}:before{
content: "Hi,firefox users!";
}
}
@include firefox-message(".header");
编译后的css
body.firefox .header:before{
content: "Hi,firefox users!"};
由示例可以看出来,#{$selecotor}这里插入到是参数$selector,而调用的时候,传进来的参数是一个带引号的字符串".header";
但是,经过编译后,.header的引号没有了,字符串类型变了。这是为了组成选择器而进行的的转换。
十四、[Sass]值列表
所谓值列表 (lists) 是指 Sass 如何处理 CSS 中:
margin: 10px 15px 0 0
或者:
font-face: Helvetica, Arial, sans-serif
像上面这样通过空格或者逗号分隔的一系列的值。
分隔方式
- 空格
- 逗号
事实上,独立的值也被视为值列表——只包含一个值的值列表。
Sass列表函数(Sass list function)赋予了值列表更多的功能,如下是部分
1:nth函数:可以直接访问值列表中的某一项
2:join函数:可以将多个值列表连结在一起
3:append函数:可以在值列表中添加值
4:@each规则:能够给值列表中的每个项目添加样式
值列表中可以再包含值列表。如果内部一层的值列表和外部层的使用相同的分割方式,那么要用圆括号包裹内层:
(1px 2px)(5px 6px)表示两个值列表,并且两个值列表内部又分别有两个值列表,这三个大小值列表都是用空格分隔的。
上边的值列表与 1px 2px 5px 6px 这个值列表在编译的css中是一样的。
他们的区别是:
有括号的是包含两个值列表的值列表,并且两个值还分别包含两个值。
后者是包含四个值的值列表。
可以用()表示空的列表,这样不可以直接编译成CSS
如果值列表中包含空的值列表或空值,编译时将清除空值,比如 1px 2px () 3px 或 1px 2px null 3px。
做个试验:
$bl: 1px 3px 4px ();
.ma{
margin: $bl;
}
编译结果:
.ma{
margin: 1px 3px 4px;}
第二个试验
$bl: 1px null 5px;
.ma{
margin: $bl;
}
编译的css:
.ma{
margin: 1px 5px;}
十五、[Sass运算]
在 Sass 中可以做各种数学计算,
Sass 中的数学运算——加法
在变量或属性中都可以做加法运算。
如:
.box {
width: 20px + 8in;
}
编译出来的 CSS:
.box {
width: 788px;
}
练习:
$sidebar-width: 220px;
$content-width: 720px;
$gap-width: 20px;
.container {
width: $sidebar-width + $content-width + $gap-width;
margin: 0 auto;
}
编译的css:
.container {
width: 960px;
margin: 0 auto;
}
但对于携带不同类型的单位时,在 Sass 中计算会报错,如下例所示:
.box {
width: 20px + 1em;
}
编译的时候,编译器会报错:“Incompatible units: 'em' and ‘px'.”
Sass 中的数学运算——减法
Sass 的减法运算和加法运算类似
示例来做阐述:
$full-width: 960px;
$sidebar-width: 200px;
.content {
width: $full-width - $sidebar-width;
}
编译出来的 CSS 如下:
.content {
width: 760px;
}
同样的,运算时碰到不同类型的单位时,编译也会报错,
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.”错误信息。
练习:
让icon图标的background-position的y轴值按20px递增
$list: twitter,facebook,github,weibo;
@for $i from 1 through length($list){
.icon-#{nth($list,$i)}{
background-postion: 0 -20px * $i;
}
}
编译结果:
.icon-twitter {
background-postion: 0 -20px; }
.icon-facebook {
background-postion: 0 -40px; }
.icon-github {
background-postion: 0 -60px; }
.icon-weibo {
background-postion: 0 -80px; }
讲解:
第一行准备了一个$list值列表,里边放的无引号的字符串,用逗号隔开。是为了日后的选择器用的
@for语句,用来遍历循环执行程序,让变量 i 在$list的长度中循环。
写法上:
$i from 1:表示i从1开始循环,【在Sass中,索引值index是从1开始的,和js的从0开始不一样】
through length($list):遍历的范围或说次数,取决于$list值列表的长度。
这里,length()是一个函数方法,传入参数 $list值列表
在大括号中,是遍历的内容,主要是给.icon-x选择器分别添加background-position属性。
而选择器名字,结合nth函数和变量,在$list列表做了个循环都添加了一遍
#{}插值,把四次循环遍历出来的列表结果分别插进来
nth($list,$i):是nth函数,传入两个参数,第一个是要取值的列表变量名字,第二个是取第几个的索引值,从1开始【从1开始,特别注意】
属性值 0 -20px * $i:
0表示x轴的位置是0;
-20px * $i:表示20px递增,利用乘法运算和for循环遍历,得出递增你结果。
另一种解决方法:
$list: twitter,facebook,github,weibo;
$index: 0;
@each $i in $list {
. icon-#{$i}{
background-postion: 0 - 20px * $index;
}
$index: $index + 1;
}
最后结果一样。利用的是index=0;index++;的技巧。
Sass 中的数学运算——除法
Sass 的乘法运算规则也适用于除法运算
即,支持多种单位、符号两边的数值不能都带长度单位(经后边测试,这句话说法有问题)
/”符号在 CSS 中已做为一种符号使用。因此在 Sass 中做除法运算时,
直接使用“/”符号做为除号时,将不会生效,编译时既得不到我们需要的效果,也不会报错。
”/ ”符号被当作除法【自动识别为除法符】运算符时有以下几种情况:
• 如果数值或它的任意部分是存储在一个变量中或是函数的返回值。【用变量进行除法运算时】
示例:
$width: 1000px;
$nums: 10;
.item{
width: $width / 10;
}
或者
.item{
width: $width / $ nums;
}
以上两种都会被自动识别成除法运算。
• 如果数值被圆括号包围。【除法运算表达式用小括号()包裹】
错误示例:
.box{
width: 100px / 2; //这种写法就是错的,不会报错但是也解析不出来,特别注意!单单一个除法运算一定记得加括号!一定记得加括号
}
正确写法:
.box{
width: (100px / 2); //这样就能正常运算了,得出结果50px
}
• 如果数值是另一个数学表达式的一部分。【"/"符号在已有的数学表达式中,会被认为是除法符号】
如:
.box{
width: 100px / 2 + 2in; //这种,即使没有括号也是可以用的。
}
汇总示例:
//scss
p{
font: 10px/8px; //纯CSS,不是除法运算
$width: 1000px; //声明一个局部变量
width: $width/2; //使用了变量,是除法运算
width: round(1.5)/2; //使用了函数,是除法运算
heigth: (500px/2); //使用了圆括号,是除法运算
margin-left: 5px + 8px/2px; //使用了加(+)号,是除法运算。【这个可见,除法运算符的两边可以都带单位,上边的说法不对】
}
验证:除法符号两边可以都带上单位:
.col {
width: 960px / 10px + 3px;
}
编译后css:
.col{
width: 99px;}
可见,除法符号两边可以都带上单位。这个之所以最后的结果也是带单位的(99px),有可能是,960px/10px = 96; 96+3px=99px;也就是说最后的单位是因为加号运算才有的,并不是做了除法以后还有单位。
因为原理上说:
如果两个值带有相同的单位值时,除法运算之后会得到一个不带单位的数值。
实验
——一个正常的除法运算
.box {
width: (1000px / 100px);
}
编译出来的CSS如下:
.box {
width: 10; //没有单位
}
——第一次给除法后边加上加法运算,并给值带上单位
.box {
width: (1000px / 100px) + 1px;
}
编译的css:
.box{
width: 11px;}
——第二次改变单位
.box{
width: (1000px / 100px) + 1em;
}
编译的css
.box{
width: 11em;}
由此可见:确实是因为最后边的加号运算才让结果有了单位,而并不是除法左右带单位结果也带单位。
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;
}
练习题:
计算出每列的列宽
列宽 = 单列宽度 x 列数 + 列间距 x (列数 - 1)
$col-width: 60px;
$col-gap: 20px;
@for $i from 1 through 12 {
.col-#{$i}{
width:$col-width * $i + $col-gap * ($i - 1); //注意符号的中英文切换。
}
}
Sass 中的数学运算——数字运算
数字运算包括前面介绍的:加法、减法、乘法和除法等运算。而且还可以通过括号来修改他们的运算先后顺序。
和我们数学运算是一样的,
示例——一个典型的计算 Grid 单列列宽的运算。
.box {
width: ((220px + 720px) - 11 * 20 ) / 12 ;
}
编译出来的 CSS:
.box {
width: 60px;
}
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;
}
我自己做了个练习,结果有点意外:
p{
color: #030620 + #233525;
}
最后编译的css:
p {
color: #263b45; }
26 和 45 都很正常,3也正常,b从何而来?
06+35 = 41;可以分成 3 11 ;得到3b
那么推测是:11 代表的b
因为颜色值就是0-9 a-f这16个,9完了以后a接到后边,到了b刚好是11;
为了证实这个推测:
把06的6改成5,05+ 35 = 40;
可以想成左右一个数字一个数字地加,左边0+3,右边5+5:可以分成 3 10;得到3a
那么10 代表a
06改成07——42;可以分成3 12;得到3c
12代表c
以此类推...
07改成08——43; 可以分成3 13;得到3d
13代表d
08改成09——44;可以分成3 14;得到3e
14 代表e
接下来,为了得到15,左边09不能再加了,把右边的35改成36,——45; 可以分成3 15;得到3f
15代表f
再把36继续加一,得到40
总结:数值与字母的对应
10-a
11-b
12-c
13-d
14-e
15-f
加上0-9的顺序,a-f就是接到9后边排序了没错。
Sass 中的数学运算——字符运算
同js一样:在 Sass 中可以通过加法符号“+”来对字符串进行连接
$content: "Hello" + "" + "Sass!";
.box:before {
content: " #{$content} ";
}
编译出来的CSS:
.box:before {
content: " Hello Sass! ";
}
注意,如果有引号的字符串被添加了一个没有引号的字符串 (也就是,带引号的字符串在 + 符号左侧), 结果会是一个有引号的字符串。
同样的,如果一个没有引号的字符串被添加了一个有引号的字符串 (没有引号的字符串在 + 符号左侧), 结果将是一个没有引号的字符串。
例如:
p:before {
content: "Foo " + Bar;
font-family: sans- + "serif";
}
编译出来的 CSS:
p:before {
content: "Foo Bar";
font-family: sans-serif; }
完2017-06-21 23:12:24
整整一天,24小时。
最后整理出来一份大纲,是基础篇的,主要是sass的特性: