這篇文章主要介紹前端構(gòu)建CSS預(yù)處理器的示例分析,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

目前創(chuàng)新互聯(lián)已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、淶源網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
Less 是一門 CSS 預(yù)處理語(yǔ)言,它擴(kuò)充了 CSS 語(yǔ)言,增加了諸如變量、混合(mixin)、函數(shù)等功能,讓 CSS 更易維護(hù)、方便制作主題、擴(kuò)充。
Less 可以運(yùn)行在 Node、瀏覽器和 Rhino 平臺(tái)上。網(wǎng)上有很多第三方工具幫助你編譯 Less 源碼。
一、前言
說(shuō)到前端構(gòu)建怎能缺少CSS預(yù)處理器呢!其實(shí)CSS的預(yù)處理器有很多啦,比較出名的有Scss、Sass、Stylus和Less。(最近還聽說(shuō)出現(xiàn)了Autoprefixer等CSS后處理器,可參考@一絲的PPT)
眾多CSS預(yù)處理器中Less的語(yǔ)法最接近原生CSS,因此相對(duì)來(lái)說(shuō)更容易上手,假如有JS、C#等編程經(jīng)驗(yàn)的話,其實(shí)上述的幾種預(yù)處理器的學(xué)習(xí)成本也不會(huì)特別高。下面是我們這陣子的學(xué)習(xí)筆記,以便日后查閱。
最好的入門教程——官網(wǎng)地址:http://lesscss.org/
最佳實(shí)踐之一——Bootstrap
由于內(nèi)容較多,特設(shè)目錄一坨:
二、搭建學(xué)習(xí)環(huán)境
三、內(nèi)聯(lián)樣式和外聯(lián)樣式
四、語(yǔ)法
1. 注釋
2. 變量(Variable)
列表類型
3. 嵌套(Nested)
4. 父選擇器引用(ParentSelector)
5. 導(dǎo)入指令(Import)
6. 繼承(Extend)
7. 混合(Mixin)
8. 選擇、循環(huán)作業(yè)控制
五、運(yùn)算符
六、函數(shù)
七、通過(guò)Lessc將Less引入開發(fā)環(huán)境
八、實(shí)戰(zhàn)一下
九、與Grunt結(jié)合
十、總結(jié)
二、搭建學(xué)習(xí)環(huán)境
搭建Less的學(xué)習(xí)環(huán)境非常簡(jiǎn)單,只需在</body>標(biāo)簽前通過(guò)<script type="text/javascript" src="less.js"></script>引入處理器即可實(shí)現(xiàn)瀏覽器端中將less預(yù)編譯為css樣式。更有效的方式是通過(guò)如下代碼監(jiān)測(cè)less樣式,自動(dòng)編譯為css樣式,從而減少我們修改less代碼后需按F5后才看到實(shí)際效果的繁瑣步驟。
<script>less = { env: 'development'};</script>
<script src="less.js"></script>
<script>less.watch();</script>三、內(nèi)聯(lián)樣式和外聯(lián)樣式
基于我們現(xiàn)在使用的是瀏覽器端進(jìn)行預(yù)編譯,因此Less可用于內(nèi)聯(lián)樣式和外聯(lián)樣式當(dāng)中。
內(nèi)聯(lián)樣式如下:
<style type="text/less"> // less 代碼 </style>
外聯(lián)樣式引入如下:
<link rel="stylesheet/less" type="text/css" href="文件.less" rel="external nofollow" />
四、語(yǔ)法
1. 注釋
// 單行注釋,不會(huì)作為最終輸出 /* 多行注釋,以原生CSS的/*注釋....*/形式作為最終輸出 */
2. 變量(Variable)
Less中的變量有以下規(guī)則:
以@作為變量的起始標(biāo)識(shí),變量名由字母、數(shù)字、_和-組成
沒(méi)有先定義后使用的規(guī)定;
以最后定義的值為最終值;
可用于rule值、rule屬性、rule屬性部件、選擇器、選擇器部件、字符串拼接;
定義時(shí) "@變量名: 變量值;" 的形式;引用時(shí)采用 "@變量名" 或 "@{變量名}" 的形式;
存在作用域,局部作用域優(yōu)先級(jí)高于全局作用域。
Less源碼:
@color: color;
@dialog: .dialog;
@suffix: fix;
// 空格將被忽略,若要保留空格則需要使用單引號(hào)或雙引號(hào)
@hi: 'hello ';
@dear: there ;
.dialog{
// 用于 rule屬性部件,必須使用"@{變量名}" 的形式
background-@{color}: #888;
// 用于 rule屬性,必須使用"@{變量名}" 的形式
@{color}: blue;
}
// 用于 選擇器,必須使用"@{變量名}" 的形式
@{dialog}{
width: 200px;
}
@{dialog}::after{
content: ': @{hi}@{dear}!'; // 用于 字符串拼接,必須使用"@{變量名}" 的形式
}
@h: 1000px;
// 用于 選擇器部件,必須使用"@{變量名}" 的形式
.ie-@{suffix}{
@h: 30px; // 存在作用域,局部作用域優(yōu)先級(jí)高于全局作用域。
height: @h; // 用于 屬性值,兩種形式均可使用
line-height: 30px;
}
// 1. 以@作為變量的起始標(biāo)識(shí),變量名由字母、數(shù)字、_和-組成
// 2. 沒(méi)有先定義后使用的規(guī)定;
@dialog-border-color: #666;
@dialog-border-width: 10px;
@dialog-border-width: 1px; // 3. 以最后定義的值為最終值;最終輸出:
.dialog {
background-color: #888;
color: blue;
}
.dialog {
width: 200px;
}
.dialog::after {
content: ': hello there!';
}
.ie-fix {
height: 30px;
line-height: 30px;
}列表類型
less變量除了支持#FFF,12px,12,test等單值類型外,還支持列表類型,通過(guò)內(nèi)置函數(shù)extract通過(guò)索引獲取列表元素,通過(guò)內(nèi)置函數(shù)length獲取列表的元素個(gè)數(shù)
@colors: #FFF, #0F0, #F0F;
.skin{
color: extract(@colors, 0);
height: 12px * length(@colors);
}最終輸出:
.skin{
color: #FFF;
height: 36px;
}3. 嵌套(Nested)
Less源碼:
.main{
padding: 10px;
> div {
width: 100px;
}
.aside {
width: 200px;
}
}最終輸出:
.main {
padding: 10px;
}
.main > div {
width: 100px;
}
.main .aside {
width: 200px;
}4. 父選擇器引用(ParentSelector)
采用&引用完整的父選擇器
可通過(guò)追加和預(yù)追加的方式加工&,從而生成新的選擇器
通過(guò)&::after等方式添加偽元素、偽類樣式規(guī)則集合
同一個(gè)選擇器可使用多個(gè)&
通過(guò)在選擇器后添加 "空格&"的方式,可將當(dāng)前選擇器排列到最前面
&指向組選擇器時(shí),會(huì)生成新的組選擇器
Less源碼:
/*
* 采用&引用完整的父選擇器
* 可通過(guò)追加和預(yù)追加的方式加工&,從而生成新的選擇器
* 通過(guò)&::after等方式添加偽元素樣式規(guī)則集合
* 同一個(gè)選擇器可使用多個(gè)&
* 通過(guò)在選擇器后添加 "空格&"的方式,可將當(dāng)前選擇器排列到最前面
*/
@bg: #aaa;
#ps1 .btn{
background-color: @bg;
border-radius: 5px;
&:hover{
background-color: lighten(@bg, 30%);
cursor: pointer;
}
&-msg, &-eof{
color: blue;
}
.no-borderradius &{
background-image: url('img/btn-bg.png');
}
}
/*
* &指向組選擇器時(shí),會(huì)生成新的組選擇器
*/
#dummy1, .dummy1{
&:hover{
color: red;
}
& + &{
font-size: 12px;
}
}最終輸出:
/*
* 采用&引用完整的父選擇器
* 可通過(guò)追加和預(yù)追加的方式加工&,從而生成新的選擇器
* 通過(guò)&::after等方式添加偽元素樣式規(guī)則集合
* 同一個(gè)選擇器可使用多個(gè)&
* 通過(guò)在選擇器后添加 "空格&"的方式,可將當(dāng)前選擇器排列到最前面
*/
#ps1 .btn {
background-color: #aaaaaa;
border-radius: 5px;
}
#ps1 .btn:hover {
background-color: #f6f6f6;
cursor: pointer;
}
#ps1 .btn-msg,
#ps1 .btn-eof {
color: blue;
}
.no-borderradius #ps1 .btn {
background-image: url('img/btn-bg.png');
}
/*
* &指向組選擇器時(shí),會(huì)生成新的組選擇器
*/
#dummy1:hover,
.dummy1:hover {
color: red;
}
#dummy1 + #dummy1,
#dummy1 + .dummy1,
.dummy1 + #dummy1,
.dummy1 + .dummy1 {
font-size: 12px;
}5. 導(dǎo)入指令(Import)
less樣式文件可通過(guò) @import '文件路徑'; 引入外部的less文件。
注意:
不帶擴(kuò)展名或帶非.less的擴(kuò)展名均被視為less文件;
@import可出現(xiàn)在任何位置,而不像css的@import那樣只能放在文件第一行。
另外@import還提供了6個(gè)可選配置項(xiàng)(分別為reference,inline,less,css,once,multiple),用來(lái)改變引入文件的特性。語(yǔ)法為: @import (reference) '文件路徑'; 。下面為各配置項(xiàng)的具體說(shuō)明:
1. @import (reference) "文件路徑";
將引入的文件作為樣式庫(kù)使用,因此文件中樣式不會(huì)被直接編譯為css樣式規(guī)則。當(dāng)前樣式文件通過(guò)extend和mixins的方式引用樣式庫(kù)的內(nèi)容。
2. @import (inline) "文件路徑";
用于引入與less不兼容的css文件,通過(guò)inline配置告知編譯器不對(duì)引入的文件進(jìn)行編譯處理,直接輸出到最終輸出。注意:引入的文件和當(dāng)前文件會(huì)被編譯為一個(gè)樣式樣式
3. @import (less) "文件路徑";
默認(rèn)使用該配置項(xiàng),表示引入的文件為less文件。
4. @import (css) "文件路徑";
表示當(dāng)前操作為CSS中的@import操作。當(dāng)前文件會(huì)輸出一個(gè)樣式文件,而被引入的文件自身為一個(gè)獨(dú)立的樣式文件
5. @import (once) "文件路徑";
默認(rèn)使用該配置項(xiàng),表示對(duì)同一個(gè)資源僅引入一次。
6. @import (multiple) "文件路徑"; 表示對(duì)同一資源可引入多次。
6. 繼承(Extend)
有兩種語(yǔ)法形式, <selector>:extend(<parentSelector>){} 和 <selector>{ &:extend(<parentSelector>); }
Less源碼:
.animal{
color: #fff;
}
/* 語(yǔ)法1:<selector>:extend(<parentSelector>){} */
.bear:extend(.animal){
width: 100px;
height: 100px;
}
/* 語(yǔ)法2:<selector>{ &:extend(<parentSelector>); } */
.deer{
&:extend(.animal);
width: 50px;
height: 50px;
}最終輸出:
.animal,
.bear,
.deer {
color: #fff;
}
/* 語(yǔ)法1:<selector>:extend(<parentSelector>){} */
.bear {
width: 100px;
height: 100px;
}
/* 語(yǔ)法2:<selector>{ &:extend(<parentSelector>); } */
.deer {
width: 50px;
height: 50px;
}注意事項(xiàng):
6.1. 父選擇器必須嚴(yán)格匹配,除了屬性選擇器中屬性值引號(hào)不必匹配外,或添加all關(guān)鍵字外。
Less源碼:
*.parent{
height: 100px;
.hair{
color: #f27;
}
[name=eyes]{
color: #768;
}
}
// 匹配失敗
.son:extend(.parent){}
.son:extend(.hair){}
// 匹配成功
.son:extend(*.parent [name='eyes']){}
.son:extend(*.parent [name="eyes"]){}
// all關(guān)鍵字會(huì)匹配所有包含parentSelector內(nèi)容的選擇器,并以selector替換parentSelector來(lái)生成新的選擇器
// 下面的內(nèi)容會(huì)生成 *.son,*.son .hair,*.son [name=eyes]三個(gè)新的選擇器
.son:extend(.parent all){}最終輸出:
*.parent,
*.son {
height: 100px;
}
*.parent .hair,
*.son .hair {
color: #f27;
}
*.parent [name=eyes],
.son,
.son,
*.son [name=eyes] {
color: #768;
}6.2. 父選擇器不支持變量形式
Less源碼:
@p1: .parent1;
@p2: .parent2;
.parent1{
height: 100px;
}
@{p2}{
height: 200px;
}
// 匹配失敗
// 形式1,不支持以變量作入?yún)?
.son1:extend(@{p1}){}
// 形式2,不支持以變量作為選擇器的規(guī)則集合
.son1:extend(.parent2){}
// 匹配成功
.son2:extend(.parent1){}
@s3: son3;
.@{s3}:extend(.parent1){}最終輸出:
.parent1,
.son2,
.son3 {
height: 100px;
}
.parent2 {
height: 200px;
}6.3. media query影響繼承的作用域
6.3.1. media query內(nèi)的extend操作,僅能繼承當(dāng)前塊的其他選擇器樣式。
注意:不能extend當(dāng)前media query塊內(nèi)部的子media query塊中的選擇器樣式;但可以extend父media query塊的選擇器樣式。
Less源碼:
.parent1{
height: 200px;
}
@media screen{
.parent1{
height: 100px;
}
// 無(wú)法繼承子media query塊的選擇器樣式
.son1:extend(.parent2){}
@media (min-width: 1023px){
// 繼承父media query塊的選擇器樣式
.son2:extend(.parent1){}
.parent2{
width: 200px;
}
}
}最終輸出:
.parent1 {
height: 200px;
}
@media screen {
.parent1 {
height: 100px;
}
}
@media screen and (min-width: 1023px) {
.parent2 {
width: 200px;
}
}6.3.2. 非media query內(nèi)的extend操作,將會(huì)繼承所有media query中匹配的選擇器樣式。
Less源碼:
@media screen{
.parent{
height: 100px;
}
@media (min-width: 1023px){
.parent{
width: 200px;
}
}
}
.son:extend(.parent){}最終輸出:
@media screen {
.parent,
.son {
height: 100px;
}
}
@media screen and (min-width: 1023px) {
.parent,
.son {
width: 200px;
}
}6.4. 增強(qiáng)的mixin定義mixin時(shí)僅能使用類選擇器和ID選擇器,而extend操作可對(duì)應(yīng)所有的選擇器,因此當(dāng)沒(méi)有動(dòng)態(tài)入?yún)⒍中枰愡x擇器和ID選擇器以外的選擇器時(shí),可使用extend來(lái)實(shí)現(xiàn)mixin的功能。
7. 混合(Mixin)
Mixin相當(dāng)于macro,會(huì)將樣式規(guī)則內(nèi)聯(lián)到調(diào)用的位置中。而Less中的mixin有以下的注意點(diǎn):
7.1. 類選擇器、ID選擇器自動(dòng)被定義為mixin,而且具有命名空間;
Less源碼:
.animal{
.human{
#fsjohnhuang{
.hair{
color: #000;
}
}
}
}
.front-end-monkey{
// 或者.animal.human#fsjohnhuang.hair();
// 或者.animal>.human>#fsjohnhuang>.hair;
// 或者.animal>.human>#fsjohnhuang>.hair();
// 即可調(diào)用mixin
.animal.human#fsjohnhuang.hair;
}最終輸出:
.animal .human #fsjohnhuang .hair {
color: #000;
}
.front-end-monkey {
color: #000;
}7.2. 顯示定義不帶參數(shù)和帶參數(shù)的樣式庫(kù)(mixin庫(kù)),不會(huì)輸出到最終輸出中,僅供調(diào)用;
Less源碼:
// 定義不帶參數(shù)的mixin
.animal(){
color: #000;
}
// 定義帶參數(shù)的mixin
// 注意:由于,和;均可用于作為參數(shù)分隔符,但由于如background、border等樣式屬性支持屬性值組,而,則作為屬性值組元素分隔符,因此推薦使用;作為參數(shù)分隔符
.dog(@type; @age){
height: @type * @age * 12px;
}
// 定義帶參數(shù)默認(rèn)值的mixin
.cat(@type; @age:1){
height: @type * @age * 5px;
}
// 調(diào)用才會(huì)出現(xiàn)在最終輸出
.chihuahua{
.dog(1;2);
}最終輸出:
.chihuahua {
height: 24px;
}7.3. mixin內(nèi)置兩個(gè)特殊的對(duì)象 @arguments 和 @reset 。@arguments代表mixin的所有入?yún)?而@reset代表mixin的...入?yún)?shù)組。
Less源碼:
.dog(@type;@age;@rest...){
height: @type * @age * 12px;
border: @rest;
}
.cat(@solid;@w;@color){
border: @arguments;
}
.chihuahua{
.dog(1;2;solid;1px;red);
}
.mimi{
.cat(solid;2px;blue);
}最終輸出:
.chihuahua {
height: 24px;
border: solid 1px red;
}
.mimi {
border: solid 2px blue;
}7.4. mixin的重載可定義多個(gè)同名mixin,調(diào)用時(shí)只要參數(shù)數(shù)量匹配則會(huì)執(zhí)行相應(yīng)的mixin。
Less源碼:
.dog(@name){
&::after{
content: @name;
}
}
.dog(@name;@age){
height: @age * 4px;
}
.dog(@name;@age;@width:20px){
height: @age * 12px;
width: @width;
}
// 僅匹配到 .dog(@name){
.one-dog{
.dog('chihuahua');
}
// 匹配到.dog(@name;@age) 和 .dog(@name;@age;@width:20px)
.two-three-dog{
.dog('two-three-dog', 2);
}
// 參數(shù)的模式匹配
// 當(dāng)?shù)谝粎?shù)值為mimi時(shí)調(diào)用該mixin
.cat(mimi, @age){
height: @age * 22px;
}
// 當(dāng)?shù)谝粎?shù)值為mini時(shí)調(diào)用該mixin
.cat(mini, @age){
height: @age * 12px;
}
// 不管第一參數(shù)值為啥均調(diào)用該mixin
.cat(@any, @age){
color: #f3c;
}
.mycat{
.cat(mini, 1);
}最終輸出:
.one-dog::after {
content: 'chihuahua';
}
.two-three-dog {
height: 8px;
height: 24px;
width: 20px;
}
.mycat {
height: 12px;
color: #f3c;
}8. 選擇、循環(huán)作業(yè)控制
Less中通過(guò)混合(Mixin)后的when關(guān)鍵字來(lái)提供選擇的作業(yè)控制,通過(guò)遞歸來(lái)實(shí)現(xiàn)循環(huán)的作業(yè)控制。
Less源碼:
// 條件匹配
// true值匹配,僅實(shí)參為true時(shí)才匹配成功
.truth(@a) when (@a){
&::after{
content: @a;
}
}
// 匹配成功
.truth2{
.truth(true);
}
// 匹配失敗
.truth3{
.truth(#fff);
}
/* 類型判斷函數(shù)
* iscolor
* isnumber
* isstring
* iskeyword
* isurl
*/
.bear(@color) when (iscolor(@color)){
color: @color;
}
/* 單位判斷函數(shù)
* ispixel
* ispercentage
* isem
* isunit
*/
.bear(@height) when (ispixel(@height)){
height: @height;
}
// =,>,>=,<=,< 關(guān)系運(yùn)算符
.rich(@h) when (@h > 1000){
height: @h;
}
// and、not、or(使用,號(hào)表示) 邏輯運(yùn)算符
.huge(@h, @w) when (@h > 180) and (@w > 180){
height: @h;
width: @w;
}
// 使用& when()實(shí)現(xiàn)if語(yǔ)句
@debug: true;
& when (@debug){
div{
border: solid 1px red;
}
}
// 通過(guò)遞歸實(shí)現(xiàn)循環(huán)
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}最終輸出:
.truth2::after {
content: true;
}
/* 類型判斷函數(shù)
* iscolor
* isnumber
* isstring
* iskeyword
* isurl
*/
/* 單位判斷函數(shù)
* ispixel
* ispercentage
* isem
* isunit
*/
div {
border: solid 1px red;
}
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}五、運(yùn)算符
Less還支持+、-、*、/運(yùn)算符。但對(duì)單位不一致的運(yùn)算數(shù)進(jìn)行運(yùn)算要注意以下兩點(diǎn):
1. 運(yùn)算數(shù)與運(yùn)算符間必須用空格分隔;
2. 以第一個(gè)運(yùn)算數(shù)的單位作為運(yùn)算結(jié)果的單位;
Less源碼:
// 運(yùn)算數(shù)與運(yùn)算符間沒(méi)有空格
@fail: 1px +2em;
.fail{
height: @fail;
}
@success1: 1px + 2em;
.success1{
height: @success1;
}
@success2: 2px + 1em;
.success2{
height: @success2;
}最終輸出:
.fail{
height: 1px 2em;
}
.success1{
height: 3px;
}
.success2{
height: 3em;
}六、函數(shù)
Less為我們提供了一個(gè)功能強(qiáng)大的內(nèi)置函數(shù)庫(kù),其中絕大部分為顏色處理函數(shù)。下面著重介紹Misc Function中的default函數(shù)、String Function中的escape函數(shù)和顏色處理函數(shù)。
1. default函數(shù)
示例:
// for teenager
.person(@age) when (@age <= 19) and (@age >=13){
height: @age * 10px;
}
// for child
.person(@age) when (@age <13){
height: @age * 6px;
}
// for adult
.person(@age) when (default()){
height: 180px;
}
.son{
.person(10);
}
.daughter{
person(17);
}
.father{
.person(27);
}最終輸出:
.son{
height: 60px;
}
.daughter{
height: 170px;
}
.father{
height: 180px;
}雖然上述示例邏輯上不合理。但可以看出default函數(shù)用于條件控制當(dāng)中,充當(dāng)else或switch語(yǔ)句中default的角色。
通過(guò)官網(wǎng)提供的綜合示例我們可以更好理解它的用法:
// Less源碼
.x {
.m(red) {case-1: darkred}
.m(blue) {case-2: darkblue}
.m(@x) when (iscolor(@x)) and (default()) {default-color: @x}
.m('foo') {case-1: I am 'foo'}
.m('bar') {case-2: I am 'bar'}
.m(@x) when (isstring(@x)) and (default()) {default-string: and I am the default}
&-blue {.m(blue)}
&-green {.m(green)}
&-foo {.m('foo')}
&-baz {.m('baz')}
}
// 最終輸出
.x-blue {
case-2: #00008b;
}
.x-green {
default-color: #008000;
}
.x-foo {
case-1: I am 'foo';
}
.x-baz {
default-string: and I am the default;
}注意:
1. default函數(shù)必須在條件控制語(yǔ)句當(dāng)中使用;
2. default函數(shù)可實(shí)現(xiàn)比else更復(fù)雜的功能,如下:
// Less源碼
.mixin(@value) when (ispixel(@value)) {width: @value}
.mixin(@value) when not(default()) {padding: (@value / 5)}
div-1 {
.mixin(100px);
}
div-2 {
/* ... */
.mixin(100%);
}
// 最終輸出:
div-1 {
width: 100px;
padding: 20px;
}
div-2 {
/* ... */
}2. escape函數(shù)
顧名思義就是對(duì)字符串中的特定字符進(jìn)行編碼,該函數(shù)將對(duì)\<space\>, #, ^, (, ), {, }, |, :, >, <, ;, ], [ 和 =字符進(jìn)行編碼。
3. 顏色處理函數(shù)
顏色處理函數(shù)又分為四大類:顏色定義函數(shù)(Color Definition)、顏色通道值獲取函數(shù)(Color Channel)、顏色通道值修改函數(shù)(Color Operation Function)、混色函數(shù)(Color Blending)。
這里僅僅介紹常用的lighten和darken函數(shù)。
lighten(color, amount) ,color為顏色,amount為增加的亮度值,取值范圍為0-100%。
darken(color, amount) ,color為顏色,amount為減少的亮度值,取值范圍為0-100%。
七、通過(guò)Lessc將Less引入開發(fā)環(huán)境
到這里我想大家已經(jīng)對(duì)Less有一定程度的了解,并希望在將其加入你的開發(fā)工具包中。但通過(guò)less.js將Less解析器引入到瀏覽器肯定是不適合開發(fā)的,而cli工具lessc更適合開發(fā)環(huán)境中使用。在使用之前我們先要通過(guò)npm來(lái)安裝less。
npm install -g less
然后我們就可以通過(guò) lessc [option option=parameter ...] <source> [destination] 的命令格式來(lái)調(diào)用lessc了!
lessc的option選項(xiàng)較多,我將主要的選項(xiàng)分為lessc命令信息相關(guān)、sourcemap相關(guān)、@import指令相關(guān)和插件相關(guān)四類。
1. lessc命令信息相關(guān)
lessc -h ,獲取lessc命令的幫助信息;
lessc -v ,獲取lessc命令的版本號(hào)。
2. sourcemap相關(guān)
由于在瀏覽器直接查看和操作的是CSS樣式規(guī)則,而我們開發(fā)時(shí)使用的Less代碼,這會(huì)導(dǎo)致難以找到CSS樣式規(guī)則所對(duì)應(yīng)的Less代碼從而增大調(diào)試難度。而sourcemap就是為了解決這一痛點(diǎn)而提出的技術(shù)解決方案,其原理就是通過(guò)一個(gè)map文件來(lái)保存兩個(gè)文件中代碼的對(duì)應(yīng)關(guān)系,然后支持sourcemap的瀏覽器的devTools中就會(huì)根據(jù)這些對(duì)應(yīng)關(guān)系來(lái)定位相應(yīng)的Less代碼。(Chrome和FF均支持sourcemap,IE11及以下均不支持)
若對(duì)sourcemap不太了解的可以參考《前端構(gòu)建:Source Maps詳解》
--source-map ,生成與生成的css同名的sourcemap文件(例如生成的css文件為main.css,那么sourcemap文件就是main.css.map),且與css文件位于同一目錄下;
--source-map=<sourcemap文件路徑> ,自定義sourcemap文件的路徑;
--source-map-rootpath=<sourcemap文件中sources屬性值的路徑前綴> ,假如main.less文件位于src/less下,而生成的css和sourcemap文件位于bin/style下,那么就需要修改sourcemap文件中用于指向less文件路徑的sources屬性值,瀏覽器才能通過(guò)sourcemap文件查找到less文件。上述例子的命令為:
lessc --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css
--source-map-map-inline ,以data URI Scheme的形式將sourcemap文件內(nèi)容內(nèi)嵌到css文件中。
--source-map-url=<css文件中指向sourcemap文件的url> ,默認(rèn)情況下css文件的最后一行會(huì)插入如 /*# sourceMappingURL=main.css.map */ 的內(nèi)容來(lái)指向sourcemap文件,而該選項(xiàng)則可修改sourceMappingURL的值。
3. @import指令相關(guān)
--include-path=<path>[;<path>]* ,通過(guò)@import指令引入外部less或css等文件時(shí)存在引入的文件路徑到底是以哪個(gè)目錄作為參考的問(wèn)題,我們可以通過(guò)該選項(xiàng)來(lái)指定參考目錄,當(dāng)存在多個(gè)參考目錄時(shí),使用;號(hào)分隔。
--relative-urls 或 -ru ,用于保持樣式庫(kù)中的圖片等資源的相對(duì)路徑。示例:
# main.less
@import "files/backgrounds.less";
# files/backgrounds.less
.icon-1 {
background-image: url('images/lamp-post.png');
}不使用該選項(xiàng)時(shí):
.icon-1 {
background-image: url('images/lamp-post.png');
}使用該選項(xiàng)時(shí):
.icon-1 {
background-image: url('files/images/lamp-post.png');
}4. 插件相關(guān)
lessc以插件的形式來(lái)增強(qiáng)其功能,下面僅介紹clean-css插件,其他插件請(qǐng)參考/upload/otherpic73/76434
|-- src 源碼
| |-- less
| | |-- main.less
| |-- index.html
|-- bin 編譯后的文件
| |-- style
| |-- main.css
| |-- main.css.map
| |-- index.html
|-- dist 發(fā)布文件
|-- lib
| |-- less
| |-- img
| |-- nav.png
|-- app
|-- style
| |--main.css
|-- index.html
index.html文件內(nèi)容:
<html> <head> <title></title> <link rel="stylesheet" type="text/css" href="style/main.css" rel="external nofollow" /> </head> <body> <div class="nav"> </div> </body> </html>
樣式庫(kù)base.less文件內(nèi)容:
.base-nav{
height: 50px;
background-image: url(img/nav.png);
}
.base-debug{
border: solid 5px red;
}main.less文件內(nèi)容:
@import (reference) "base.less";
@env:release; //編譯模式:release或debug
/* 導(dǎo)航欄 */
.nav:extend(.base-nav){
// 編譯模式為debug時(shí)采用該樣式
& when (@env=debug){
.base-debug();
}
}我們一般將工程代碼級(jí)別的產(chǎn)出分為源碼、可執(zhí)行代碼 和可發(fā)布代碼 三種,而可執(zhí)行代碼和可發(fā)布代碼的構(gòu)建需求是不同的,因此構(gòu)建方式也有所區(qū)別,也就是lessc使用的選項(xiàng)也會(huì)不同。下面將針對(duì)不同的產(chǎn)出物來(lái)介紹lessc的使用。
1. 可執(zhí)行代碼
我將可執(zhí)行代碼部分再細(xì)分為release和debug兩種編譯模式,可以看到通過(guò)變量@env來(lái)實(shí)現(xiàn)不同模式下采用不同的樣式規(guī)則。默認(rèn)采用release模式編譯源碼。
lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css
在執(zhí)行l(wèi)essc命令時(shí)通過(guò)選項(xiàng)--modify-var="env=debug"即可以debug模式編譯源碼。
lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/ --modify-var="env=debug" src/less/main.less bin/style/main.css
可以看到上述編譯過(guò)程中均會(huì)生成sourcemap文件以便調(diào)試使用。
2. 可發(fā)布代碼
對(duì)于發(fā)布的內(nèi)容我們會(huì)對(duì)其進(jìn)行壓縮處理
lessc --include-path=lib/less --clean-css="advanced" --relative-urls src/less/main.less dist/app/style/main.css
由于sourcemap文件僅在開發(fā)階段有用,因此生成發(fā)布代碼時(shí)就不要生成了。
完整的構(gòu)建文件build.bat如下:
@echo off cls goto :%1 :bin echo Building...... ::remove subitems of bin rd /S /Q bin ::copy html files xcopy /y src\*.html bin\ ::compile less to css cmd /C lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/main.less src/less/main.less bin/style/main.css echo Building is over! goto :over :debug echo Building...... ::remove subitems of bin rd /S /Q bin ::copy html files xcopy /y src\*.html bin\ ::compile less to css cmd /C lessc --include-path=lib/less --relative-urls --source-map --source-map-rootpath=../../src/less/ --modify-var="env=debug" src/less/main.less bin/style/main.css echo Building is over! goto :over :dist echo Deploying...... ::remove subitems of dist rd /S /Q dist ::copy lib xcopy /y lib\less\img dist\lib\less\img\ ::copy html files xcopy /y src\*.html dist\app\ ::compile less to css cmd /C lessc --include-path=lib/less --clean-css="advanced" --relative-urls src/less/main.less dist/app/style/main.css echo Deploying is over! :over
然后在CMD中輸入 build bin 、 build debug 或 build dist 即可構(gòu)建工程了!
sample@github
九、與Grunt結(jié)合
我們沿用第八節(jié)的工程目錄結(jié)構(gòu)來(lái)演示。
首先我們要將npm的package.json添加到工程中,然后安裝grunt及其插件(grunt-contrib-less,less-plugin-clean-css,grunt-contrib-clean,grunt-contrib-copy),現(xiàn)在我們的工程結(jié)構(gòu)應(yīng)該是這樣的。
sample-grunt
|-- package.json
|-- Gruntfile.js
|-- node_modules
|-- lib 第三方依賴庫(kù)
| |-- less
| |-- base.less
| |-- img
| |-- nav.png
|-- src 源碼
| |-- less
| | |-- main.less
| |-- index.html
|-- bin 編譯后的文件
| |-- style
| |-- main.css
| |-- main.css.map
| |-- index.html
|-- dist 發(fā)布文件
|-- lib
| |-- less
| |-- img
| |-- nav.png
|-- app
|-- style
| |--main.css
|-- index.html
其中用于將Less編譯為CSS的插件為grunt-contrib-less, 下面我們對(duì)應(yīng)第八章的內(nèi)容來(lái)介紹該插件的選項(xiàng)。
sourcemap相關(guān):
{Boolean} sourceMap,對(duì)應(yīng)lessc中屬性值為true/false的--source-map選項(xiàng);
{String} sourceMapFilename,對(duì)應(yīng)lessc中屬性值為String的--source-map選項(xiàng);
{String} sourceMapRootPath,對(duì)應(yīng)lessc的--source-map-rootpath選項(xiàng);
{String} sourceMapURL,對(duì)應(yīng)lessc的--source-map-url選項(xiàng);
{Boolean} outputSourceFiles,,對(duì)應(yīng)lessc的--source-map-map-inline選項(xiàng);
@import指令相關(guān):
{Array|String} paths,對(duì)應(yīng)lessc的--include-path選項(xiàng);
{Boolean} relativeUrls,對(duì)應(yīng)lessc的--relative-urls選項(xiàng);
插件相關(guān):
{Array} plugins,數(shù)組元素為插件實(shí)例。
Gruntfile.js內(nèi)容如下:
'use strict'
var lessBinDebugOpts = {
sourceMap: true,
sourceMapRootpath: '../../'
},
debug = {env: 'debug'}
module.exports = function(grunt){
grunt.initConfig({
clean: {
options:{
force: true
},
bin: ['bin'],
dist: ['dist']
},
copy: {
bin: {
files: [
{expand: true, cwd: 'src/', src: '*.html', dest: 'bin/'}
]
},
dist: {
files:[
{expand: true, cwd: 'lib/', src: '**', dest: 'dist/lib/'},
{expand: true, cwd: 'src/', src: '*.html', dest: 'dist/app'}
]
}
},
less: {
options:{
paths: 'lib/less',
relativeUrls: true
},
bin:{
options: (delete lessBinDebugOpts.modifyVars, lessBinDebugOpts),
files: {
'bin/style/main.css': 'src/less/main.less'
}
},
debug:{
options: (lessBinDebugOpts.modifyVars = debug, lessBinDebugOpts),
files: {
'bin/style/main.css': 'src/less/main.less'
}
},
dist:{
options:{
plugins: [new (require('less-plugin-clean-css'))({advanced: true})]
},
files: {
'dist/app/style/main.css': 'src/less/main.less'
}
}
}
})
grunt.loadNpmTasks('grunt-contrib-less')
grunt.loadNpmTasks('grunt-contrib-copy')
grunt.loadNpmTasks('grunt-contrib-clean')
var task = function(){
var name = this.name
, tasks = ['clean', 'copy', 'less']
, targets = tasks.map(function(v, i, m){
var target = name === 'debug' && v !== 'less' ? 'bin' : name
return v + ':' + target
})
grunt.task.run(targets)
}
grunt.registerTask('bin', task)
grunt.registerTask('debug', task)
grunt.registerTask('dist', task)
}sample-grunt@github
十、總結(jié)
到這里我只能和大家說(shuō)一聲,“辛苦了各位,終于看完了耶!”。但正如標(biāo)題所說(shuō),此刻無(wú)論是對(duì)less的使用,還是將其融入我們的開發(fā)工作流,我們均是入了個(gè)門而已。那應(yīng)該如何進(jìn)階呢?那就是
;; 定義進(jìn)階過(guò)程 (defn becomeGeek [progress] (.log js/console "實(shí)踐->總結(jié)->參考最佳實(shí)踐") (if (> 100 progress) (becomeGeek (+ 1 progress)) )) ;; 努力吧騷年! (becomeGeek 1)
以上是“前端構(gòu)建CSS預(yù)處理器的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站標(biāo)題:前端構(gòu)建CSS預(yù)處理器的示例分析
轉(zhuǎn)載源于:http://chinadenli.net/article32/pieepc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)、做網(wǎng)站、品牌網(wǎng)站制作、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)