Scss笔记

文章目录

    • CSS 预处理器语言定义
        • 其它 CSS 预处理器语言
        • 什么是 Sass
            • Sass 官网描述
            • Sass 前世今生
            • Sass 早期不如 LESS 普及
    • Sass 安装(windows版)
    • Sass 语法格式
        • Sass 和 SCSS 的区别
    • Sass 编译
        • Sass 命令编译
        • 常见错误
        • Sass 不同风格样式的输出方法
            • 嵌套输出方式
            • 展开输出方式
            • 紧凑输出方式
            • 压缩输出方式
            • Sass 的调试
    • Sass 变量
        • 默认变量
        • 局部变量与全局变量
    • 嵌套
        • 选择器嵌套
        • 属性嵌套
        • 伪类嵌套
    • 混合宏
        • 声明混合宏
        • 调用混合宏
        • 混合宏的不足
    • Sass 扩展/继承
    • 占位符%
    • 差值#{}
    • 注释
    • 数据类型
      • 字符串
      • 值列表
    • 运算
      • 加法
      • 减法
      • 乘法
      • 除法
      • 变量计算
      • 数字运算
      • 颜色运算
      • 字符运算
    • @if
    • @for
    • @while
    • @each
    • 函数
      • 字符串函数
        • unquote()
        • quote()
      • 字符串函数
        • To-upper-case()
        • To-lower-case()
      • 数字函数
        • percentage()
        • round()
        • ceil()
        • floor()
        • abs()
        • min()
        • max()
        • random()
      • 列表函数
        • length()
        • nth()

CSS 预处理器语言定义

  • CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作

  • 通俗的说,CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供项目使用

  • CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用变量、简单的逻辑程序、函数(如右侧代码编辑器中就使用了变量$color)等等在编程语言中的一些基本特性

  • 它可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处

其它 CSS 预处理器语言

CSS 预处理器技术已经非常的成熟,而且也涌现出了很多种不同的 CSS 预处理器语言,比如说:

  • Sass(SCSS)
  • LESS
  • Stylus
  • Turbine
  • Swithch CSS
  • CSS Cacheer
  • DT CSS

如此之多的 CSS 预处理器,那么“我应该选择哪种 CSS 预处理器?”也相应成了最近网上的一大热门话题

在 Linkedin、Twitter、CSS-Trick、知乎以及各大技术论坛上,很多人为此争论不休

相比过去我们对是否应该使用 CSS 预处理器的话题而言,这已经是很大的进步了

到目前为止,在众多优秀的 CSS 预处理器语言中就属 Sass、LESS 和 Stylus 最优秀,讨论的也多,对比的也多

什么是 Sass

Sass 官网描述

Sass 是一门高于 CSS 的元语言,它能用来清晰地、结构化地描述文件样式 有着比普通 CSS 更加强大的功能 Sass
能够提供更简洁、更优雅的语法,同时提供多种功能来创建可维护和管理的样式表

Sass 前世今生

Sass 是最早的 CSS 预处理语言,有比 LESS 更为强大的功能,不过其一开始的缩进式语法(Sass 老版本语法,后面课程会详细介绍 )并不能被大众接受,不过由于其强大的功能和 Ruby on Rails 的大力推动,还是有很多开发者选择了 Sass

Sass 是采用 Ruby 语言编写的一款 CSS 预处理语言,它诞生于2007年,是最大的成熟的 CSS 预处理语言。最初它是为了配合 HAML(一种缩进式 HTML 预编译器)而设计的,因此有着和 HTML 一样的缩进式风格

Sass 早期不如 LESS 普及

虽然缩进式风格可以有效缩减代码量,强制规范编码风格,但它一方面并不为大多数程序接受,另一方面无法兼容已有的 CSS 代码。这也是 Sass 虽然出现得最早,但远不如 LESS 普及的原因

Sass 安装(windows版)

  • 官网下载安装包
  • 安装时选择部署环境变量Scss笔记_第1张图片
  • 打开电脑终端输入gem install sass
  • 安装后通过sass -v检查
  • 通过gem update sass更新
  • 通过gem uninstall sass卸载

Sass 语法格式

Sass 和 SCSS 的区别

