1. 程式人生 > 其它 >Less學習筆記【未完成】

Less學習筆記【未完成】

鎮樓圖

Pixiv:

注:此blog至少建立在一定的CSS基礎之上,其中選擇器更加重要



〇、LESS(Leaner Style Sheets)是什麼?

是CSS的前處理器,因為CSS編寫起來確實特別麻煩,因此有了CSS前處理器的工具來簡化編寫程式碼時間

其他比較有名的CSS預處理還有SASS、SCSS、Stylus

引入

<link rel="stylesheet/less" href="styles.less" />
<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.11.1/less.min.js" ></script>
<!-- 瀏覽器環境,引入Less.js,或者自己下載Less.js -->
npm install -g less
> lessc styles.less styles.css
<!-- Node.js環境 -->

由於LESS僅僅加了些許擴充套件,因此學習起來很簡單,這也是為什麼CSS的blog還沒寫完我先寫LESS的情況。不必擔心相容性,LESS幾乎支援一切瀏覽器

問題一:如果在客戶端環境下使用或多或少必然會有一定上效能的消耗

問題二:LESS由於使用了Ajax必須必須在http(s)協議下使用,直接本地檔案執行js檔案是不會有任何效果的!!!!!

Koala

可以下載Koala用於將Less檔案轉譯成css檔案,由此可以使用生成的css檔案而不必使用less檔案也能避免上述所說的問題

但是需要注意LESS在Koala裡的版本是非常低的,為了避免因版本導致的錯誤,建議您安裝nodejs後安裝less,具體安裝步驟這裡就不再闡述了

LESS檔案編寫

首先建立個less字尾的檔案,然後和CSS一樣就可以開始寫LESS加持的程式碼了

但需要注意每個.less檔案是獨立編譯的,其中的任何定義的東西都是不可相互訪問的,也就是1.less中定義的變數不可以在2.less中訪問


一、變數

儘管在CSS3中也存在變數機制,但其支援可能並不如LESS

變數定義屬性值

變數可以去定義屬性值,以【@變數名】的形式定義,呼叫屬性值也是【@變數名】

@width: 10px;
@height: 50px;

.father {
    width: @width;
    height: @height;
}

個人理解:@指標

變數本身是通過@去定義的,其中@可以理解為指標

對上一個例子稍加改動可以很直觀地說明這個問題

@width: 10px;
@height: 50px;

.father {
    width: width;
    height: @height;
}

當我用koala編譯後它的結果如下圖

其中加了@的被解成了50px,沒加@的就是其原樣

在下面變數定義變數能感受這種類似於指標的用法

指標與變數賦值

變數同樣可以作為其他變數的變數

@color1: grey;
@color3: color1;
//不加@就是其本身

p{
    color: @@color3;
    //color3就是color3
    //@color3被解成了color1
    //@@color3被解成了grey
}

但是LESS似乎只支援到兩層@,當博主嘗試@@@時報錯了

在理解變數的本質後應該知道如何去賦值變數

@color1: grey;
@color3: @color1;
//加@就是其屬性值從而完成賦值操作

p{
    color: @color3;
}

變數定義屬性名和部分屬性名(v1.6.0)

除了屬性值以外變數還可以定義很多內容,其中只要不是去定義屬性值的,在呼叫時必須以【@{變數名}】的形式去呼叫

LESS不像正統語言一樣有嚴格的語法規範,在【@{變數名}】時它無法支援多重"指標",使用【@@{variety}】或是【@{@{variety}}】看上去可能符合指標猜想的語法都是會報錯的

@p1: color;

.father {
    @{p1}: red;
}

此外還可以去定義部分屬性名,很多CSS屬性會用-符號區分這時候可以通過LESS這樣定義

@v: left;

.div1 {
    margin-@{v}: 0;
}

變數定義選擇器(V1.4.0)

@firbox: father;
@element: a;

.@{firbox} > @{element}[data-v="1"]:visited {
	color: red;
}

變數定義url(的一部分)(v1.4.0)

由於url網址部分一般都是會有相同的字首部分,也可以定義url字串在url裡使用

@images: "../images";

html {
    background: url("@{images}/1.jpg");
}

變數作用域(Lazy evaluation)

只要保證呼叫變數時能從當前層級往上能找到即可

