CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作
通俗的说,CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用
CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性
它可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处
CSS 预处理器技术已经非常的成熟,而且也涌现出了很多种不同的 CSS 预处理器语言,比如说:
如此之多的 CSS 预处理器,那么“我应该选择哪种 CSS 预处理器?”也相应成了最近网上的一大热门话题
在 Linkedin、Twitter、CSS-Trick、知乎以及各大技术论坛上,很多人为此争论不休
相比过去我们对是否应该使用 CSS 预处理器的话题而言,这已经是很大的进步了
到目前为止,在众多优秀的 CSS 预处理器语言中就属 Sass、LESS 和 Stylus 最优秀,讨论的也多,对比的也多
Sass 是一门高于 CSS 的元语言,它能用来清晰地、结构化地描述文件样式 有着比普通 CSS 更加强大的功能 Sass
能够提供更简洁、更优雅的语法,同时提供多种功能来创建可维护和管理的样式表
Sass 是最早的 CSS 预处理语言,有比 LESS 更为强大的功能,不过其一开始的缩进式语法(Sass 老版本语法,后面课程会详细介绍 )并不能被大众接受,不过由于其强大的功能和 Ruby on Rails 的大力推动,还是有很多开发者选择了 Sass
Sass 是采用 Ruby 语言编写的一款 CSS 预处理语言,它诞生于2007年,是最大的成熟的 CSS 预处理语言。最初它是为了配合 HAML(一种缩进式 HTML 预编译器)而设计的,因此有着和 HTML 一样的缩进式风格
虽然缩进式风格可以有效缩减代码量,强制规范编码风格,但它一方面并不为大多数程序接受,另一方面无法兼容已有的 CSS 代码。这也是 Sass 虽然出现得最早,但远不如 LESS 普及的原因
gem install sass
sass -v
检查gem update sass
更新gem uninstall sass
卸载Sass 和 SCSS 其实是同一种东西,我们平时都称之为 Sass,两者之间不同之处有以下两点:
.sass
后缀为扩展名,而 SCSS 是以.scss
后缀为扩展名{}
和分号;
,而 SCSS 的语法书写和我们的 CSS 语法书写方式非常类似示例:
Sass 语法
$font-stack: Helvetica, sans-serif //定义变量
$primary-color: #333 //定义变量
body
font: 100% $font-stack
color: $primary-color
Scss 语法
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
body {
font: 100% $font-stack;
color: $primary-color;
}
编译出来的 CSS
body {
font: 100% Helvetica, sans-serif;
color: #333;
}
在项目中还是引用.css
文件,Sass 做为一个预处理工具,提前帮你做事情,只有你需要时候,他才有功效
Sass 开发之后,要让 Web 页面能调用 Sass 写好的东西,得有一个过程
这个过程就称之为 Sass 编译过程
Sass 的编译有多种方法:
由于时间问题后两种我没有学习.今后可能补上.(也可能不会.)
单文件编译:
sass :
多文件编译:
sass :
watch实时编译:
sass --watch :
单文件和多文件都可以
假设我们有一段 Sass 代码
nav {
ul{
margin: 0;
}
li{
margin: 0;
}
}
编译时带上参数--style nested
sass : --style nested
编译后的 CSS
nav ul {
margin: 0;}
nav li {
margin: 0; }
编译时带上参数--style expanded
sass : --style expanded
编译后的 CSS
nav ul {
margin: 0;
}
nav li {
margin: 0;
}
是的,nested
与expanded
区别只是大括号起在另一行(我个人喜好这种.)
编译时带上参数--style compact
sass : --style compact
编译后的 CSS
nav ul { margin: 0; }
nav li { margin: 0; }
compact
将每种样式各输出在一行
编译时带上参数--style compressed
sass : --style compressed
编译后的 CSS
nav ul{margin: 0;}nav li{margin: 0;}
compressed
会去掉所有的样式,这种方式是最节省的(文件最小)
但是我个人并不会这么做…没有必要为几K大小降低可读性…
3.3版本之上的 Sass 自带调试功能 不需要再填写参数
Sass 中变量的声明符与 php 相同,都是象征美元的$
符
赋值符则与 CSS 相同,为:
$变量名 : 变量值;
Sass 的默认变量仅需在值后加上!default
即可
$a : red !defaulf;
定义在元素外的变量就是全局变量
$a = red;
.box{
color:$a;
}
如上例子,a为全局变量
定义在元素内部的变量则为局部变量
.box{
$a = red;
color:$a;
}
局部变量只会在局部范围内覆盖全局变量,不会影响全局变量的值
$color: orange;//定义全局变量
.block {
color: $color;//调用全局变量
}
em {
$color: red;//定义局部变量
a {
color: $color;//调用局部变量
}
}
假设我们有一段这样的结构:
<header>
<nav>
<a href=“##”>Homea>
<a href=“##”>Abouta>
<a href=“##”>Bloga>
nav>
<header>
想选中 header 中的 a 标签,在写 CSS 会这样写:
nav a {
color:red;
}
header nav a {
color:green;
}
那么在 Sass 中,就可以使用选择器的嵌套来实现:
nav {
a {
color: red;
header & {
color:green;
}
}
}
CSS 有一些属性前缀相同,只是后缀不一样
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
在 Sass 中我们可以这样写:
.box {
border: {
top: 1px solid red;
bottom: 1px solid green;
}
}
其实伪类嵌套和属性嵌套非常类似,只不过他需要借助&
符号一起配合使用。我们就拿经典的“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中,使用@mixin
来声明混合宏
@mixin 混合宏名称{
-webkit-border-radius: 5px;
border-radius: 5px;
}
带参数混合宏:
@mixin 混合宏名称($redius){
-webkit-border-radius: $redius;
border-radius: $redius;
}
带默认参数混合宏:
@mixin 混合宏名称($redius:5px){
-webkit-border-radius: $redius;
border-radius: $redius;
}
复杂的混合宏:
@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);
}
}
Sass 中通过@include
来调用混合宏
button{
@include 混合宏名称;
}
带参数
button{
@include 混合宏名称(参数);
}
如果混合宏有默认参数,传递参数会覆盖默认参数
当混合宏传的参数过多时,可以使用...
来替代
@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 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 中是通过关键词 @extend
来继承已存在的类样式块,从而实现代码的继承
.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;
}
编译出来之后:
.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 中的占位符%
功能是一个很强大,很实用的一个功能,因为%
声明的代码,如果不被@extend
调用的话,不会产生任何代码
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
这段代码没有被 @extend
调用,他并没有产生任何代码块,只是静静的躺在你的某个 SCSS 文件中,只有通过 @extend
调用才会产生代码:
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
.btn {
@extend %mt5;
@extend %pt5;
}
.block {
@extend %mt5;
span {
@extend %pt5;
}
}
编译出来的CSS
.btn, .block {
margin-top: 5px;
}
.btn, .block span {
padding-top: 5px;
}
@extend
调用的占位符,编译出来的代码会将相同的代码合并在一起使用 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;
}
这是 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; }
#{}
语法不能在mixin
中调用
注释对于一名程序员来说,是极其重要,良好的注释能帮助自己或者别人阅读源码
在 Sass 中注释有两种方式,我暂且将其命名为:
/*
开头,结属使用 */
//
两者区别,前者会在编译出来的 CSS 显示,后者在编译出来的 CSS 中不会显示,来看一个示例:
//定义一个占位符
%mt5 {
margin-top: 5px;
}
/*调用一个占位符*/
.box {
@extend %mt5;
}
编译出来的CSS
.box {
margin-top: 5px;
}
/*调用一个占位符*/
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)
SassScript 支持 CSS 的两种字符串类型:
"Lucida Grande"
'http://sass-lang.com'
sans-serifbold
在编译 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!"; }
所谓值列表 lists
是指 Sass 如何处理 CSS 中:
margin: 10px 15px 0 0
或者:
font-face: Helvetica, Arial, sans-serif
像上面这样通过空格
或者逗号
分隔的一系列的值
事实上,独立的值也被视为值列表——只包含一个值的值列表
Sass列表函数 Sass list functions
赋予了值列表更多功能:
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 null 3px
程序中的运算是常见的一件事情,但在 CSS 中能做运算的,到目前为止仅有 calc()
函数可行
但在 Sass 中,运算只是其基本特性之一
在 Sass 中可以做各种数学计算
加法运算是 Sass 中运算中的一种,在变量或属性中都可以做加法运算
.box {
width: 20px + 8in;
}
编译出来的 CSS:
.box {
width: 788px;
}
但对于携带不同类型的单位时,在 Sass 中计算会报错,如下例所示:
.box {
width: 20px + 1em;
}
编译的时候,编译器会报错:"Incompatible units: 'em' and 'px'."
Sass 的减法运算和加法运算类似,我们通过一个简单的示例来做阐述:
$full-width: 960px;
$sidebar-width: 200px;
.content {
width: $full-width - $sidebar-width;
}
编译出来的 CSS 如下:
.content {
width: 760px;
}
同样的,运算时碰到不同类型的单位时,编译也会报错
Sass 中的乘法运算和前面介绍的加法与减法运算还略有不同
虽然他也能够支持多种单位(比如 em ,px , %),但当一个单位同时声明两个值时会有问题
.box {
width:10px * 2px;
}
编译的时候报"20px*px isn't a valid CSS value."
错误信息。
如果进行乘法运算时,两个值单位相同时,只需要为一个数值提供单位即可。上面的示例可以修改成:
.box {
width: 10px * 2;
}
编译出来的 CSS:
.box {
width: 20px;
}
同样的,运算时碰到不同类型的单位时,编译也会报错
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 的数学运算功能变得更加实用
一起来看一个简单的示例:
$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 运算中数字运算是较为常见的,数字运算包括前面介绍的:加法、减法、乘法和除法等运算
而且还可以通过括号来修改他们的运算先后顺序
和我们数学运算是一样的,一起来看个示例:
.box {
width: ((220px + 720px) - 11 * 20 ) / 12 ;
}
编译出来的 CSS:
.box {
width: 60px;
}
上面这个简单示例是一个典型的计算 Grid
单列列宽的运算
所有算数运算都支持颜色值,并且是分段运算的
也就是说,红、绿和蓝各颜色分段单独进行运算
如:
p {
color: #010203 + #040506;
}
计算公式为 01 + 04 = 05
02 + 05 = 07
03 + 06 = 09
并且被合成为:
p {
color: #050709;
}
算数运算也能将数字和颜色值 一起运算,同样也是分段运算的。如:
p {
color: #010203 * 2;
}
计算公式为01 * 2 = 02
02 * 2 = 04
03 * 2 = 06
并且被合成为:
p {
color: #020406;
}
在 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; }
@if
指令是一个 SassScript
,它可以根据条件来处理样式块,如果条件为 true 返回一个样式块,反之 false 返回另一个样式块
在 Sass 中除了 @if
之,还可以配合 @else if
和 @else
一起使用
假设要控制一个元素隐藏或显示,我们就可以定义一个混合宏,通过 @if...@else...
来判断传进参数的值来控制 display 的值
如下所示:
//SCSS
@mixin blockOrHidden($boolean:true) {
@if $boolean {
display: block;
}
@else {
display: none;
}
}
.block {
@include blockOrHidden;
}
.hidden{
@include blockOrHidden(false);
}
编译出来的CSS:
.block {
display: block;
}
.hidden {
display: none;
}
在制作网格系统的时候,大家应该对 .col1~.col12
这样的印象较深
在 CSS 中你需要一个一个去书写,但在 Sass 中,可以使用 @for
循环来完成
在 Sass 的 @for
循环中有两种方式:
@for $i from through
@for $i from to
$i
表示变量start
表示起始值end
表示结束值这两个的区别是关键字 through
表示包括
end 这个数,而 to
则不包括
end 这个数。
如下代码,先来个使用 through
关键字的例子:
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
编译出来的 CSS:
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
再来个 to
关键字的例子:
@for $i from 1 to 3 {
.item-#{$i} { width: 2em * $i; }
}
编译出来的 CSS:
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
@for
应用在网格系统生成各个格子 class 的代码:
//SCSS
$grid-prefix: span !default;
$grid-width: 60px !default;
$grid-gutter: 20px !default;
%grid {
float: left;
margin-left: $grid-gutter / 2;
margin-right: $grid-gutter / 2;
}
@for $i from 1 through 12 {
.#{$grid-prefix}#{$i}{
width: $grid-width * $i + $grid-gutter * ($i - 1);
@extend %grid;
}
}
编译出来的 CSS:
.span1, .span2, .span3, .span4, .span5, .span6, .span7, .span8, .span9, .span10, .span11, .span12 {
float: left;
margin-left: 10px;
margin-right: 10px;
}
.span1 {
width: 60px;
}
.span2 {
width: 140px;
}
.span3 {
width: 220px;
}
.span4 {
width: 300px;
}
.span5 {
width: 380px;
}
.span6 {
width: 460px;
}
.span7 {
width: 540px;
}
.span8 {
width: 620px;
}
.span9 {
width: 700px;
}
.span10 {
width: 780px;
}
.span11 {
width: 860px;
}
.span12 {
width: 940px;
}
将上面的示例稍做修改,将 @for through
方式换成 @for to
:
//SCSS
@for $i from 1 to 13 {
.#{$grid-prefix}#{$i}{
width: $grid-width * $i + $grid-gutter * ($i - 1);
@extend %grid;
}
}
其最终编译出来的 CSS 代码和上例所编译出来的一模一样。
这两段 Sass 代码并无太多差别,只是 @for
中的 取值不同。配合 through
的 值是 12,其遍历出来的终点值也是 12,和 值一样。配合 to
的 值是 13,其遍历出来的终点值是 12,就是 对就的值减去 1
@while
指令也需要 SassScript 表达式(像其他指令一样),并且会生成不同的样式块,直到表达式值为 false 时停止循环
这个和 @for
指令很相似,只要 @while
后面的条件为 true 就会执行
这里有一个 @while
指令的简单用例:
//SCSS
$types: 4;
$type-width: 20px;
@while $types > 0 {
.while-#{$types} {
width: $type-width + $types;
}
$types: $types - 1;
}
编译出来的 CSS
.while-4 {
width: 24px;
}
.while-3 {
width: 23px;
}
.while-2 {
width: 22px;
}
.while-1 {
width: 21px;
}
@each
循环就是去遍历一个列表,然后从列表中取出对应的值
@each
循环指令的形式:
@each $var in
如果你没有接触过列表,也不要紧,他也非常简单
在下面的例子中你可以看到,$var 就是一个变量名, 是一个 SassScript 表达式,他将返回一个列表值
变量 $var 会在列表中做遍历,并且遍历出与 $var 对应的样式块
这有一个 @each
指令的简单示例:
$list: adam john wynn mason kuroir;//$list 就是一个列表
@mixin author-images {
@each $author in $list {
.photo-#{$author} {
background: url("/images/avatars/#{$author}.png") no-repeat;
}
}
}
.author-bio {
@include author-images;
}
编译出 CSS:
.author-bio .photo-adam {
background: url("/images/avatars/adam.png") no-repeat; }
.author-bio .photo-john {
background: url("/images/avatars/john.png") no-repeat; }
.author-bio .photo-wynn {
background: url("/images/avatars/wynn.png") no-repeat; }
.author-bio .photo-mason {
background: url("/images/avatars/mason.png") no-repeat; }
.author-bio .photo-kuroir {
background: url("/images/avatars/kuroir.png") no-repeat; }
在 Sass 中除了可以定义变量,具有 @extend
%placeholder
mixins
等特性之外,还自备了一系列的函数功能
其主要包括:
当然除了自备的函数功能之外,我们还可以根据自己的需求定义函数功能,常常称之为自定义函数
字符串函数顾名思意是用来处理字符串的函数
Sass 的字符串函数主要包括两个函数:
unquote($string):删除字符串中的引号
quote($string):给字符串添加引号
unquote()
函数主要是用来删除一个字符串中的引号,如果这个字符串没有带有引号,将返回原始的字符串
简单的使用终端来测试这个函数的运行结果:
//SCSS
.test1 {
content: unquote('Hello Sass!') ;
}
.test2 {
content: unquote("'Hello Sass!");
}
.test3 {
content: unquote("I'm Web Designer");
}
.test4 {
content: unquote("'Hello Sass!'");
}
.test5 {
content: unquote('"Hello Sass!"');
}
.test6 {
content: unquote(Hello Sass);
}
编译后的 css 代码:
//CSS
.test1 {
content: Hello Sass!; }
.test2 {
content: 'Hello Sass!; }
.test3 {
content: I'm Web Designer; }
.test4 {
content: 'Hello Sass!'; }
.test5 {
content: "Hello Sass!"; }
.test6 {
content: Hello Sass; }
注意:从测试的效果中可以看出,unquote( )
函数只能删除字符串最前和最后的引号(双引号或单引号),而无法删除字符串中间的引号
如果字符没有带引号,返回的将是字符串本身
quote()
函数刚好与 unquote()
函数功能相反,主要用来给字符串添加引号
如果字符串,自身带有引号会统一换成双引号 ""
如:
//SCSS
.test1 {
content: quote('Hello Sass!');
}
.test2 {
content: quote("Hello Sass!");
}
.test3 {
content: quote(ImWebDesigner);
}
.test4 {
content: quote(' ');
}
编译出来的 css 代码:
//CSS
.test1 {
content: "Hello Sass!";
}
.test2 {
content: "Hello Sass!";
}
.test3 {
content: "ImWebDesigner";
}
.test4 {
content: "";
}
使用 quote()
函数只能给字符串增加双引号,而且字符串中间有单引号或者空格时,需要用单引号或双引号括起,否则编译的时候将会报错
.test1 {
content: quote(Hello Sass);
}
这样使用,编译器马上会报错:
error style.scss (Line 13: $string: ("Hello""Sass") is not a string for `quote')
解决方案就是去掉空格,或者加上引号:
.test1 {
content: quote(HelloSass);
}
.test1 {
content: quote("Hello Sass");
}
同时 quote()
碰到特殊符号,比如: !
?
>
等,除中折号 -
和 下划线_
都需要使用双引号括起,否则编译器在进行编译的时候同样会报错:
error style.scss (Line 13: Invalid CSS after "...quote(HelloSass": expected ")", was "!);")
error style.scss (Line 16: Invalid CSS after "...t: quote(Hello": expected ")", was “?);")
To-upper-case()
函数将字符串小写字母转换成大写字母
如:
//SCSS
.test {
text: to-upper-case(aaaaa);
text: to-upper-case(aA-aAAA-aaa);
}
编译出来的 css 代码:
//CSS
.test {
text: AAAAA;
text: AA-AAAA-AAA;
}
To-lower-case()
函数 与 To-upper-case()
刚好相反,将字符串转换成小写字母:
//SCSS
.test {
text: to-lower-case(AAAAA);
text: to-lower-case(aA-aAAA-aaa);
}
编译出来的 css 代码:
//CSS
.test {
text: aaaaa;
text: aa-aaaa-aaa;
}
Sass 中的数字函数提要针对数字方面提供一系列的函数功能:
percentage($value)
:将一个不带单位的数转换成百分比值;round($value)
:将数值四舍五入,转换成一个最接近的整数;ceil($value)
:将大于自己的小数转换成下一位整数;floor($value)
:将一个数去除他的小数部分;abs($value)
:返回一个数的绝对值;min($numbers…)
:找出几个数值之间的最小值;max($numbers…)
:找出几个数值之间的最大值;random()
: 获取随机数percentage()
函数主要是将一个不带单位的数字转换成百分比形式:
>> percentage(.2)
20%
>> percentage(2px / 10px)
20%
>> percentage(2em / 10em)
20%
>>
.footer{
width : percentage(.2)
}
编译后的 css 代码:
.footer{
width : 20%
}
如果您转换的值是一个带有单位的值,那么在编译的时候会报错误信息:
>> percentage(2px / 10em)
SyntaxError: $value: 0.2px/em is not a unitless number for `percentage'
round()
函数可以将一个数四舍五入为一个最接近的整数:
>> round(12.3)
12
>> round(12.5)
13
>> round(1.49999)
1
>> round(2.0)
2
>> round(20%)
20%
>> round(2.2%)
2%
>> round(3.9em)
4em
>> round(2.3px)
2px
>> round(2px / 3px)
1
>> round(1px / 3px)
0
>> round(3px / 2em)
2px/em
.footer {
width:round(12.3px)
}
编译后的 css 代码:
.footer {
width: 12px;
}
在 round()
函数中可以携带单位的任何数值
ceil()
函数将一个数转换成最接近于自己的整数,会将一个大于自身的任何小数转换成大于本身 1 的整数
也就是只做入,不做舍的计算:
>> ceil(2.0)
2
>> ceil(2.1)
3
>> ceil(2.6)
3
>> ceil(2.3%)
3%
>> ceil(2.3px)
3px
>> ceil(2.5px)
3px
>> ceil(2px / 3px)
1
>> ceil(2% / 3px)
1%/px
>> ceil(1em / 5px)
1em/px
.footer {
width:ceil(12.3px);
}
编译后的 css 代码:
.footer {
width: 13px;
}
floor()
函数刚好与 ceil()
函数功能相反,其主要将一个数去除其小数部分,并且不做任何的进位
也就是只做舍,不做入的计算:
>> floor(2.1)
2
>> floor(2.5)
2
>> floor(3.5%)
3%
>> floor(10.2px)
10px
>> floor(10.8em)
10em
>> floor(2px / 10px)
0
>> floor(3px / 1em)
3px/em
.footer {
width:floor(12.3px);
}
编译后的 css 代码:
.footer {
width: 12px;
}
abs( )
函数会返回一个数的绝对值。
>> abs(10)
10
>> abs(-10)
10
>> abs(-10px)
10px
>> abs(-2em)
2em
>> abs(-.5%)
0.5%
>> abs(-1px / 2px)
0.5
.footer {
width:abs(-12.3px);
}
编译后的 css 代码:
.footer {
width: 12.3px;
}
min()
函数功能主要是在多个数之中找到最小的一个,这个函数可以设置任意多个参数:
>> min(1,2,1%,3,300%)
1%
>> min(1px,2,3px)
1px
>> min(1em,2em,6em)
1em
不过在 min()
函数中同时出现两种不同类型的单位,将会报错误信息:
>> min(1px,1em)
SyntaxError: Incompatible units: 'em' and 'px'.
max()
函数和 min()
函数一样,不同的是,max()
函数用来获取一系列数中的最大那个值:
>> max(1,5)
5
>> max(1px,5px)
5px
同样的,如果在 max()
函数中有不同单位,将会报错:
>> max(1,3px,5%,6)
SyntaxError: Incompatible units: '%' and ‘px'.
random()
函数是用来获取一个随机数:
>> random()
0.03886
>> random()
0.66527
>> random()
0.8125
>> random()
0.26839
>> random()
0.85063
列表函数主要包括一些对列表参数的函数使用,主要包括以下几种:
length($list)
:返回一个列表的长度值;nth($list, $n)
:返回一个列表中指定的某个标签值join($list1, $list2, [$separator])
:将两个列给连接在一起,变成一个列表;append($list1, $val, [$separator])
:将某个值放在列表的最后;zip($lists…)
:将几个列表结合成一个多维的列表;index($list, $value)
:返回一个值在列表中的位置值。length()
函数主要用来返回一个列表中有几个值,简单点说就是返回列表清单中有多少个值:
>> length(10px)
1
>> length(10px 20px (border 1px solid) 2em)
4
>> length(border 1px solid)
3
length()
函数中的列表参数之间使用空格隔开,不能使用逗号,否则函数将会出错:
>> length(10px,20px,(border 1px solid),2em)
SyntaxError: wrong number of arguments (4 for 1) for `length'
>> length(1,2px)
SyntaxError: wrong number of arguments (2 for 1) for `length'
语法:
nth($list,$n)
nth()
函数用来指定列表中某个位置的值
不过在 Sass 中,nth()
函数和其他语言不同
1 是指列表中的第一个标签值,2 是指列给中的第二个标签值,依此类推
如:
>> nth(10px 20px 30px,1)
10px
>> nth((Helvetica,Arial,sans-serif),2)
"Arial"
>> nth((1px solid red) border-top green,1)
(1px "solid" #ff0000)
注:在 nth($list,$n)
函数中的 $n
必须是大于 0 的整数:
>> nth((1px solid red) border-top green 1 ,0)
SyntaxError: List index 0 must be a non-zero integer for `nth'