Sass 和 SCSS 其实是同一种东西,我们平时都称之为 Sass,两者之间不同之处有以下两点:

  • 文件扩展名不同,Sass 是以.sass后缀为扩展名,而 SCSS 是以.scss后缀为扩展名
  • 语法书写方式不同,Sass 是以严格的缩进式语法规则来书写,不带大括号{}和分号;,而 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;
}

Sass 编译

在项目中还是引用.css文件,Sass 做为一个预处理工具,提前帮你做事情,只有你需要时候,他才有功效

Sass 开发之后,要让 Web 页面能调用 Sass 写好的东西,得有一个过程

这个过程就称之为 Sass 编译过程

Sass 的编译有多种方法:

  • 命令编译
  • GUI工具编译
  • 自动化编译

由于时间问题后两种我没有学习.今后可能补上.(也可能不会.)

Sass 命令编译

单文件编译:

sass :

多文件编译:

sass :

watch实时编译:

sass --watch :

单文件和多文件都可以

常见错误

  • Sass 编译过程中不支持 GBK 编码,创建 Sass 时就需要将编码设置为 UTF-8
  • 同理,既然不支持 GBK 编码,自然也不支持中文路径

Sass 不同风格样式的输出方法

  • 嵌套输出方式 nested
  • 展开输出方式 expanded
  • 紧凑输出方式 compact
  • 压缩输出方式 compressed

假设我们有一段 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; 
}

是的,nestedexpanded区别只是大括号起在另一行(我个人喜好这种.)

紧凑输出方式

编译时带上参数--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大小降低可读性…

Sass 的调试

3.3版本之上的 Sass 自带调试功能 不需要再填写参数

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 扩展/继承

在 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;
}
  • 从编译出来的 CSS 代码可以看出,通过 @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 中注释有两种方式,我暂且将其命名为:

  1. 类似 CSS 的注释方式,使用 /*开头,结属使用 */
  2. 类似 JavaScript 的注释方式,使用//

两者区别,前者会在编译出来的 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 的两种字符串类型:

  • 有引号字符串 (quoted strings),如 "Lucida Grande" 'http://sass-lang.com'
  • 无引号字符串 (unquoted strings),如 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 2px5px 6px两个值列表的值列表

如果内外两层值列表使用相同的分隔方式,要用圆括号包裹内层,所以也可以写成 (1px 2px) (5px 6px)

当值列表被编译为 CSS 时,Sass 不会添加任何圆括号,因为 CSS 不允许这样做
(1px 2px) (5px 6px)1px 2px 5px 6px在编译后的 CSS 文件中是一样的,但是它们在 Sass 文件中却有不同的意义,前者是包含两个值列表的值列表,而后者是包含四个值的值列表

可以用()表示空的列表,这样不可以直接编译成 CSS,比如编译 font-family: () 时,Sass 将会报错

如果值列表中包含空的值列表或空值,编译时将清除空值,比如 1px 2px () 3px1px 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

@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;
}

@for

在制作网格系统的时候,大家应该对 .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

@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 循环指令的形式:

@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 等特性之外,还自备了一系列的函数功能
其主要包括:

  • 字符串函数
  • 数字函数
  • 列表函数
  • 颜色函数
  • Introspection 函数
  • 三元函数等

当然除了自备的函数功能之外,我们还可以根据自己的需求定义函数功能,常常称之为自定义函数

字符串函数

字符串函数顾名思意是用来处理字符串的函数
Sass 的字符串函数主要包括两个函数:

	unquote($string):删除字符串中的引号
	quote($string):给字符串添加引号

unquote()

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()

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()

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-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() 函数主要是将一个不带单位的数字转换成百分比形式:

>> 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() 函数可以将一个数四舍五入为一个最接近的整数:

>> 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()

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()

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( ) 函数会返回一个数的绝对值。

>> 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() 函数功能主要是在多个数之中找到最小的一个,这个函数可以设置任意多个参数:

>> 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()

max() 函数和 min() 函数一样,不同的是,max() 函数用来获取一系列数中的最大那个值:

>> max(1,5)
5
>> max(1px,5px)
5px

同样的,如果在 max() 函数中有不同单位,将会报错:

>> max(1,3px,5%,6)
SyntaxError: Incompatible units: '%' and ‘px'.

random()

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() 函数主要用来返回一个列表中有几个值,简单点说就是返回列表清单中有多少个值:

>> 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()

语法:
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'

你可能感兴趣的:(css)