前言
Sass在CSS的基础上增加了变量、嵌套、混合、导入等高级功能, 使开发起来更优雅.
一. 准备工作
安装
brew install node-sass
使用
sass mysCSS.scss:output.css -w #监听
二. 一些规则
1. 嵌套
能避免了重复输入父选择器, 同时使复杂的 CSS 结构更易于管理.
.main {
color: red;
font-weight: bold;
.title {
font-size: 22px;
}
}
转为:
.main {
color: red;
font-weight: bold;
}
.main .title {
font-size: 22px;
}
2. &指代父选择器, 且必须作为选择器的第一个字符.
如下面示例中的&
指代.main
.main {
color: red;
font-weight: bold;
&-title {
font-size: 22px;
}
}
转为:
.main {
color: red;
font-weight: bold;
}
.main-title {
font-size: 22px;
}
3. 属性嵌套
有些 CSS 属性遵循相同的命名空间, 如 background-*, border-*, font-*, flex-*, justify-*, margin-* 和 padding-*等. 为了方便管理和避免重复输入, Sass允许将属性嵌套在命名空间中.
.main {
margin: {
top: 5px;
right: 6px;
bottom: 7px;
left: 8px;
};
}
转为:
.main {
margin-top: 5px;
margin-right: 6px;
margin-bottom: 7px;
margin-left: 8px;
}
同时命名空间也可以包含自己的属性值:
.main {
font: 20px/ 24px {
size: 16rpx;
weight: bold;
}
}
转为:
.main {
font: 20px/24px;
font-size: 16rpx;
font-weight: bold;
}
4. 单行和多行注释
多行注释 /* */
会显示在编译后的CSS文件中, 而 //
的单行注释则不会.
.main {
/*
属性嵌套的注释
*/
margin: {
left: 4px;
// margin-top的单行注释
top: 5px;
}
}
转为:
.main {
/*
属性嵌套的注释
*/
margin-left: 4px;
margin-top: 5px;
}
5. 变量
变量以美元符号开头, 赋值方法与CSS属性的写法一样. 同时, 变量有作用域(局部变量转全局用 !global
, 我几乎没用过).
.main {
$bgColor: grey;
$sm: 16px;
$lg: 22px;
background: $bgColor;
.title-wrapper {
font-size: $lg;
.des {
font-size: $sm;
}
}
}
转为:
.main {
background: grey;
}
.main .title-wrapper {
font-size: 22px;
}
.main .title-wrapper .des {
font-size: 16px;
}
6. 数组
是通过空格或者逗号分隔的一系列的值. 常用的函数有两个:nth
可以直接访问数组中的某一项; @each
指令能够遍历数组中的每一项.
7. 运算符
布尔运算符: and
or
以及 not
;
关系运算符: <, >, <=, >=, ==, !=
8. 插值语句 #{}
通过 #{}
插值语句可以在选择器或属性名中使用变量:
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
转为:
p.foo {
border-color: blue;
}
9. @import
9.1 非嵌套
被导入的文件将合并编译到同一个CSS文件中, 另外, 被导入的文件中所包含的变量或者混合指令 (mixin) 都可以在导入的文件中使用.
注意: 在以下情况下,@import
仅作为普通的CSS语句, 不会导入任何 Sass 文件:
- 文件拓展名是
.css
; - 文件名以
http://
开头; - 文件名是
url()
; -
@import
包含媒体查询。
如果不在上述情况内, 文件的拓展名是 .scss
或 .sass
, 则导入成功. 没有指定拓展名, Sass 将会试着寻找文件名相同, 拓展名为 .scss
或 .sass
的文件并将其导入.
@import "foo.scss"; # 方式一
@import "foo"; # 方式二
都会导入文件foo.scss
.
9.2 嵌套的@import
大多数情况下, 一般在文件的最外层使用 @import
. 但也可以将 @import
嵌套进CSS样式或者 @media
中, 只是这样导入的样式只能出现在嵌套的层中.
如: example.scss
样式如下:
.example {
color: red;
}
导入到 home.scss
内
.home-page {
@import './example.scss';
}
转为:
.home-page .example {
color: red;
}
10. Partials
如果需要导入Scss文件, 但又不希望将其编译为CSS, 只需要在文件名前添加下划线, 这样会告诉Sass不要编译这些文件, 但导入语句中却不需要添加下划线. 一般对于公共的Sass文件会用到.
**注意: ** 不可以同时存在添加下划线与未添加下划线的同名文件, 添加下划线的文件将会被忽略.
如: 将文件命名为 _colors.scss
, 便不会编译 _colors.css
文件.
@import "colors.scss";
11. @media
11. 1 与在CSS中的用法一样, 只不过Sass允许在CSS规则中嵌套.
如果 @media
嵌套在CSS规则内, 在编译时, @media` 将被编译到文件的最外层, 包含嵌套的父选择器.
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}
转为:
.sidebar {
width: 300px;
}
@media screen and (orientation: landscape) {
.sidebar {
width: 500px;
}
}
11.2 @media的媒体查询允许互相嵌套使用,编译时,Sass 自动添加 and
@media screen {
.sidebar {
@media (orientation: landscape) {
width: 500px;
}
}
}
转为:
@media screen and (orientation: landscape) {
.sidebar {
width: 500px;
}
}
12. @extend
@extend
的作用是将重复使用的样式延伸给需要包含这个样式的特殊样式.
考虑一下这种情况, 有一个success的按钮只是在普通按钮button增加了background-color: green;
的属性.
<button class="button success">已提交成功</button>
.button {
border: none;
font-size: 16px;
background: #f2f2f2;
}
.success {
background: green;
}
这可能会给html增加无语义的样式. 我们key考虑通过 @extend
改变一下:
.button {
border: none;
font-size: 16px;
background: #f2f2f2;
}
.success {
@extend .button;
background: green;
}
转为:
.button, .success {
border: none;
font-size: 16px;
background: #f2f2f2;
}
.success {
background: green;
}
13. @if
当 @if
的表达式返回值不是 false
或者 null
时, 条件成立, 输出 {}
内的代码. @if
声明后面可以跟多个 @else if
声明,或者一个 @else
声明.
p {
@if 1 > 0 { background: red;}
@if 5 > 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
转为:
p {
background: red;
border: 2px dotted;
}
14. @for
@for
指令可以在限制的范围内重复输出格式, 每次按要求对输出结果做出变动. 有两种格式:@for $var from <start> through <end>
和 @for $var from <start> to <end>
, 区别在于前者包含 <end>, 后者不包括. 另外, $var
可以是任何变量,比如 $i
;<start> 和 <end> 必须是整数值。
@for $i from 1 through 3 {
.x-line-#{$i} {
@if $i == 1 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} @else {
display: -webkit-box!important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: $i;
-webkit-box-orient: vertical!important;
}
}
}
转为:
.x-line-1 {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.x-line-2 {
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical !important;
}
.x-line-3 {
display: -webkit-box !important;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical !important;
}
15. @each
语法: @each $var in <list>
, 其中$var
可以是任何变量名.
@each $direction in left, top, right, bottom {
.#{$direction}-icon {
background-image: url('/images/#{$direction}.png');
}
}
转为:
.left-icon {
background-image: url("/images/left.png");
}
.top-icon {
background-image: url("/images/top.png");
}
.right-icon {
background-image: url("/images/right.png");
}
.bottom-icon {
background-image: url("/images/bottom.png");
}
15.1 多重赋值
@each指令也可以使用多个变量. 如 @each $var1, $var2...
. 如果是二维列表,子列表的每个元素都被分配给各自的变量.
@each $animal, $color, $cursor in (puma, black, default),
(sea-slug, blue, pointer),
(egret, white, move) {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
border: 2px solid $color;
cursor: $cursor;
}
}
转为:
.puma-icon {
background-image: url("/images/puma.png");
border: 2px solid black;
cursor: default;
}
.sea-slug-icon {
background-image: url("/images/sea-slug.png");
border: 2px solid blue;
cursor: pointer;
}
.egret-icon {
background-image: url("/images/egret.png");
border: 2px solid white;
cursor: move;
}
15.2 Map的多重赋值
由于Map被视为键值对的列表, 因此多重赋值也适用于它们.
@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{$header} {
font-size: $size;
}
}
转为:
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.2em;
}
16. 混合指令 @mixin
语法: 在 @mixin
后添加名称与样式.
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
17. 引用混合样式 @include
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
转为:
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px;
}
也可以在最外层引用混合样式, 不会直接定义属性, 也不可以使用父选择器.
@mixin silly-links {
a {
color: blue;
background-color: red;
}
}
@include silly-links;
转为:
a {
color: blue;
background-color: red;
}
混合样式中也可以包含其他混合样式, 如:
@mixin compound {
@include highlighted-background;
@include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
18. 参数
参数用于给混合指令中的样式设定变量, 并且赋值使用. 在定义混合指令的时候, 按照变量的格式, 通过逗号分隔, 将参数写进圆括号里. 引用指令时, 按照参数的顺序, 再将所赋的值对应写进括号:
**注意: ** 在调用的时候, 如果没有默认值, 则所有的参数是必传.
**注意: ** 在使用
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p {
@include sexy-border(blue, 1in);
}
转为:
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}
如果不想按照参数顺序赋值, 可以通过关键词参数赋值:
p {
@include sexy-border($width: 100px, $color: red);
}
转为:
p {
border-color: red;
border-width: 100px;
border-style: dashed;
}
混合指令可以使用给变量赋值的方法给参数设定默认值, 当这个指令被引用的时候, 如果没有给参数赋值, 则自动使用默认值(**注意: ** 默认参数需要放到最后):
@mixin sexy-border($color, $width: 1in) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p {
@include sexy-border(blue);
}
h1 {
@include sexy-border(blue, 2in);
}
转为:
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}
h1 {
border-color: blue;
border-width: 2in;
border-style: dashed;
}
参数变量
当不能确定混合指令需要使用多少个参数, 比如一个关于 box-shadow
的混合指令不能确定有多少个 'shadow' 会被用到.
语法: 在参数的最后方通过 …
声明.
@mixin box-shadow($shadows...) {
box-shadow: $shadows;
}
.shadows {
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
转为:
.shadows {
box-shadow: 0px 4px 5px #666, 2px 6px 10px #999;
}
参数变量也可以用在引用混合指令的时候 (@include
), 将一串值列表中的值逐条作为参数引用:
@mixin box-shadow($shadows...) {
box-shadow: $shadows;
}
$values: 0px 4px 5px #666, 2px 6px 10px #999;
.shadows {
@include box-shadow($values);
}
19. @content
向混合样式中导入内容: 在引用混合样式的时候, 可以先将一段代码导入到混合指令中, 然后再输出混合样式, 额外导入的部分将出现在 @content
标志的地方.
$titleColor: white;
@mixin colors($bgBorderColor: blue) {
background-color: $bgBorderColor;
@content;
border-color: $bgBorderColor;
}
.common {
@include colors { color: $titleColor; }
}
转为:
.common {
background-color: blue;
color: white;
border-color: blue;
}