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";