sass让人们受益的一个重要特性就是它为css引入了变量。你可以把反复使用的css属性值 定义成变量,然后通过变量名来引用它们,而无需重复书写这一属性值。
# 1、变量声明;【使用$符号】
当变量定义在css规则块内,那么该变量只能在此规则块内使用。如果它们出现在任何形式的{...}块中(如@media或者@font-face块)中时,只能在块内生效。
$highlight-color: #F90; //变量名使用中划线和下划线都行
.login-wrap {
text-align: center;
font-size: 30px;
color:$highlight-color;
border:1px solid $highlight-color
}
$highlight-color: #F90; //可以在login-wrap外的块中使用
.login-wrap {
$width: 30px;
text-align: center;
font-size: $width; //只能在login-wrap块中使用
color:$highlight-color;
}
变量对象
$theme-map:(
$color: red,
$width: 200px;
);
在scss中,对象都是放在 () 圆括号中的,而不是花括号{}中
!default,如果一个变量已经定义,当通过!default赋值时,不会起作用
$content: "First content";
$content: "Second content?" !default;
#main {
content: $content;
}
编译为
#main {
content: "First content"; //还是第一个
}
$content: null;
$content: "Non-null content" !default;
#main {
content: $content;
}
编译为
#main {
content: "Non-null content"; //定义的default值
}
# 2、css嵌套
可以避免重复多次的写父选择器。将嵌套的选择器作为子选择器。
.center{
.title{
font-size: 20px;
font-weight: bold;
}
input{
background-color: gray;
}
}
/* 编译后 */
.center .title {
font-size: 20px;
font-weight: bold;
}
.center input { background-color: gray;}
群组的嵌套
//子元素群组
.container {
h1, h2, h3 {margin-bottom: 10px}
}
编译后
.container h1, .container h2, .container h3 { margin-bottom: 10px }
//父元素群组
nav, aside {
a {color: blue}
}
编译后
nav a, aside a {color: blue}
# 3、父元素的引用
有时并不是让嵌套的作为子原则器,而是父选择器的补充,比如:hover,,此时必须使用 父元素的引用符 &, 此时&代表父元素
.center{
input{
background-color: gray;
}
&:hover{
color:red;
}
}
编译后
.center input{background-color: gray;}
.center:hover{color:red;}
# 4、子组合和同胞选择器的使用 >、+ 和 ~ ;
可以把它们放在==外层选择器后边==,或==里层选择器前边==:
article {
~ article { border-top: 1px dashed #ccc } //里层选择器前面
> section { background: #eee }
dl > { //外层选择器前面
dt { color: #333 }
dd { color: #555 }
}
nav + & { margin-top: 0 }
}
//编译后
article ~ article { border-top: 1px dashed #ccc }
article > footer { background: #eee }
article dl > dt { color: #333 }
article dl > dd { color: #555 }
nav + article { margin-top: 0 }
# 5、混合器
通过变量我们可以对单个css值,定义定义和重用,如果对多个css值,都写变量,显得太麻烦,所以使用混合器一次性定义多个。
通过@mixin定义, 通过@include使用
@mixin rounded-corners {
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
}
.center{
input{
background-color: gray;
@include rounded-corners;
}
}
编译后
.center{
input{
background-color: gray;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
}
}
可以给混合器传参
@mixin rounded-corners($normal) {
-moz-border-radius: $normal;
-webkit-border-radius: $normal;
border-radius: $normal;
}
.center{
input{
background-color: gray;
@include rounded-corners(50%);
}
}
混合器默认参数
$normals: 2px;
@mixin rounded-corners($normal:$normals) {
-moz-border-radius: $normal;
-webkit-border-radius: $normal;
border-radius: $normal;
}
.center{
input{
background-color: gray;
@include rounded-corners();
}
}
向混合样式中导入内容
$normals: 2px;
@mixin rounded-corners($normal:$normals) {
-moz-border-radius: $normal;
-webkit-border-radius: $normal;
@content;
}
.center{
input{
background-color: gray;
@include rounded-corners(){
border-radius: $normal;
};
}
}
@include中的 border-radius: $normal; 会最后合并到 @mixin的@content中 最后编译为
.center{
input{
background-color: gray;
-moz-border-radius: $normal;
-webkit-border-radius: $normal;
border-radius: $normal;
}
}
利用混合器,可以很容易地在样式表的不同地方共享样式。如果你发现自己在不停地重复一段样式,那就应该把这段样式构造成优良的混合器,尤其是这段样式本身就是一个逻辑单元,比如说是一组放在一起有意义的属性。
判断一组属性是否应该组合成一个混合器,一条经验法则就是你能否为这个混合器想出一个好的名字。如果你能找到一个很好的短名字来描述这些属性修饰的样式,比如rounded-cornersfancy-font或者no-bullets,那么往往能够构造一个合适的混合器。如果你找不到,这时候构造一个混合器可能并不合适。
# 6、继承
变量是基于单个 css 属性的,mixin是基于多个css属性的,并且这两个都是同属一个css样式文件才生效
而继承是基于css类的,可以在不同的css文件间使用,既可以给自身的选择器用,也可以给继承的后代选择器用
//1.css
@mixin rounded-corners($normal) {
-moz-border-radius: $normal;
-webkit-border-radius: $normal;
border-radius: $normal;
}
//或者通过其他地方将mixin导入进来
.center{ //可用于class为center的元素
.title{
font-size: 20px;
font-weight: bold;
}
input{
background-color: gray;
@include rounded-corners(50%); //使用混合器
}
&:hover{
color:red;
}
}
//2.css
.password {
@extend .center; //password继承样式表中任何 位置的 .center的样式。
box-shadow: 0 0 0 10px red inset;
}
不仅会继承.center自身的所有样式,任何跟.center有关的组合选择器样式也会被.password 以组合选择器的形式继承
//不要使用后代选择器去继承
.password .text{ //不推荐
@extend .center;
}
extend-Only 选择器,或者占位符选择器%,和id、class选择器类似,只是 必须通过 @extend 指令调用【将原来的“ . ”使用“ % ”定义,只用于继承,不会给某个元素用】
%center{ //只用于@extend的使用,不会给class为center的元素用,况且此时也不是class样式了
input{
background-color: gray;
@include rounded-corners(50%);
}
&:hover{
color:red;
}
}
.password {
@extend %center;
box-shadow: 0 0 0 10px red inset;
}
如果两个 样式之间有 从属、深浅等 基于某一个大类的,则使用继承最好
否则,如果两个样式之间,没有任何关联,直接简单的拼接,则使用mixins比较好
# 7、函数
p {
color: hsl(0, 100%, 50%);
}
//编译为
p {
color: #ff0000;
}
//注意如果在css中,hsl不会编译,而是直接输出,是否显示颜色,取决于浏览器是否支持hsl
//map-get函数,表示从一个对象中,根据key,获取对应的value
.password {
color: map-get((color:red), "color");
}
scss允许你自定义函数,使用@function定义函数名,使用@return返回值
$grid-width: 40px;
@function grid-width($n) {
@return $n * $grid-width;
}
#sidebar { width: grid-width(5); }
编译为
#sidebar {
width: 200px;
}
# 8、导入SASS文件
在css中@import允许在一个css文件中导入其他css文件。然而,只有执行到@import时,浏览器才会去下载其他css文件,这导致页面加载起来特别慢。
而sass的@import,在生成css文件时就把相关文件导入进来。这意味着在使用css样式之前,所有相关的样式被归纳到了同一个css文件中,而无需发起额外的下载请求。
@import "mixins.scss //导入mixins.scss
@import "mixins" //导入mixins.scss,可以省略 后缀
@import "mixins.css" //被解析为导入css
@import url("mixins") //被解析为导入css
一般情况下,你反复声明一个变量,只有最后一处声明有效且它会覆盖前边的值。
$link-color: blue;
$link-color: red;
a {
color: $link-color; //值为red
}
同理, 如果在 variable.scss中有个变量$link-color: red;那么在导入文件后,重新声明会覆盖掉。
@import "variable"
$link-color: red;
a {
color: $link-color; //值为red
}
利用此特性,可以在你的样式表中对导入的样式稍作修改。
# 9、注释
body {
color: #333; // 这种注释内容不会出现在生成的css文件中
padding: 0; /* 这种注释内容会出现在生成的css文件中 */
}
在普通的css中,注释都是/**/
而在scss中提供的//注释,称为"静默注释",即不会出现的最终编译的css文件中。
# 10、数据类型
Sass 支持 6 种主要的数据类型:
- 数字,1, 2, 13, 10px
- 字符串,有引号字符串与无引号字符串,"foo", 'bar', baz
- 颜色,blue, #04a3f9, rgba(255,0,0,0.5)
- 布尔型,true, false
- 空值,null
- 数组 (list),用空格或逗号作分隔符,1.5em 1em 0 2em, Helvetica, Arial, sans-serif
- maps, 相当于 JavaScript 的 object,(key1: value1, key2: value2)
# 11、插值语句#{}
一般情况下,直接使用运算符就可以,但是如果只是为了将结果显示,而不是计算,那么就需要#{}
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
编译为
p.foo {
border-color: blue;
}
.title {
$min-size: 2px
font-size: 18px / $min-size;
}
编译为
.title {
font-size: 9;
}
.title {
$min-size: 2px
font-size: 18px / #{ $min-size };
}
编译为
.title {
font-size: 18px / 2px;
}
.title {
$slidebar-width: 20px;
width: calc(50px - $slidebar-width);
}
编译为
.title {
width: calc(50px - $slidebar-width); //非法,不起作用
}
因为calc中整体是个字符串,scss只会做 字符串的拼接,等拼接后,编译成css,再通过浏览器去计算,scss本身不会去计算。
.title {
$slidebar-width: 20px;
width: calc(50px - #{$slidebar-width});
}
编译为
.title {
width: calc(50px - 20px);
}
# 12、运算
在+ - * / 运算中,有时不想进行计算,只是为了显示,那么采用#{} 将值包裹
//加法
p {
font-size: 18px+2px;
}
编译为
p {
font-size: 20px;
}
//直接显示
p {
font-size: #{18px} + #{2px};
}
编译为
p {
font-size: 18px + 2px;
}
字符串连接
p {
cursor: e + -resize;
}
编译为
p {
cursor: e-resize;
}
# 13、/deep/
在vue中,如果要修改 组件的内部样式,必须穿透去修改,即在scss中使用/deep/, 当然如果是css,则直接使用 >>> 即可
可以用来穿透去修改 插件的样式。而且如果父类使用了/deep/,子类不能再用/deep/,否则样式不会生效。 因为父类使用/deep/ 后,所有子类都被穿透了
# 14、控制指令
@if
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
编译为
p {
color: green;
}
@for @each @while