CSS不像其它高級語言一樣支持算術運算、變數、流程式控制制與面向對象特性,所以CSS樣式較多時會引起一些問題,如修改複雜,冗餘,某些別的語言很簡單的功能實現不了等。而javascript則是一種半面向對象的動態語言,有java的影子,有C的味道,中間有比其它語言多的糟粕,使用預處理辦法可以解決這些問題。 ...
CSS不像其它高級語言一樣支持算術運算、變數、流程式控制制與面向對象特性,所以CSS樣式較多時會引起一些問題,如修改複雜,冗餘,某些別的語言很簡單的功能實現不了等。而javascript則是一種半面向對象的動態語言,有java的影子,有C的味道,中間有比其它語言多的糟粕,使用預處理辦法可以解決這些問題。其中Less[les]與Sass是CSS的預處理技術,而CoffeeScript、TypeScript則是javascript的預處理技術。
一、Less
1.1、概要
Less是一種動態樣式語言,Less 是一門 CSS 預處理語言,它擴展了 CSS 語言,增加了變數、Mixin、函數等特性,使 CSS 更易維護和擴展。
Less 將 CSS 賦予了動態語言的特性,如 變數, 繼承, 運算, 函數。LESS 既可以在 客戶端 上運行 (支持IE 6+, Webkit, Firefox),也可以藉助Node.js或者Rhino在服務端運行。 Less是一個JS庫,所以他可以在客戶端運行,相對Sass則必須在服務端藉助Ruby運行
中文網站: http://www.lesscss.net/
英文官網: http://lesscss.org
less源碼: https://github.com/cloudhead/less.js
github地址: https://github.com/less/less.js
1.2、變數
語法:@變數名:值;
1)、以@作為變數的起始標識,變數名由字母、數字、_和-組成
2)、沒有先定義後使用的規定;
3)、以最後定義的值為最終值;
4)、可用於rule值、rule屬性、rule屬性部件、選擇器、選擇器部件、字元串拼接;
5)、定義時 "@變數名: 變數值;" 的形式;引用時採用 "@變數名" 或 "@{變數名}" 的形式;
6)、存在作用域,局部作用域優先順序高於全局作用域。
@color: #4d926f; #header { color: @color; } #header { color: #4d926f; } @color: #253636; @color: #ff3636; //覆蓋第一次的定義 #header {color: @color;} //多次反覆解析 #header {color: #ff3636;}
編譯後:
#header { color: #ff3636; } #header { color: #4d926f; } #header { color: #ff3636; } #header { color: #ff3636; }
1.3、解析Less
1.3.1、線上處理
頁面中直接引用less的源碼,使用javascript動態翻譯,這樣在開發階段非常方便,但是在運行階段會影響效率,建議在開發階段使用less.js線上處理,項目穩定運行時將less文件預處理。
步驟一:
下載到less.js動態處理.less文件的javascript腳本,下載地址: https://github.com/less/less.js
步驟二:
在頁面中引入樣式與less.js文件,如下:
<link rel="stylesheet/less" type="text/css" href="styles.less"> <script src="less.js" type="text/javascript"></script>
測試運行
示例代碼:
style1.less
/*1定義變數*/ @color:red; @bgColor:lightgreen; /*定義變數color,值為red*/ .cls11{ color: @color; } @color:lightblue; /*重新定義,覆蓋前面的定義,後定義的起作用*/ .cls12 { background: @bgColor; border: 2px solid @color; }
de2.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Less</title> <link rel="stylesheet/less" type="text/css" href="css/style1.less"> <script src="js/less/less.min.js" type="text/javascript"></script> </head> <body> <div id="div1" class="cls12"> Hello Less </div> </body> </html>
運行效果:
從上圖可以看出less.js將style1.less文件翻譯後變成了一個標準的CSS內部樣式表。
1.3.2、預處理
線上處理的效率低,預處理就是將less文件先翻譯成標準的CSS文件,再引入到項目中,處理的辦法有許多:
方法一:使用lessc
a)、請先在電腦上安裝node.js,下載地址: https://nodejs.org/en/
a)、安裝lessc
使用npm(node.js package management)node.js包管理器
在命令行模式下輸入安裝指令:npm install less -g
使用lessc翻譯less文件為css文件:
lessc styles.less 顯示
lessc styles.less > styles.css 生成文件
參數 –x 普通壓縮
參數 -h 幫助
-x的壓縮方法已經被棄用,建議使用清理插件。
方法二:使用工具軟體
能夠翻譯Less的工具軟體有不少,這裡介紹:Koala
Koala是一個開源的預處理語言圖形編譯工具,目前已支持Less、Sass、Compass與CoffeeScript。
功能特性:
多語言支持: 支持Less、Sass、Compass與CoffeeScript。
實時監聽與編譯: 在後臺監聽文件的變動,檢測到文件被修改後將自動進行編譯。
編譯選項支持: 可以設置與自定義你需要的編譯選項。
壓縮支持: Less、Sass可直接編譯生成壓縮後的css代碼。
錯誤提示: 編譯中如果遇到錯誤,Koala將在右下角提示並顯示出具體的出錯地方,方便開發者快速定位。
跨平臺: Windows、Mac、Linux完美支持。
安裝Koala
在Koala官網根據你的系統平臺下載對應的版本。Linux系統要求已安裝好ruby運行環境。
下載地址: http://koala-app.com/
註意:路徑中不要使用中文,切記!
方法三:使用IDE插件
如果使用Eclipse,Hbuilder,Visual Studio等開發工具可以安裝插件完成自動翻譯功能,這裡使用HBuilder,在工具->插件下可以選擇安裝,如下圖所示:
使用方法:
新建Less文件,保存後會自己生成對應的CSS文件。
1.4、混入(Mixins)
類似函數或巨集
定義函數,@radius是參數,3px是預設值
.borderRadius(@radius:3px){
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
border-radius: @radius;
}
使用函數,帶參數
#header { .borderRadius(10px); }
不帶參數使用預設參數
.btn { .borderRadius}
註意:
a)、可以不使用參數 .wrap(){…} .pre{ .wrap },也可以使用多個參數
b)、內置變數@arguments代表所有參數(運行時)的值 .boxShadow(@x:0,@y:0,@blur:1px,@color:#000){ box-shadow: @arguments; }
註意,在參數沒有預設值的前提下使用@arguments調用時必須賦值,否則會導致整個頁面內的less語法出錯而失效。
c)、Mixins必須使用ID或者類,即#xx或.xx,否則無效。
Less示例代碼:
/*混入(Mixins)*/ /*定義*/ .circle(@width:100px, @color:lightblue) { width: @width; height: @width; background: @color; border-radius: @width/2; float: left; } .boxShadow(@x:0, @y:0, @blur:1px, @color:#000) { box-shadow: @arguments; } /*調用*/ .cls21 { .circle(); /*預設值*/ } .cls22 { .circle(200px,lightgreen); /*帶參數*/ .boxShadow(5px,5px); } .cls23 { .circle(300px); /*帶一個參數*/ }
HTML頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Less</title> <link rel="stylesheet" type="text/css" href="css/style2.css" /> </head> <body> <div id="div1" class="cls21"> </div> <div id="div1" class="cls22"> </div> <div id="div1" class="cls23"> </div> </body> </html>
翻譯結果:
/*調用*/ .cls21 { width: 100px; height: 100px; background: lightblue; border-radius: 50px; float: left;/*預設值*/ } .cls22 { width: 200px; height: 200px; background: lightgreen; border-radius: 100px; float: left; /*帶參數*/ box-shadow: 5px 5px 1px #000; } .cls23 { width: 300px; height: 300px; background: lightblue; border-radius: 150px; float: left;/*帶一個參數*/ } /*# sourceMappingURL=style2.css.map */
運行效果:
1.5、嵌套
允許將多個CSS選擇器嵌套在一起,&表示當前選擇器的父選擇器
#header {
&.fl{ float: left; }
.mln { margin-left: 0; }
}
生成
#header.fl{float: left;}
#header .mln {margin-left: 0;}
示例:
/*嵌套*/ #parent { color: red; .sub11 { background: green; } &.sub12 { width: 100px; } .sub13 { height: 200px; .sub131 { font-size: 10px; } } }
結果:
/*嵌套*/ #parent { color: red; } #parent .sub11 { background: green; } #parent.sub12 { width: 100px; } #parent .sub13 { height: 200px; } #parent .sub13 .sub131 { font-size: 10px; }
1.6、運算
運算主要是針對任何數字、顏色、變數的操作,支持加、減、乘、除、()或者更複雜的綜合運算;
@init: #111111;
@transition: @init*2;
.switchColor { color: @transition; }
算術運算示例:
/*運算*/ @base: 5%; @filler: @base * 2; @other: @base + @filler; @base-color:lightblue; .cls41{ color: #888 / 4; background-color: @base-color + #111; height: 100% / 2 + @filler; }
運行結果:
.cls41 { color: #222222; background-color: #bee9f7; height: 60%; }
1.7、函數
Less 提供了許多用於轉換顏色,處理字元串和進行算術運算的函數
.lightColor{lighten(@color, 10%); }
更多函數: http://www.lesscss.net/functions/
示例:
/*函數*/ .cls51 { /*將一個資源內嵌到樣式文件,如果開啟了ieCompat選項,而且資源文件的體積過大,或者是在瀏覽器中使用,則會使用url()進行回退。如果沒有指定MIME,則Node.js會使用MIME包來決定正確的MIME。*/ background: data-uri('../img/yes.gif') no-repeat; height: 20px; } .cls52 { /*增加一定數值的顏色亮度。*/ background: lighten(blue,20%); }
翻譯結果:
/*函數*/ .cls51 { /*將一個資源內嵌到樣式文件,如果開啟了ieCompat選項,而且資源文件的體積過大,或者是在瀏覽器中使用,則會使用url()進行回退。如果沒有指定MIME,則Node.js會使用MIME包來決定正確的MIME。*/ background: url("data:null;base64,R0lGODlhDAAMAKIAAMznjyJ6Gu732TKGFq7ZTF+nDI7JBf///yH5BAAAAAAALAAAAAAMAAwAAAM8eCdAZgQItdy7RAlXyhidBhjdEAQD1ZDHGVDQUyivMlws1d6xR6EFyKi06xgkHA8oSJhscI8mhWGJTA4JADs=") no-repeat; height: 20px; } .cls52 { /*增加一定數值的顏色亮度。*/ background: #6666ff; }
運行效果:
1.8、繼承
示例代碼:
/*繼承*/ .animal { background-color: black; color: white; } .bear { &:extend(.animal); background-color: brown; } .mouse{ &:extend(.animal); }
翻譯結果:
/*繼承*/ .animal, .bear, .mouse { background-color: black; color: white; } .bear { background-color: brown; }
1.9、作用域
同一級的變數後者覆蓋前者,內部變數優先順序高於外部變數,變數只在同一個文件中生效。
示例:
/*作用域*/ @len:10px; .cls61{ @len:20px; height:@len; } .cls62{ width:@len; } @len:30px; .cls63{ height: @len; }
結果:
.cls61 { height: 20px; } .cls62 { width: 30px; } .cls63 { height: 30px; }
1.10、註釋
示例:
/*註釋*/ .cls71{ width: 100px; //單行註釋,CSS中不允許單行註釋,Less允許 height:100px; /* 多行註釋,CSS與Less都允許 */ }
結果:
/*註釋*/ .cls71 { width: 100px; height: 100px;/* 多行註釋,CSS與Less都允許 */ }
二、Sass
Sass與Less類似類似也是一種CSS的預編譯語言,他出現的更晚,但功能更加強大,Sass 有兩種語法。 第一種被稱為 SCSS (Sassy CSS),是一個 CSS3 語法的擴充版本;第二種比較老的語法成為縮排語法(或者就稱為 "Sass"), 提供了一種更簡潔的 CSS 書寫方式特點如下:
特點:
1)、不能直接在頁面中解析,需要使用ruby預先翻譯成css文件,而Less可以線上動態翻譯。
2)、Sass功能更加強大,擁有流控語句等Less不具備的功能
3)、完全相容 CSS3,在 CSS 語言基礎上添加了擴展功能,比如變數、嵌套 (nesting)、混合 (mixin)
在使用時Sass的尾碼名為scss,本文全部使用scss的語法,可以安裝Koala直接解析,不需要去搭建ruby環境,Koala已封裝好。
下載地址: http://koala-app.com/
2.1、變數
sass中可以定義變數,方便統一修改和維護
Sass代碼:
/*變數*/ $width:1004px; $color:blue; .cls11 { width: $width; height: $width/2; background: $color; } $width:100px; $color:red; .cls12 { $color:green; width: $width; height: $width/2; background: $color; }
CSS代碼:
.cls11 { width: 1004px; height: 502px; background: blue; } .cls12 { width: 100px; height: 50px; background: green; }
2.2、嵌套
sass可以進行選擇器的嵌套,表示層級關係,看起來很優雅整齊。
Sass代碼:
.cls21 { width: 100px; .cls22{ height: 200px; } .cls23 { color:blue; } }
CSS代碼:
.cls21 { width: 100px; } .cls21 .cls22 { height: 200px; } .cls21 .cls23 { color: blue; }
2.3、導入
sass中如導入其他sass文件,最後編譯為一個css文件,優於純css的@import
reset.scss
$zero:0; $PI:3.14; * { margin: $zero; padding: $zero; } body,html{ height: 100%; }
Sass代碼:
@import "reset"; .cls31 { /*height: zero; */ /*error*/ }
CSS代碼:
* { margin: 0; padding: 0; } body, html { height: 100%; } .cls31 { /*height: zero; */ /*error*/ }
2.4、mixin 混入
sass中可用mixin定義一些代碼片段,且可傳參數,方便日後根據需求調用。從此處理css3的首碼相容輕鬆便捷。定義時使用關鍵字@mixin,調用時使用@include
SCSS樣式:
@mixin circle($size:100px,$color:lightblue){ width: $size; height: $size; border-radius: $size/2; background: $color; } .cls41{ @include circle(); } .cls42{ @include circle(150px); } .cls43{ @include circle(200px,lightgreen); }
CSS樣式:
.cls41 { width: 100px; height: 100px; border-radius: 50px; background: lightblue; } .cls42 { width: 150px; height: 150px; border-radius: 75px; background: lightblue; } .cls43 { width: 200px; height: 200px; border-radius: 100px; background: lightgreen; }
2.5、擴展/繼承
sass可通過@extend來實現代碼組合聲明,使代碼更加優越簡潔。
SCSS樣式:
.state { background: blue; border: 1px solid lightblue; } .success{ @extend .state; background: green; } .error { @extend .state; border: 2px solid red; }
CSS樣式:
.state, .success, .error { background: blue; border: 1px solid lightblue; } .success { background: green; } .error { border: 2px solid red; }
2.6、運算
SCSS樣式:
.cls61 { width: (100px+10px)/2-20px%7px+1px*8; }
CSS樣式:
.cls61 { width: 57px; }
2.7、函數
sass中集成了大量的顏色函數,讓變換顏色更加簡單。
SCSS樣式:
$pcolor: #999ccc; .cls71 a { color: $pcolor; &:hover { background: darken($pcolor,15%); /*變暗15%*/ color: lighten($pcolor,5%); /*變亮5%*/ }
CSS樣式:
.cls71 a { color: #999ccc; } .cls71 a:hover { background: #666bb3; color: #aaacd5; }
2.8、流程式控制制
sass中和其它程式語言一樣也擁有流程式控制制語句,如if,for,each,while,指令,函數等。
SCSS樣式:
$blur: lightblue; @for $i from 1 through 10 { .font-#{$i} { /*計算字體大小*/ font-size: 12px+$i*2px; /*顏色變暗*/ color: darken($blur,$i*2); /*如果i是3的倍數,則下劃線*/ @if $i%3==0 { text-decoration: underline; } } }
CSS樣式:
/*8*/ .font-1 { font-size: 14px; color: #a5d4e4; } .font-2 { font-size: 16px; color: #9dd1e1; } .font-3 { font-size: 18px; color: #96cddf; text-decoration: underline; } .font-4 { font-size: 20px; color: #8ec9dc; } .font-5 { font-size: 22px; color: #86c5da; } .font-6 { font-size: 24px; color: #7ec2d8; text-decoration: underline; } .font-7 { font-size: 26px; color: #76bed5; } .font-8 { font-size: 28px; color: #6ebad3; } .font-9 { font-size: 30px; color: #67b7d1; text-decoration: underline; } .font-10 { font-size: 32px; color: #5fb3ce; }
HTML頁面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="css/style3.css" /> </head> <body style="padding: 10px;"> <div class="font-1">Hello SASS!</div> <div class="font-2">Hello SASS!</div> <div class="font-3">Hello SASS!</div> <div class="font-4">Hello SASS!</div> <div class="font-5">Hello SASS!</div> <div class="font-6">Hello SASS!</div> <div class="font-7">Hello SASS!</div> <div class="font-8">Hello SASS!</div> <div class="font-9">Hello SASS!</div> <div class="font-10">Hello SASS!</div> </body> </html>
運行效果:
更多內容請參考:http://www.sass-zh.com/
三、CoffeeScript
javascript變得日益重要,但有很多明顯的缺點,藉助一種中間語言轉譯出優雅的javascript是解決這些問題的方法。如CoffeeScript,TypeScript。
Coffee Script是JavaScript的轉譯語言。瞭解JavaScript的發展歷程:https://news.cnblogs.com/n/558565/。
Coffee的特點:
CoffeeScript語法類似 Ruby ,可以被編譯成 JavaScript
CoffeeScript取JavaScript之精華,而拋棄了諸如全局變數聲明、with等容易出錯的部分
CoffeeScript是JavaScript與程式員之間的橋梁,程式員看到的是優雅的CoffeeScript介面,使得編程更簡潔,寫法更隨意
更少,更緊湊,和更清晰的代碼
通過規避和改變對JavaScript中不良部分的使用,只留下精華,讓代碼減少出錯率,更容易維護
在很多常用模式的實現上採用了JavaScript中的最佳實踐
CoffeeScript生成的JavaScript代碼都可以完全通過JSLint的檢測
中文網: http://coffee-script.org/
源碼:https://github.com/coffee-js/coffee-script
3.1、安裝
CoffeeScript 編譯器本身是 CoffeeScript 寫的, 使用了 Jison parser generator. 命令行版本的coffee是一個實用的 Node.js 工具。
安裝前你需要最新穩定版 Node.js, 和 npm (Node Package Manager)。藉助 npm 可以安裝 CoffeeScript:
npm install -g coffee-script
安裝之後, 你應該可以運行 coffee 命令以執行腳本, 編譯 .coffee 文件到 .js 文件, 和提供一個互動式的 REPL. coffee 命令有下列參數:
-c, --compile 編譯一個 .coffee 腳本到一個同名的 .js 文件.
-m, --map 隨 JavaScript 文件一起生成 source maps. 並且在 JavaScript 裡加上 sourceMappingURL 指令.
-i, --interactive 啟動一個互動式的 CoffeeScript 會話用來嘗試一些代碼片段. 等同於執行 coffee 而不加參數.
-o, --output [DIR] 將所有編譯後的 JavaScript 文件寫到指定文件夾. 與 --compile 或 --watch 搭配使用.
-j, --join [FILE] 編譯之前, 按參數傳入順序連接所有腳本到一起, 編譯後寫到指定的文件. 對於編譯大型項目有用.
-w, --watch 監視文件改變, 任何文件更新時重新執行命令.
-p, --print JavaScript 直接列印到 stdout 而不是寫到一個文件.
-s, --stdio 將 CoffeeScript 傳遞到 STDIN 後從 STDOUT 獲取 JavaScript. 對其他語言寫的進程有好處. 比如:
cat src/cake.coffee | coffee -sc
-l, --literate 將代碼作為 Literate CoffeeScript 解析. 只會在從 stdio 直接傳入代碼或者處理某些沒有尾碼的文件名需要寫明這點.
-e, --eval 直接從命令行編譯和列印一小段 CoffeeScript. 比如:
coffee -e "console.log num for num in [10..1]"
-b, --bare 編譯到 JavaScript 時去掉頂層函數的包裹.
-t, --tokens 不對 CoffeeScript 進行解析, 僅僅進行 lex, 列印出 token stream: [IDENTIFIER square] [ASSIGN =] [PARAM_START (] ...
-n, --nodes 不對 CoffeeScript 進行編譯, 僅僅 lex 和解析, 列印 parse tree:
--nodejs node 命令有一些實用的參數, 比如
--debug, --debug-brk, --max-stack-size, 和 --expose-gc. 用這個參數直接把參數轉發到 Node.js. 重覆使用 --nodejs 來傳遞多個參數.
3.2、使用
1、編輯coffee腳本,尾碼為coffee,代碼如下:
# 賦值: number = 42 opposite = true # 條件: number = -42 if opposite # 函數: square = (x) -> x * x # 數組: list = [1, 2, 3, 4, 5] # 對象: math = root: Math.sqrt square: square cube: (x) -> x * square x # Splats: race = (winner, runners...) -> print winner, runners # 存在性: alert "I knew it!" if elvis? # 數組 推導(comprehensions): cubes = (math.cube num for num in list)
將coffeescript翻譯成javascript的方法如下:
a)、使用IDE插件直接翻譯
翻譯成javascript後的腳本如下:
(function() { var cubes, list, math, num, number, opposite, race, square, slice = [].slice; number = 42; opposite = true; if (opposite) { number = -42; } square = function(x) { return x * x; }; list = [1, 2, 3, 4, 5]; math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); } }; race = function() { var runners, winner; winner = arguments[0], runners = 2 <= arguments.length ? slice.call(arguments, 1) : []; return print(winner, runners); }; if (typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } cubes = (function() { var i, len, results; results = []; for (i = 0, len = list.length; i < len; i++) { num = list[i]; results.push(math.cube(num)); } return results; })(); }).call(this);
b)、命令行翻譯
翻譯後的結果與上文相同,-c是參數表示編譯的意思,-w是監聽文件的變化,文件發生變化後將立即編譯。
面向對象示例:
class Animal constructor: (@name) -> move: (meters) -> alert @name + " moved #{meters}m." class Snake extends Animal move: -> alert "Slithering..." super 5 class Horse extends Animal move: -> alert "Galloping..." super 45 sam = new Snake "Sammy the Python" tom = new Horse "Tommy the Palomino" sam.move() tom.move()
翻譯後的javascript:
(function() { var Animal, Horse, Snake, sam, tom, extend = function(child, parent) { for(var key in parent) { if(hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + (" moved " + meters + "m.")); }; return Animal; })(); Snake = (