什么是Sass
Sass 是對(duì) CSS 的擴(kuò)展耻矮,是一種CSS預(yù)處理器考婴,讓 CSS 語言更強(qiáng)大、優(yōu)雅凿试。 它允許你使用變量、嵌套規(guī)則、 mixins、導(dǎo)入等眾多功能, 并且完全兼容 CSS 語法看盖溺, 使得CSS的開發(fā),變得簡(jiǎn)單和可維護(hù)铣缠。
Sass安裝
在Ruby環(huán)境下執(zhí)行
gem install sass
編譯(使用)
單文件轉(zhuǎn)換
sass style.scss style.css
單文件監(jiān)聽命令
sass --watch style.scss:style.css
文件夾監(jiān)聽命令
sass --watch sassDir:cssDir
css 文件轉(zhuǎn)換成scss/sass文件
sass-convert style.css style.sass
sass-convert style.css style.scss
我們一般常用的有--style烘嘱,--sourcemap,--debug-info等蝗蛙。
sass --watch style.scss:style.css --style compact
sass --watch style.scss:style.css --sourcemap
sass --watch style.scss:style.css --style expanded --sourcemap
sass --watch style.scss:style.css --debug-info
- style表示解析后的css是什么格式蝇庭,有四種取值分別為:nested,expanded捡硅,compact哮内,compressed。
- sourcemap表示開啟sourcemap調(diào)試壮韭。開啟sourcemap調(diào)試后北发,會(huì)生成一個(gè)后綴名為.css.map文件。
- debug-info表示開啟debug信息喷屋,升級(jí)到3.3.0之后因?yàn)閟ourcemap更高級(jí)琳拨,這個(gè)debug-info就不太用了。
四種style生成后的css
// nested
#main {
color: #fff;
background-color: #000; }
#main p {
width: 10em; }
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline; }
// expanded
#main {
color: #fff;
background-color: #000;
}
#main p {
width: 10em;
}
.huge {
font-size: 10em;
font-weight: bold;
text-decoration: underline;
}
// compact
#main { color: #fff; background-color: #000; }
#main p { width: 10em; }
.huge { font-size: 10em; font-weight: bold; text-decoration: underline; }
// compressed
#main{color:#fff;background-color:#000}#main p{width:10em}.huge{font-size:10em;font-weight:bold;text-decoration:underline}
基本使用
注釋
SASS共有兩種注釋風(fēng)格屯曹。
標(biāo)準(zhǔn)的CSS注釋 /* comment */
狱庇,會(huì)保留到編譯后的文件。
單行注釋 // comment
是牢,只保留在SASS源文件中僵井,編譯后被省略。
在/*后面加一個(gè)感嘆號(hào)驳棱,表示這是"重要注釋"。即使是壓縮模式編譯农曲,也會(huì)保留這行注釋社搅,通常可以用于聲明版權(quán)信息乳规。
/*!
重要注釋形葬!
*/
嵌套規(guī)則(Nested Rules)
SASS允許選擇器嵌套,比如下面代碼
#a {
.a-1{
background:yellow;
.child{
font-size:12px;
.child-1{
color:red
}
}
}
}
編譯后的結(jié)果:
#a .a-1 {
background: yellow;
}
#a .a-1 .child {
font-size: 12px;
}
#a .a-1 .child .child-1 {
color: red;
}
引用父選擇符: & ==> parent selector
& 在編譯時(shí)將被替換為父選擇符暮的,輸出到 CSS 中笙以,多用于偽類,如 a:hover , a:active , a:visited , a:first-letter , a:last-child等冻辩,比如下面代碼:
.hello {
.dropdown{
display: none;
}
&:hover {
.dropdown{
display: block;
}
}
}
編譯后的結(jié)果:
.hello .dropdown {
display: none;
}
.hello:hover .dropdown {
display: block;
}
屬性嵌套
主要用于復(fù)合屬性猖腕,比如background拆祈、font等
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
border: {
radius:20px;
color:red;
}
}
編譯后的結(jié)果:
.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
border-radius: 20px;
border-color: red;
}
變量(Variables)
SASS允許使用變量,所有變量以$開頭倘感。寫法就像CSS一樣
$width: 10px;
#main {
width: $width;
}
作用域
變量支持塊級(jí)作用域放坏,嵌套規(guī)則內(nèi)定義的變量只能在嵌套規(guī)則內(nèi)使用(局部變量),不在嵌套規(guī)則內(nèi)定義的變量則可在任何地方使用(全局變量)老玛。將局部變量轉(zhuǎn)換為全局變量可以添加 !global 聲明:
$width: 10px;
.p {
$width: 30px;
.a{
width: $width
}
}
編譯結(jié)果為:
.p .a {
width: 30px;
}
插值(Interpolation)
如果變量需要鑲嵌在字符串之中淤年,就必須需要寫在#{}(插值Interpolation)之中,比如:
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
content: "hello world #{$name}"
}
運(yùn)算
Sass支持?jǐn)?shù)字的標(biāo)準(zhǔn)運(yùn)算(加 +蜡豹、減 -麸粮、乘 *、除 /和取模 %)
p {
width: (1em + 2em) * 3;
}
//也可以寫成這樣
p {
width: (1 + 2em) * 3;
}
//或者這樣
p {
width: (1em + 2) * 3;
}
編譯后的結(jié)果:
p {width: 9em;}
除法運(yùn)算
在以下三種情況中镜廉,/ 會(huì)被解釋為除法運(yùn)算弄诲。 這已經(jīng)覆蓋了絕大多數(shù)真正使用除法運(yùn)算的情況:
- 如果數(shù)值或它的任意部分是存儲(chǔ)在一個(gè)變量中或是函數(shù)的返回值。
- 如果數(shù)值被圓括號(hào)包圍桨吊。
- 如果數(shù)值是另一個(gè)數(shù)學(xué)表達(dá)式的一部分
p {
font: 10px/8px; // 純 CSS威根,不是除法運(yùn)算
$width: 1000px;
width: $width/2; // 使用了變量,是除法運(yùn)算
width: round(1.5)/2; // 使用了函數(shù)视乐,是除法運(yùn)算
height: (500px/2); // 使用了圓括號(hào)洛搀,是除法運(yùn)算
margin-left: 5px + 8px/2px; // 使用了加(+)號(hào),是除法運(yùn)算
}
編譯后的結(jié)果:
p {
font: 10px/8px; //沒有進(jìn)行編譯
width: 500px;
width: 1;
height: 250px;
margin-left: 9px;
}
如果你希望在編譯后的 CSS 中使用變量和 /佑淀, 你可以用 #{} 包住變量留美。 例如:
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
編譯后的結(jié)果:
p {
font: 12px/30px;
}
顏色運(yùn)算
p {
color: #123123 + #040506;
}
編譯后的結(jié)果:
p {
color: #163629;
}
在文本字符串中,#{} 形式的表達(dá)式可以被用來在字符串中添加動(dòng)態(tài)值:
空值會(huì)被視作空字符串:
p:before {
content: "I ate #{5 + 10} pies!";
}
$value: null;
p:before {
content: "I ate #{$value} pies!";
}
編譯后的結(jié)果:
p:before {
content: "I ate 15 pies!";
}
p:before {
content: "I ate pies!";
}
規(guī)則和指令(directive )
(導(dǎo)入)@import
Sass 擴(kuò)展了 CSS 的 @import 規(guī)則伸刃,讓它能夠引入 scss 和sass 文件谎砾,Sass的@import規(guī)則和CSS的有所不同,編譯時(shí)會(huì)將@import的scss文件合并進(jìn)來只生成一個(gè)CSS文件捧颅。但是如果你在Sass文件中導(dǎo)入css文件如@import 'reset.css'景图,那效果跟普通CSS導(dǎo)入樣式文件一樣,導(dǎo)入的css文件不會(huì)合并到編譯后的文件中碉哑,而是以@import方式存在挚币。
用法如下:
@import "basic.scss";
還可以嵌套使用,相當(dāng)于個(gè)編譯后的basic .css加了一個(gè)命名空間扣典,
.example {
@import "basic.scss";
}
編譯后的結(jié)果:
.example #a .a-1 {
background: yellow;
}
.example #a .a-1 .child {
font-size: 12px;
}
.example #a .a-1 .child .child-1 {
color: red;
}
媒體查詢(@media)
Sass 中 @media 指令與 CSS 中用法一樣妆毕,只是增加了一點(diǎn)額外的功能:允許其在 CSS 規(guī)則中嵌套。如果 @media 嵌套在 CSS 規(guī)則內(nèi)贮尖,編譯時(shí)笛粘,@media 將被編譯到文件的最外層,包含嵌套的父選擇器。這個(gè)功能讓 @media 用起來更方便薪前,不需要重復(fù)使用選擇器润努,也不會(huì)打亂 CSS 的書寫流程。
.father{
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
.hello{
font-size:20px
}
}
}
}
編譯后的結(jié)果:
.father .sidebar {
width: 300px;
}
@media screen and (orientation: landscape) {
.father .sidebar {
width: 500px;
}
.father .sidebar .hello {
font-size: 20px;
}
}
繼承(@extend)
- 簡(jiǎn)單繼承
Sass中序六,選擇器繼承可以讓選擇器繼承另一個(gè)選擇器的所有樣式任连,并聯(lián)合聲明。使用選擇器的繼承例诀,要使用關(guān)鍵詞@extend随抠,后面緊跟需要繼承的選擇器。
比如:
.error {
border: 1px #f00;
&.intrusion {
background-image: url("/image/hacked.png");
}
}
.seriousError {
@extend .error;
}
編譯后的結(jié)果:
.error, .seriousError, {
border: 1px #f00;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
- 多元素繼承(Multiple Extends)
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error;
@extend .attention;
border-width: 3px;
}
編譯后的結(jié)果:
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
border-width: 3px;
}
- 鏈?zhǔn)嚼^承(Chaining Extends)
.error {
border: 1px #f00;
background-color: #fdd;
}
.seriousError {
@extend .error;
border-width: 3px;
}
.criticalError {
@extend .seriousError;
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
編譯后的結(jié)果:
.error, .seriousError, .criticalError {
border: 1px #f00;
background-color: #fdd;
}
.seriousError, .criticalError {
border-width: 3px;
}
.criticalError {
position: fixed;
top: 10%;
bottom: 10%;
left: 10%;
right: 10%;
}
從編譯后的CSS中不難看出繁涂,類名“.error”變成了群組選擇拱她,添加了類名“.seriousError”和類名“.criticalError”。而類名“.seriousError”變成了群組選擇扔罪,添加了類名“.criticalError”秉沼。這就叫做鏈?zhǔn)嚼^承。
混合(@m(xù)ixin)
Sass中使用@mixin聲明混合矿酵,可以傳遞參數(shù)唬复,參數(shù)名以$符號(hào)開始,多個(gè)參數(shù)以逗號(hào)分開全肮,也可以給參數(shù)設(shè)置默認(rèn)值敞咧。聲明的@mixin通過@include來調(diào)用。
- 使用
通過@mixin定義混合
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
通過@include調(diào)用定義的混合
.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;
}
```
- 帶參數(shù)的混合
```
@mixin sexy-border($color:blue, $width:20px) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
//不傳參辜腺,使用默認(rèn)參數(shù)
p { @include sexy-border;}
//傳參數(shù)
p { @include sexy-border(green, 10px); }
```
```
//不傳參休建,使用默認(rèn)參數(shù)
p {
border-color: blue;
border-width: 20px;
border-style: dashed;
}
//傳參數(shù)
p {
border-color: green;
border-width: 10px;
border-style: dashed;
}
```
- 多組值參數(shù)mixin
如果一個(gè)參數(shù)可以有多組值,如box-shadow评疗、transition等测砂,那么參數(shù)則需要在變量后加三個(gè)點(diǎn)表示,如$shadow...百匆,比如:
```
@mixin box-shadow($shadow...) {
-webkit-box-shadow:$shadow;
box-shadow:$shadow;
}
.box{
border:1px solid #ccc;
@include box-shadow(0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3));
}
```
編譯后的結(jié)果:
```
.box{
border:1px solid #ccc;
-webkit-box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3);
box-shadow:0 2px 2px rgba(0,0,0,.3),0 3px 3px rgba(0,0,0,.3),0 4px 4px rgba(0,0,0,.3);
}
```
#### 條件指令
###### @if: @if可一個(gè)條件單獨(dú)使用砌些,也可以和@else或者@else if 結(jié)合多條件使用
```
p {
@if 1 + 1 == 2 { border: 1px solid; }
@if true {background-image:url('')}
@if 5 < 3 { border: 2px dotted; }
@if null { border: 3px double; }
}
$type: monster;
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
```
編譯后的結(jié)果:
```
p {
border: 1px solid;
background-image: url("");
}
p {
color: green;
}
```
#### 循環(huán)指令
###### @for
for循環(huán)有兩種形式,分別為:@for $var from <start> through <end>和@for $var from <start> to <end>加匈。$i表示變量寄症,start表示起始值,end表示結(jié)束值矩动,這兩個(gè)的區(qū)別是關(guān)鍵字through表示包括end這個(gè)數(shù),而to則不包括end這個(gè)數(shù)释漆。
```
/*from ... through*/
@for $i from 1 through 3 { //1,2,3
.item-#{$i} { width: 2em * $i; }
}
###
/*from ... to*/
@for $i from 1 to 3 { //1,2
.item-to-#{$i} { width: 2em * $i; }
}
```
編譯后的結(jié)果:
```
/*from ... through*/
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
/*from ... to*/
.item-to-1 {
width: 2em;
}
.item-to-2 {
width: 4em;
}
```
###### @each
語法為:@each $var in <list>悲没。其中$var表示變量。
```
//單字段
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
//多字段
$animal-data: (puma, black, default),(sea-slug, blue, pointer),(egret, white, move);
@each $animal, $color, $cursor in $animal-data {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
border: 2px solid $color;
cursor: $cursor;
}
}
```
編譯結(jié)果為:
```
//單字段
.puma-icon {
background-image: url("/images/puma.png");
}
.sea-slug-icon {
background-image: url("/images/sea-slug.png");
}
.egret-icon {
background-image: url("/images/egret.png");
}
.salamander-icon {
background-image: url("/images/salamander.png");
}
//多字段
.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;
}
```
###### @while
@while和@for指令很相似,只要@while后面的條件為true就會(huì)執(zhí)行示姿。
```
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
```
編譯結(jié)果為:
```
.item-6 {
width: 12em;
}
.item-4 {
width: 8em;
}
.item-2 {
width: 4em;
}
```
### 自定義函數(shù)
```
$grid-width: 40px;
$gutter-width: 10px;
@function test($a){
@return $a+10
}
@function grid-width($n) {
$hello:1px ;
@for $i from 1 through $n{
$hello:$hello+$i
}
@if $hello > 10 {
$hello:15px
}
@return $hello + test(2)
}
#sidebar { width: grid-width(5); }
```
編譯結(jié)果為:
```
#sidebar {
width: 27px;
}
```
**關(guān)于應(yīng)用場(chǎng)景的思考:**
[SASS應(yīng)用場(chǎng)景的思考](https://segmentfault.com/a/1190000009466690)