對於一個從後臺轉到前端的web開發者來說,最大的麻煩就是寫CSS,瞭解CSS的人都知道,它可以開髮網頁樣式,但是沒法用它編程,感覺耦合性相當的高,如果想要方便以後維護,只能逐句修改甚至重寫相當一部分的CSS。隨著後臺人員大量的涌入前端這個行業,CSS又煥發了新的春天,人們開始為CSS加入編程元素,也 ...
對於一個從後臺轉到前端的web開發者來說,最大的麻煩就是寫CSS,瞭解CSS的人都知道,它可以開髮網頁樣式,但是沒法用它編程,感覺耦合性相當的高,如果想要方便以後維護,只能逐句修改甚至重寫相當一部分的CSS。隨著後臺人員大量的涌入前端這個行業,CSS又煥發了新的春天,人們開始為CSS加入編程元素,也就是“CSS預處理器”。它的基本思想就是用一門專門的編程語言,進行網頁樣式設計,然後再編譯成正常的CSS文件。下麵我們結合官方文檔和阮一峰老師的用法指南,再次系統的總結一下Sass的主要用法。
1.Sass的安裝
Sass是Ruby語言寫的,我們在安裝Sass之前必須先安裝Ruby,安裝Ruby的過程就不再贅述,安裝好Ruby後可以直接在命令行(windows在cmd中)輸入下麵的命令
gem install sass
2.Sass的使用
Sass文件就是普通的文本文件,尾碼名有.sass和.scss兩種。 尾碼名為.sass的文件編碼風格不需要添加大括弧,但需要處理縮進等操作,如下
*
margin:0;
padding:0;
尾碼名為.scss的文件編碼風格偏向於正常的CSS風格如下:
*{
margin:0;
padding:0;
}
Sass官方都會對兩者風格平行更新,所以喜歡哪種風格還是看個人的愛好,由於本人偏向於.scss文件尾碼,所以下麵的例子都會基於.scss文件風格。
下麵的命令,可以在屏幕上顯示.scss文件轉化的css(假設文件名為test)
sass test.scss
如果要把.scss文件直接轉化為css文件,後面需要再跟.css的文件名
sass test.scss test.css
Sass提供了四種編譯風格的選項
* nested: 嵌套縮進的css的代碼,預設
* expanded:沒有縮進、擴展的css代碼
* compact:簡介格式的css代碼
* compressed:壓縮後的css代碼
我們可以用如下命令切換編譯風格
sass --style compressed test.scss test.css
我們也可以讓Sass監聽某個文件或目錄,一旦源文件發生變動,就自動生成編譯後的版本
// watch a file
sass --watch test.scss:test.css
// watch a direcoty
sass --watch app/sass:public/stylesheets
如果有使用webStrom開發的同學可以添加File Watchers,但是我感覺不如開啟整個目錄監聽的好,有一點需要註意的就是不同的批處理對應不同的的尾碼名文件即sass.bat對應.sass文件、scss.bat對應.scss文件
3.Sass的基本用法
3.1 導入
Sass的導入(@import)規則和CSS的有所不同,讓我們回顧一下CSS@import導入的缺點:CSS在@import一個文件的時候,它不會立即導入,只有在引用它的那個css文件被下載、解析之後,瀏覽器才會知道還有另外一個css需要下載,這時才去下載,然後下載後開始解析、構建render tree等一系列操作,從而導致css無法並行下載。但是Sass的導入(@import),編譯時會將@import的scss文件合併進來只生成一個CSS文件。但是如果你在sass文件中導入css文件如@import 'reset.css',那效果跟普通CSS導入樣式文件一樣,導入的css文件不會合併到編譯後的文件中,而是以@import方式存在。
所有的sass導入文件都可以忽略尾碼名.scss。一般來說基礎的文件命名方法以開頭,如mixin.scss。這種文件在導入的時候可以不寫下劃線,可寫成@import "mixin"。
被導入sass文件a.scss:
//a.scss
//-------------------------------
body {
background: #eee;
}
需要導入樣式的sass文件b.scss:
@import "reset.css";
@import "a";
p{
background: #0982c1;
}
轉譯出來的b.css樣式:
@import "reset.css";
body {
background: #eee;
}
p{
background: #0982c1;
}
根據上面的代碼可以看出,b.scss編譯後,reset.css繼續保持import的方式,而a.scss則被整合進來了。
3.2 註釋
sass有兩種註釋方式,一種是標準的css註釋方式/* */,另一種則是//雙斜桿形式的單行註釋,不過這種單行註釋不會被轉譯出來。 標準的css註釋
/*
*我是css的標準註釋
*設置body內距
*/
body{
padding:5px;
}
雙斜桿單行註釋 單行註釋跟JavaScript語言中的註釋一樣,使用又斜杠(//),但單行註釋不會輸入到CSS中。
//我是雙斜杠表示的單行註釋
//設置body內距
body{
padding:5px; //5px
}
3.3 變數
sass的變數必須是$開頭,後面緊跟變數名,而變數值和變數名之間就需要使用冒號(:)分隔開(就像CSS屬性設置一樣),如果值後面加上!default則表示預設值。
3.3.1 普通變數
定義之後可以在全局範圍內使用。
//sass style
//-------------------------------
$fontSize: 12px;
body{
font-size:$fontSize;
}
//css style
//-------------------------------
body{
font-size:12px;
}
3.3.2 預設變數
sass的預設變數僅需要在值後面加上!default即可。
//sass style
//-------------------------------
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
//css style
//-------------------------------
body{
line-height:1.5;
}
sass的預設變數一般是用來設置預設值,然後根據需求來覆蓋的,覆蓋的方式也很簡單,只需要在預設變數之前重新聲明下變數即可
//sass style
//-------------------------------
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
//css style
//-------------------------------
body{
line-height:2;
}
可以看出現在編譯後的line-height為2,而不是我們預設的1.5。預設變數的價值在進行組件化開發的時候會非常有用。
3.3.3 特殊變數
一般我們定義的變數都為屬性值,可直接使用,但是如果變數作為屬性或在某些特殊情況下等則必須要以#{$variables}形式使用。
//sass style
//-------------------------------
$borderDirection: top !default;
$baseFontSize: 12px !default;
$baseLineHeight: 1.5 !default;
//應用於class和屬性
.border-#{$borderDirection}{
border-#{$borderDirection}:1px solid #ccc;
}
//應用於複雜的屬性值
body{
font:#{$baseFontSize}/#{$baseLineHeight};
}
//css style
//-------------------------------
.border-top{
border-top:1px solid #ccc;
}
body {
font: 12px/1.5;
}
3.3.4 多值變數
多值變數分為list類型和map類型,簡單來說list類型有點像js中的數組,而map類型有點像js中的對象。
3.3.4.1 list
list數據可通過空格,逗號或小括弧分隔多個值,可用nth($var,$index)取值。關於list數據操作還有很多其他函數如length($list),join($list1,$list2,[$separator]),append($list,$value,[$separator])等,具體可參考sass Functions(搜索List Functions即可) 定義
//一維數據
$px: 5px 10px 20px 30px;
//二維數據,相當於js中的二維數組
$px: 5px 10px, 20px 30px;
$px: (5px 10px) (20px 30px);
使用
//sass style
//-------------------------------
$linkColor: #08c #333 !default;//第一個值為預設值,第二個滑鼠滑過值
a{
color:nth($linkColor,1);
&:hover{
color:nth($linkColor,2);
}
}
//css style
//-------------------------------
a{
color:#08c;
}
a:hover{
color:#333;
}
3.3.4.2 map
map數據以key和value成對出現,其中value又可以是list。格式為:$map: (key1: value1, key2: value2, key3: value3);。可通過map-get($map,$key)取值。關於map數據還有很多其他函數如map-merge($map1,$map2),map-keys($map),map-values($map)等,具體可參考sass Functions(搜索Map Functions即可) 定義
$heading: (h1: 2em, h2: 1.5em, h3: 1.2em);
使用
//sass style
//-------------------------------
$headings: (h1: 2em, h2: 1.5em, h3: 1.2em);
@each $header, $size in $headings {
#{$header} {
font-size: $size;
}
}
//css style
//-------------------------------
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.2em;
}
3.4 嵌套(Nesting)
sass的嵌套包括兩種:一種是選擇器的嵌套;另一種是屬性的嵌套。我們一般說起或用到的都是選擇器的嵌套。
3.4.1 選擇器嵌套
所謂選擇器嵌套指的是在一個選擇器中嵌套另一個選擇器來實現繼承,從而增強了sass文件的結構性和可讀性。 在選擇器嵌套中,可以使用&表示父元素選擇器
//sass style
//-------------------------------
#top_nav{
line-height: 40px;
text-transform: capitalize;
background-color:#333;
li{
float:left;
}
a{
display: block;
padding: 0 10px;
color: #fff;
&:hover{
color:#ddd;
}
}
}
//css style
//-------------------------------
#top_nav{
line-height: 40px;
text-transform: capitalize;
background-color:#333;
}
#top_nav li{
float:left;
}
#top_nav a{
display: block;
padding: 0 10px;
color: #fff;
}
#top_nav a:hover{
color:#ddd;
}
3.4.2 屬性嵌套
所謂屬性嵌套指的是有些屬性擁有同一個開始單詞,如border-width,border-color都是以border開頭。拿個官網的實例看下:
//sass style
//-------------------------------
.fakeshadow {
border: {
style: solid;
left: {
width: 4px;
color: #888;
}
right: {
width: 2px;
color: #ccc;
}
}
}
//css style
//-------------------------------
.fakeshadow {
border-style: solid;
border-left-width: 4px;
border-left-color: #888;
border-right-width: 2px;
border-right-color: #ccc;
}
3.5 混合(mixin)
sass中使用@mixin聲明混合,可以傳遞參數,參數名以$符號開始,多個參數以逗號分開,也可以給參數設置預設值。聲明的@mixin通過@include來調用。
3.5.1 無參數mixin
//sass style
//-------------------------------
@mixin center-block {
margin-left:auto;
margin-right:auto;
}
.demo{
@include center-block;
}
//css style
//-------------------------------
.demo{
margin-left:auto;
margin-right:auto;
}
3.5.2 有參數mixin
//sass style
//-------------------------------
@mixin opacity($opacity:50) {
opacity: $opacity / 100;
filter: alpha(opacity=$opacity);
}
//css style
//-------------------------------
.opacity{
@include opacity; //參數使用預設值
}
.opacity-80{
@include opacity(80); //傳遞參數
}
3.5.3 多個參數mixin
調用時可直接傳入值,如@include傳入參數的個數小於@mixin定義參數的個數,則按照順序表示,後面不足的使用預設值,如不足的沒有預設值則報錯。除此之外還可以選擇性的傳入參數,使用參數名與值同時傳入。
//sass style
//-------------------------------
@mixin horizontal-line($border:1px dashed #ccc, $padding:10px){
border-bottom:$border;
padding-top:$padding;
padding-bottom:$padding;
}
.imgtext-h li{
@include horizontal-line(1px solid #ccc);
}
.imgtext-h--product li{
@include horizontal-line($padding:15px);
}
//css style
//-------------------------------
.imgtext-h li {
border-bottom: 1px solid #cccccc;
padding-top: 10px;
padding-bottom: 10px;
}
.imgtext-h--product li {
border-bottom: 1px dashed #cccccc;
padding-top: 15px;
padding-bottom: 15px;
}
3.5.4 多組值參數mixin
如果一個參數可以有多組值,如box-shadow、transition等,那麼參數則需要在變數後加三個點表示,如$variables...。
//sass style
//-------------------------------
//box-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));
}
//css style
//-------------------------------
.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);
}
3.5.5 @content
@content在sass3.2.0中引入,可以用來解決css3的@media等帶來的問題。它可以使@mixin接受一整塊樣式,接受的樣式從@content開始。
//sass style
//-------------------------------
@mixin max-screen($res){
@media only screen and ( max-width: $res )
{
@content;
}
}
@include max-screen(480px) {
body { color: red }
}
//css style
//-------------------------------
@media only screen and (max-width: 480px) {
body { color: red }
}
3.6 繼承
sass中,選擇器繼承可以讓選擇器繼承另一個選擇器的所有樣式,並聯合聲明。使用選擇器的繼承,要使用關鍵詞@extend,後面緊跟需要繼承的選擇器。
3.6.1 普通繼承
//sass style
//-------------------------------
h1{
border: 4px solid #ff9aa9;
}
.speaker{
@extend h1;
border-width: 2px;
}
//css style
//-------------------------------
h1,.speaker{
border: 4px solid #ff9aa9;
}
.speaker{
border-width: 2px;
}
3.6.2 占位選擇器%
從sass 3.2.0以後就可以定義占位選擇器%。這種選擇器的優勢在於:如果不調用則不會有任何多餘的css文件,避免了以前在一些基礎的文件中預定義了很多基礎的樣式,然後實際應用中不管是否使用了@extend去繼承相應的樣式,都會解析出來所有的樣式。占位選擇器以%標識定義,通過@extend調用。
//sass style
//-------------------------------
%ir{
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
%clearfix{
@if $lte7 {
*zoom: 1;
}
&:before,
&:after {
content: "";
display: table;
font: 0/0 a;
}
&:after {
clear: both;
}
}
#header{
h1{
@extend %ir;
width:300px;
}
}
.ir{
@extend %ir;
}
//css style
//-------------------------------
#header h1,
.ir{
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
#header h1{
width:300px;
}
如上代碼,定義了兩個占位選擇器%ir和%clearfix,其中%clearfix這個沒有調用,所以解析出來的css樣式也就沒有clearfix部分。占位選擇器的出現,使css文件更加簡練可控,沒有多餘。所以可以用其定義一些基礎的樣式文件,然後根據需要調用產生相應的css。
ps:在@media中暫時不能@extend @media外的代碼片段,以後將會可以。
3.7 函數
sass定義了很多函數可供使用,當然你也可以自己定義函數,以@fuction開始。實際項目中我們使用最多的應該是顏色函數,而顏色函數中又以lighten減淡和darken加深為最,其調用方法為lighten($color,$amount)和darken($color,$amount),它們的第一個參數都是顏色值,第二個參數都是百分比。
//sass style
//-------------------------------
$baseFontSize: 10px !default;
$gray: #ccc !defualt;
// pixels to rems
@function pxToRem($px) {
@return $px / $baseFontSize * 1rem;
}
body{
font-size:$baseFontSize;
color:lighten($gray,10%);
}
.test{
font-size:pxToRem(16px);
color:darken($gray,10%);
}
//css style
//-------------------------------
body{
font-size:10px;
color:#E6E6E6;
}
.test{
font-size:1.6rem;
color:#B3B3B3;
}
3.8 運算
sass具有運算的特性,可以對數值型的Value(如:數字、顏色、變數等)進行加減乘除四則運算。請註意運算符前後請留一個空格,不然會出錯。
$baseFontSize: 14px !default;
$baseLineHeight: 1.5 !default;
$baseGap: $baseFontSize * $baseLineHeight !default;
$halfBaseGap: $baseGap / 2 !default;
$samllFontSize: $baseFontSize - 2px !default;
//grid
$_columns: 12 !default; // Total number of columns
$_column-width: 60px !default; // Width of a single column
$_gutter: 20px !default; // Width of the gutter
$_gridsystem-width: $_columns * ($_column-width + $_gutter); //grid system width
3.9 條件判斷及迴圈
3.9.1 @if判斷
@if可一個條件單獨使用,也可以和@else結合多條件使用
//sass style
//-------------------------------
$lte7: true;
$type: monster;
.ib{
display:inline-block;
@if $lte7 {
*display:inline;
*zoom:1;
}
}
p {
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else if $type == monster {
color: green;
} @else {
color: black;
}
}
//css style
//-------------------------------
.ib{
display:inline-block;
*display:inline;
*zoom:1;
}
p {
color: green;
}
3.9.2 三目判斷
語法為:if($condition, $iftrue, $iffalse) 。三個參數分別表示:條件,條件為真的值,條件為假的值。
if(true, 1px, 2px) => 1px
if(false, 1px, 2px) => 2px
3.9.3for迴圈
for迴圈有兩種形式,分別為:@for $var from through 和@for $var from to 。$i表示變數,start表示起始值,end表示結束值,這兩個的區別是關鍵字through表示包括end這個數,而to則不包括end這個數。
//sass style
//-------------------------------
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
//css style
//-------------------------------
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
3.9.4 @each迴圈
語法為:@each $var in 。其中$var表示變數,而list和map表示list類型數據和map類型數據。sass 3.3.0新加入了多欄位迴圈和map數據迴圈。
3.9.4.1 單個欄位list數據迴圈
//sass style
//-------------------------------
$animal-list: puma, sea-slug, egret, salamander;
@each $animal in $animal-list {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
//css style
//-------------------------------
.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');
}
3.9.4.2 多個欄位list數據迴圈
//sass style
//-------------------------------
$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;
}
}
//css style
//-------------------------------
.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;
}
3.9.4.3多個欄位map數據迴圈
//sass style
//-------------------------------
$headings: (h1: 2em, h2: 1.5em, h3: 1.2em);
@each $header, $size in $headings {
#{$header} {
font-size: $size;
}
}
//css style
//-------------------------------
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.2em;
}
(完)