@{selector} {
    @{attr}: @value;
    @value: red;
}
@attr: color;
@selector: p;
//雖然定義在下
//但能從呼叫處往上尋找時能搜查到此層級

另外這種搜查機制也對於同名變數來說符合就近原則

p {
    @v: #123;
	color: @v;
    @v: #456;
    //結果為#456
    //它會優先搜查一遍
    //搜查後#456當然覆蓋了#123
}
@v: #789;
//由於呼叫那一層已經搜查到了
//因此無需向上搜查此層

個人理解:$解引用(v3.0.0)

在新版本3.0.0下可以使用$符號來解引用一個要作為樣式的屬性

在某些情況下可能更加節省程式碼量。

我個人認為這種語法適用於“同類屬性”的情況,所謂同類屬性是指功能性一樣但應用範圍不同,如下例的color、background-color都是用於顏色設定只不過一個是文字一個是背景罷了

div {
    margin: 0px;
    padding: $margin;
    color: #fff;
    background-color: $color;
    //解引用無需定義新的變數
}

基於上面@假設為指標的理解,這裡我理解為解引用,但理解歸理解,實際操作和之前指標一樣無法實現理解上的語法


二、屬性值運算

賦值

上面有講過便不再贅述

@a: 10;
@b: @a;

空格附加

比如CSS中margin多個屬性值來說是通過空格來間隔開的,LESS提供這樣一個機制去實現多個屬性值空格相加

通過+_符號以空格形式附加屬性值

@v1: 10px;
@v2: 20px;
@v3: 30px;
@v4: 40px;
.div1{
    /*已忽略其他必要屬性*/
    margin+_: @v1;
    margin+_: @v2;
    margin+_: @v3;
    margin+_: @v4;
}

.div2{
	margin: @v1 @v2 @v3 @v4;
    //雖然也能通過這種方式附加
    //這與後面的函式相關聯
    //比如設定一個函式附加屬性值
    //這樣的機制無法實現而+_可以
}

逗號附加

還有一類屬性值必須要通過逗號隔開,LESS是通過+符號以逗號形式附加屬性值

這裡不作演示了

簡單運算

對於Less而言它可以進行一些簡單的運算,當然在Less內建函式中還內建大量數學函式可以實現非常複雜的運算

@size: 10;
@o1: @size + 5;
@o2: @size - 5;
@o3: @size * 5;

div {
	d1: @o1;
	d2: @o2;
	d3: @o3;
}

三、巢狀(Nesting)

巢狀

巢狀是非常常用的工具,可以使大量CSS難以看清楚的結構,在Less中變得顯而易見

father {
    display: flow-root;
    .first,.second {
        width: 400px;
        height: 200px;
    }
    .first {
        margin-bottom: 100px;
        background: purple;
    }
    .second {
        margin-top: 200px;
        background: green;
    }
}
//比如這裡顯而易見的,father中套了first、second
//而CSS處理的話只會分開,當數量足夠多時便很難分清結構了

引用父元素

巢狀雖然實現了父類→子類的,但無法實現子類→父類,&提供了從子類→父類的功能

這一般用於類、複雜運算、屬性值選擇器或是偽類,如下例只需要&即可實現不同偽類的情況,同樣其結構也更加清晰

a {
    font-size: 20px;
    background: pink;
    &:link {
        color: red;
    }
    &:visited {
        color: green;
    }
    &:active {
        color: hotpink;
    }
    &:hover {
        color: blue;
    }
}

所謂引用是真的完全引用,不會有太大的語法限制

也會有這種形式的LESS程式碼

.area {
    &-1 {}
    &-2 {}
    //類
    & &[data-v1="3"]:hover{}
    .father &{}
    //假設.father盒子巢狀.area盒子
    //那麼可以實現這種巢狀的樣式
    //複雜運算
}
//通過這種方式可以很好地整合程式碼

你可能會擔心還會生成一個.area的父類,但實際上LESS會進行優化,只要你的選擇裡沒有任何樣式那麼它就不會生成此類。.area下面全都是選擇器,並不是具體的樣式,因此它不會生成.area這一個父類,可以放心大膽地使用這種程式碼

引用父元素的組合

上面闡述了引用父元素下其子元素能夠如何如何之類的,但是其父元素也是可以參與運算的,這樣會導致更加靈活的巢狀,但目前我個人沒找到這種實際應用的場景

.a,.b > .c{
    & & {}
}

