Sass 入门
一.Sass是什么?
Sass是一款强化CSS的辅助工具,它在CSS语法的基础上增加了变量,嵌套,混合,导入等高级功能.
Sass是一种动态的CSS(CSS预处理器),它扩展了CSS语法,定义了一套新的语法规则和函数,以加强和提升CSS
二.语法格式
1.语法格式
Sass有两种语法格式,一个是Sass语法格式,另一种是Scss语法格式,是Sass 3 引入的新语法
-
(1) Sass语法格式,被称为缩进格式,是一种简化格式,以严格的缩进式语法规则来书写,不带
大括号{}
和分号;
-
(2) Scss是Sass 3引入的新语法,其语法完全兼容CSS3,并且继承了Sass的强大功能,和我们写CSS语法书写方式非常类似
一般我们推荐使用Scss语法,语法要求并没有那么严格
Sass语法:
body
background-color: red
font-size:16px
Scss语法:
body{
background-color:red;
font-size:16px;
}
通常情况下,这两套语法我们通过.sass和.scss两个文件扩展名区分开来
PS:浏览器不认识Sass,需要编译成CSS文件!!!
此外,仍然可以在Sass中写普通的CSS语法
2.编译Sass
官网中介绍,编译Sass,需要安装Ruby,才能使用它的命令行编译,我这里不做介绍,也不打算使用命令行编译.
Sass编译有很多种方式
- 命令行编译模式()
sublime
插件SASS-Build
- 编译软件
koala
安装链接 - 前端自动化软件
codekit
Grunt
打造前端自动化工作流grunt-sass
Gulp
打造前端自动化工作流gulp-sass
webpack
配置style-loader,css-loader,sass-loader
3.编译配置选项(输出格式)
Sass内置有四种编译格式:nested,expanded,compact,compressed
1.未编译的样式
.box {
width: 300px;
height: 400px;
&-title {
height: 30px;
line-height: 30px;
}
}
2.nested 编译排版格式(嵌套的)
/*命令行内容*/
sass style.scss:style.css --style nested
/*编译过后样式*/
.box {
width: 300px;
height: 400px; }
.box-title {
height: 30px;
line-height: 30px; }
3.expanded编译排版格式(展开的)
/*命令行内容*/
sass style.scss:style.css --style expanded
/*编译过后样式*/
.box {
width: 300px;
height: 400px;
}
.box-title {
height: 30px;
line-height: 30px;
}
4.compact编译排版格式(紧凑的)
/*命令行内容*/
sass style.scss:style.css --style compact
/*编译过后样式*/
.box { width: 300px; height: 400px; }
.box-title { height: 30px; line-height: 30px; }
5.compressed 编译排版格式(压缩的)
/*命令行内容*/
sass style.scss:style.css --style compressed
/*编译过后样式*/
.box{width:300px;height:400px}.box-title{height:30px;line-height:30px}
4.注释
Sass支持标准的CSS多行注释/* */
以及单行注释//,还有强制注释
三种注释区别:
注释类型 | 描述 |
---|---|
多行注释/* */ | 会在编译成的css文件中存在,但是不会在压缩版本里存在 |
单行注释// | 不会在编译成的css文件中存在 |
强制注释/*! */ | 任何版本中都会存在 |
三.Scss
1.变量
sass使用$符号
来标识变量
$nav-color: #F90;
$width: 100px;
nav {
width: $width;
color: $nav-color;
}
//编译后
nav {
width: 100px;
color: #F90;
}
变量作用域
- 局部变量:定义在选择器之内的变量,使用范围是该选择器与子选择器
- 全局变量:定义在选择器之外的变量,子选择中也定义了同名变量,则会覆盖全局变量
1.普通变量
//普通变量
$fontSize: 20px;
$fontSize: 12px;
body{
font-size: $fontSize;
}
2.默认变量
变量的结尾添加!default可以指定默认值,此时,如果变量已经被赋值,不会再重新赋值,如果变量未被赋值,则会被赋予新的值
//默认变量
$color: blue;
$color: orange !default;
#div1{
background-color: $color;
}
//编译后
#div1{
background-color: blue;
}
3.全局变量
$color: red; //全局变量
#div1{
background-color: $color;
.box{
color: $color;
}
em{
$color: orange; //局部变量
background-color: $color;
}
.box2{
color: $color;
}
}
还有一种,通过!global
定义全局变量
#div2{
background-color: $color;
.box{
color: $color;
}
em{
$color: orange !global; //全局变量
background-color: $color;
}
.box2{
color: $color;
}
}
局部变量转换为全局变量可以添加 !global
4.特殊变量
字符串拼接的方法
$dirction: top;
$basefontSize: 16px;
$baseLineHeight: 1.5;
#div3{
border-#{$dirction}: 1px solid black;
}
body{
font: #{$basefontSize}/#{$baseLineHeight};
}
2.选择器嵌套
Sass允许将一套CSS样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器,避免了重复输入父选择器
对我们开发CSS,写页面样式,最有用的就是这个选择器嵌套,使用它,我们可以不用去管不同权重的CSS样式,写法可以跟html层级结构布局一样,去编写CSS样式
#box{
width:100px;
height:100px;
h1{
text-align:center;
}
span{
font-size:16px;
a{
color:blue
}
}
}
//编译后
#box {
width: 100px;
height: 100px;
}
#box h1 {
text-align: center;
}
#box span {
font-size: 16px;
}
#box span a {
color: blue;
}
另外,我们使用嵌套外层的父选择器时,还可以简写父选择器:使用&标识符
,设定hover或者伪类元素非常有用
a {
background-color:red;
&:hover{
font-size:60px;
}
}
//编译后
a {
background-color: red;
}
a:hover {
font-size: 60px;
}
3.属性嵌套
有些CSS属性遵循相同的命名空间,比如font-family,font-size,font-weight都以font作为属性的命名空间,为了便于管理这样的属性,同时也为了避免重复输入,Sass允许将属性嵌套在命名空间中
//编译前
.mk-cell {
background: #fff;
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
//编译后
.mk-cell {
background: #fff;
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}
4.@import导入样式
CSS
有一个特别不常用的特性,即@import ur
l规则,它允许在一个css
文件中导入其他css
文件,页面打开时,link
引用的css文件被加载,而@import
引用的CSS等页面加载完DOM
之后再加载
1.扩展link和@import区别
CSS引入外部样式表有两种方式,分别是通过link
和 @import
第一种
<link rel="stylesheet" href="css/style.css" />-->
第二种
<style type="text/css">
@import url("css/style.css");
</style>
二者区别:
- (1) 源头的差别:
link
属于xhtml
标签,而@import
完全是css
提供的一种方式,link
除了加载css
外,还可以做很多其他的事情,如定义RSS
,定义rel
连接属性,@import
只能加载CSS
- (2) 加载顺序的差别: 当页面被加载的时候,
link
引用的css
会同时被加载,而@import
引用的css
会等到页面全部加载(DOM
)才加载,所以有时候会打开页面,发现没有样式的页面 - (3) 兼容性的差别:
@import
是CSS2.1
提出的,老的浏览器不支持,@import
只在IE5
以上才支持,而link
标签,没有此问题 - (4) 使用
dom
控制样式时的差别: 当使用javascript
控制dom
去改变样式的时候,只能使用link
标签,@import
控制不到
2.sass中的@import
sass也有一个@import规则,但不同的是,sass的@improt规则在生成css文件时,就把相关文件导入进来.
@import "reset",
这条命令将reset.scss
文件中所有样式添加到当前样式表中
一般用来导入公共样式!!!
1.全局导入
/ a.scss
$width : 100px;
.before {
width: $width;
}
@import "b";
.after {
width: $width;
}
.container {
width: $width;
height: $height;
border: 1px solid;
}
// b.scss
$width : 200px;
$height : 200px
-----------------------------------分割线----------------------------------
编译后
// a.css
.before {
width: 100px;
}
.after {
width: 200px;
}
.container {
width: 200px;
height: 200px;
border: 1px solid;
}
2.局部导入
// bgblue.scss
aside {
background: blue;
color: white;
}
.bluebox {
@import "bgblue"
}
//生成的结果
.bluebox {
aside {
background: blue;
color: #fff;
}
}
5.混合器(宏) @mixin
混合器@mixin 用于定义可重复使用的样式,避免了使用无语义的class,混合器可以包含所有CSS规则,绝大部分的Sass规则,甚至通过参数功能引入变量,输出多样化的样式
1.mixin的定义和使用
- 混合器的用法是在@mixin后添加名称与样式
- 使用@include指令引用混合样式,格式是在其后添加混合名称,以及需要的参数(可选)
@mixin no-bullets {
list-style: none;
li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
}
ul.plain {
color: #444;
@include no-bullets;
}
// 编译后:
ul.plain {
color: #444;
list-style: none;
}
ul.plain li {
list-style-image: none;
list-style-type: none;
margin-left: 0px;
}
2.混合器传参
1.无参数
//清除浮动
@mixin clearBoth {
content: "";
height: 0;
clear: both;
display: block;
overflow: hidden;
visibility: hidden;
}
#div5{
li{
@include clearBoth;
}
}
2.普通传参
//有传递的参数时加上括号,在括号中传参
@mixin ellipsis($line) {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: $line;
}
.block{
@include ellipsis(2)
}
3.混合关键词传参
//编译前
@mixin button-variant($color, $background, $border) {
color: $color;
border: 1px solid $border;
background-color: $background;
}
.block{
@include button-variant( $background:#fff,$color:red, $border:red)
}
//编译后
.block {
color: red;
border: 1px solid red;
background-color: #fff;
}
4.混合参数变量(不定参传参)
//编译前
@mixin box-shadow($shadows...) {
-moz-box-shadow: $shadows;
-webkit-box-shadow: $shadows;
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
//编译后
.shadowed {
-moz-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
-webkit-box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}
5.默认值传参
@mixin xxx($border: 1px dashed black, $padding: 20px) {
border-bottom: $border;
padding-left: $padding;
padding-right: $padding;
}
#div2{
@include xxx();
}
6.继承@extend
将重复使用的样式继承到使用继承语句的样式中
,可以使用选择器来精简CSS
.alert{
font-size: 12px;
a{
text-decoration: none;
&:hover{
color: blue;
}
}
}
继承,不但会继承.alert这个选择器本身的样式,还会继承所有子选择器的样式
.alert-success{
//先去继承上面.alert的所有样式
@extend .alert;
background-color: greenyellow;
}
.alert-danger{
//先去继承上面.alert的所有样式
@extend .alert;
background-color: red;
}
7.颜色函数
$color要改变的颜色,$amount取值范围是0~100%
lighten($color, $amount) //颜色变浅函数;
darken($color, $amount) //颜色变深函数;
saturate($color, $amount) //增加颜色的饱和度;
desaturate($color, $amount) //减少颜色的饱和度;
grayscale($color) //将该颜色转换为相对应的灰度颜色;
complement($color) //获取该颜色值旋转180度后相对应的颜色;
8.@if 判断指令
可以判断使用哪个主题
$theme: xxx;
body{
@if $theme == dark{
background-color: black;
}@else if $theme == light{
background-color: white;
}@else{
background-color: gray;
}
}
当 @if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
// 编译为
p {
border: 1px solid;
}
9.@for循环指令
@for 这个指令包含两种格式:@for var from to ,区别就是through包含end值,to不包含end值, 和 必须是整数值;来通过Layout 布局来分析该指令的用法
1.for循环
// @for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。
@for $i from 1 through 3 {//循环三次
.item-#{$i} { width: 2em * $i; }
}
或者
@for $i from 1 to 4 {//循环三次
.item-#{$i} { width: 2em * $i; }
}
// 编译为
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
再来个例子
//for语句 栅格系统
$count: 12;
@for $i from 1 through $count{ //包含结束位置
.col-lg-#{$i}{
width: 100% / $count * $i;
}
}
@for $i from 1 to $count{ //不包含结束位置
.col-md-#{$i}{
width: 100% / $count * $i;
}
}
2.each循环
$icons: success danger warning info primary;
@each $icon in $icons {
.icon-#{$icon}{
background: url(./images/#{$icon}.png);
}
}
//编译前
@each $var in add edit delete check {
.#{$var}-icon {
background-image: url('/images/#{$var}.png');
}
}
//编译后
.add-icon {
background-image: url("/images/add.png");
}
.edit-icon {
background-image: url("/images/edit.png");
}
.delete-icon {
background-image: url("/images/delete.png");
}
.check-icon {
background-image: url("/images/check.png");
}
3.while循环
$num: 6;
@while $num > 0{
.item-#{$num}{
width: 2em * $num;
$num: $num - 1;
}
}
10.@function指令
Sass支持自定义函数,并能在任何属性值或Sass script中使用:
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar { width: grid-width(5); }
@function double($n) {
@return $n * 2;
}
#sidebar {
width: double(5px);
}
四.扩展Sass和Less的区别
面试中经常会问到的,Sass和Less的区别?
(1) Less
在JS
上运行,Sass
在Ruby
上使用
(2) 编写变量的方式不同,Sass
使用$,而Less
使用@
(3) Sass可以输出特定的格式,Less没有输出格式
(4) Sass功能更强大
- 有变量和作用域
- 变量有全局和局部之分
- 有函数的概念
- 还有判断指令和循环指令
(5) Less和Sass处理机制不一样,Less是通过客户端处理的,Sass是通过服务端处理的,相比较之下,Less会比Sass解析起来会慢一点