因為CSS除了組合運算以外不管是偽類也好屬性選擇器也好,它本質上都只是一個選擇器,但組合選擇器是多個。

核心在於組合運算,上面例子僅僅是組合了.a和.b > .c兩個選擇器,使用& &{}會是什麼?

LESS會把每一個&嘗試組合中的所有選擇器

結果會是

.a .a,
.a .b > .c,
.b > .c .a,
.b > .c .b > .c {
	/*某個樣式*/
}

這裡簡單用數學計算下,假設LESS程式碼裡定義選擇器時有n個&符號,而父類組合的有m個選擇器,那麼其組合後總共會去組合\(m^n\)個選擇器


四、混合(Mixins)

函式

這裡博主統一稱為函式,一個樣式規則集可以當作函式。函式內部可以寫好一個樣式模板,某個屬性需要時呼叫即可

但是需要注意函式的命名必須是類選擇器或是id選擇器的命名

.a , #b {
    //既可以當作某個樣式渲染(如果HTML中滿足的話)
    //也可以當作函式來呼叫
    color: red;
    font-size: 19px;
}

.father {
    #b();
}

由於版本原因,呼叫的時候()是可選的,在未來版本可能會被刪除

.a , #b {
    color: red;
    font-size: 19px;
}

.father {
    .a;
	//不用()也能生效
}

引數

上面的語法也會當作樣式來渲染,但有時候可能就想當作函式,這時候只需要在函式後加上()即可

.c() {
    //不會生成.c的CSS程式碼
    color: red;
    &:link {
        color: red;
    }
    &:visited {
        color: green;
    }
    &:active {
        color: hotpink;
    }
    &:hover {
        color: blue;
    }
}

a {
    .c;//此時&引用是a
}

此外可以設定形參來傳遞實現更復雜的操作

.color(@color){
    color: @color;
}
.fontsize(@size: 16px){
    //可以設定預設值
    font-size: @size;
}

p {
    .color(black);
    //未設定預設值必須填寫引數
	.fontsize();
}

在寫預設值有時並不止一個屬性值

如果多個屬性值是要用,分隔的,此時可以用;分隔引數

如果多個屬性值是用空格分隔的,可以用,也可以用;分隔引數

.a(@border:3px solid red ; @margin:0 auto){
    //用;分隔引數
	border: @border;
	margin: @margin;
}

div {
	.a;
}

呼叫引數時可以指定形參名,這時呼叫無需注意順序

.a(@border:3px solid red;@margin:0 auto){
  border: @border;
  margin: @margin;
}
div{
  .a(@margin:10%);
}

函式的巢狀

由於巢狀語法的存在,函式也是可以巢狀的

LESS提供了三種等價性的呼叫方式

分別是.father > .son,.father .son和.father.son

這三種形式沒有任何區別,它會呼叫所有下一級子函式的樣式

.a(){
    color:blue;
    font-size: 18px;
    .b(){
        padding: 0;
        color:red;
        .b(){
            margin: 0;
        }
    }
    .b(){
        background: black;
        color:blue;
        //LESS輸出並不會去覆蓋樣式
        //因此結果裡會有兩個color
    }
}

.div1 {
	.a.b;
}

.div2 {
	.a > .b .b();
}

呼叫的函式只會在這一層而不會出現其父類或是子類的函式,若要使用子類的函式必須去呼叫才行

守衛(Guard)

在LESS中when的保護條件稱為是Guard,其中只有滿足when條件才可執行,不滿足不會被執行

.a() when(true){
	color: red;
}
p {
    .a;
}

.b() when(@mode = 1){
	color: blue;
}
p {
    @mode: 2;
    .b;
    //@mode為2不滿足
    //因此會拒絕.b()函式呼叫
}

在1.5以後守衛機制不僅可以適用於函式還可以適用於選擇器上

@my-option: true;
& when (@my-option = true) {
    //備註:若不存在&則不會有父元素
    //但可以用不存在的元素專門用作條件語句
  	button {
    	color: white;
  	}
  	a {
    	color: blue;
  	}
}

@arguments

@arguments可以將所有引數同時傳遞

.pos(@top: 0; @right: 0; @bottom: 0; @left: 0) {
  margin: @arguments;
  padding: @arguments;
    //同時傳遞了@top @right @bottom @left
    //且引數之間是空格附加的
}
div {
.pos(50px,30px,50px,20px);
}

@rest以及不定引數的實現

用...可以表示不定引數,@rest可以指定剩餘的可變引數

但CSS的屬性值絕大部分都是有限個,因此應用場景可能不多

.minin()){}//無參
.minin(@rest...){}//任意個引數
.minin(@a){}//無參或一個引數
.minin(@a;@rest...){}//任意個引數
.minin(@a: 1;@rest...){}//至少一個引數

模式匹配

LESS的函式是隻要滿足就會實現,因此可以設定一個常量作為形參

當滿足該常量時便會執行,否則不會執行,可以作為不同情況的函式

.mixin(dark; @color) {
  color: darken(@color, 10%);
}
.mixin(light; @color) {
  color: lighten(@color, 10%);
}

div {
  .mixin(light, #888);
   .mixin(dark,#aaa);
    //執行drak的.mixin函式
}

實現分支結構

LESS中是通過保護條件來實現分支語句的,如下面實現採用更大寬度的程式碼

.max(@a; @b) when (@a > @b) { width: @a }
.max(@a; @b) when (@a < @b) { width: @b }

此外條件之間也可以使用and、or、not這三類邏輯運算子

對於迴圈結構以及函式的返回值博主認為應用場景不多故此忽略,詳細可在官網中檢視器語法

實現雜湊表(v3.5.0)

在3.5.0的版本中變數可以去儲存函式,基於這個機制可以實現雜湊表

#Font(){
    //定義#Font例項內建size、color資料
    .size(){
        style1: 12px;
        style2: 15px;
        style3: 18px;
    }
    .color(){
        style1: black;
        style2: white;
        style3: grey;
    }
}

p{
	@f-c: #Font.color();
    color: @f-c[style1];
	font-size: #Font.size()[style3];
	//可以直接通過函式去索引相當於雜湊表
}

選擇器、屬性名作為引數

我之前用less確確實實有這麼一個需求,需要針對不同類名某些相同屬性設定不同的屬性值

.f(@selector,@value){
    .@{selector} {
        font-size: @value;
    }
}
.f(m1,12px);
.f(m2,14px);
.f(m3,16px);

此時可以將選擇器作為一個形參來設定屬性值,屬性名同理這裡不再贅述

函式作為引數

函式本身也是可以作為形參物件的,這在封裝某些程式碼時會非常有用

.media(@rules1,@rules2) {
	@media screen and (max-width: 799px) {
		@rules1()
	}
  	@media screen and (min-width: 800px)  {
      	@rules2();
  	}
}
.f(){
	font-size: 18px;
}
.g(){
	font-size: 24px;
}
* {
	.media(.f(),.g());
    //備註:必須加()否則出錯
}

五、擴充套件(Extend)【未完成】

Less中有一個特殊的偽類——extend,它用於實現組合運算

因為有時僅僅是巢狀,混合並不能完全滿足開發需求,某些時候使用擴充套件能夠減少巢狀、混合所帶來的重複程式碼

擴充套件

nav ul {
  &:extend(.inline);
  background: blue;
}
.inline {
  color: red;
}

六、其他【未完成】

@import宣告(1.4.0)

與CSS不同的是Less的@import可以隨意在任意地方宣告

Less可以去呼叫其他樣式檔案,呼叫後其文件原本全域性變數的作用域會改成當前文件

@pref: "../lessheader";

p {
    font-size: @size2;
}

@import "@{pref}/header1.less"
/*假設@size2在header1.less中
  這裡提供了一種類似於標頭檔案的宣告方式
  可以去管理Less的變數、函式
*/

[1]對檔案的處理

​ 如果發現是css檔案則會認為是CSS檔案而匯入,如果是其他字尾名或是無後綴名則會認為是Less檔案而匯入

[2]匯入可選項

​ Less的import提供了些許選項設定,可以進一步地加強import功能

選項 說明
once 預設,只包含一次檔案
css 視為CSS檔案(無論字尾名如何)
less 視為LESS檔案(無論字尾名如何)
optional 找不到檔案時繼續編譯而不是直接報錯
multiple 多次包含檔案
inline 輸出但不編譯
reference 編譯但不輸出
@pref: "../lessheader";

p {
    font-size: @size2;
}

@import(reference) "@{pref}/header1.less";
@import(inline,optional) "normalizev8.0.1.css";


參考教程

LESS

尚矽谷