less 新手入門(一) 變數、extend 擴充套件
變數
1.定義
使用 @ 符號來定義變數 ,在Less中開頭是 @ 則是變數,關於變數的命名方法,大家可以參考js中命名的規則,畢竟是做前端的,有著統一的習慣有助於我們統一風格。個人推薦變數名的命名規則使用駝峰命名法。第一個單詞首寫字母小寫,從第二個開始,單詞首寫字母大寫。如boxAaa,boxBbbb,boxContainer,……,當然也是可是使用香腸命名法用下劃線“_”來命名。如,box_main,border_bottom,……
2.使用
在樣式屬性值中使用時,直接用 @variable 即可呼叫變數;在其他地方,包括選擇器名稱、屬性名稱、URL和@import語句使用時,變數必須以插值的形式使用,
例如:
@variable: 200px; //定義變數作為樣式屬性值使用
@classname: .nav_a; //變數值不可用中劃線,此變數作為插值用於選擇器名稱
@{classname}{ //作為插值 必須加 {}
width: @variable; //作為屬性值直接呼叫
}
輸出:
.nav_a {
width: 200px;
}
3. 變數特點:
變數是懶載入的,不要求一定在使用之前宣告。
4. 在存在多個同名變數時,變數如何獲取值?
和css規則類似,在同時定義一個變數兩次時,會在使用變數的地方,從當前範圍向上搜尋,使用變數最後定義內的屬性值。
@var: 0;
.class1 {
@var: 1;
.class {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
編譯輸出
.class1 .class {
three: 3;
}
.class {
one: 1;
}
5. 變數的其它使用技巧:初始值
在定義變數時可以給變數賦一個初始值,後期在使用中通過重新定義或函式 來覆蓋原本的初始值
Extend 擴充套件
:extend是一個偽類,使用它的選擇器,將和它引用的選擇器一起使用它引用的選擇器的樣式,如:先定義一個擴充套件的選擇器,我們就叫它 .a,然後定義一個選擇器 .b(用來擴充套件),在 .a內使用 :extend 擴充套件,程式碼如下
.a{
&:extend(.b); //這裡的 & 為 父選擇符,代表的 父選擇符 .a 擴充套件 .b
font-size: 12px;
}
.b{
font-weight: bold;
}
輸出:
.a {
font-size: 12px;
}
.b,
.a {
font-weight: bold; //這裡 a 擴充套件也引用了 b 的樣式
}
注意:如果這裡的 .b 內沒有定義任何樣式,那麼編譯後的css中, 不會有 .b 的任何輸出,相應的 .a 也不會擴充套件到任何樣式
1. :extend 語法
:extend()可以附加到選擇器後面,也可以放到樣式規則中,它看起來就像是一個選擇器的偽類,在使用的時候我們可以選擇性的加上 關鍵字 all
語法示例:
.a:extend(.b){} //方法一:附加到選擇器後
.a{
&:extend(.b) // 方法二:寫在樣式規則中
}
all關鍵字的使用詳解 見 第7條
2. :extend() 直接使用在選擇器後
每個選擇器可以使用多個 :extend() 語句, 但是所使用的 :extend() 語句必須放在選擇器末尾,下面詳細描述:
- 在選擇器之後:extend :pre:hover:extend(div pre)。
- 選擇器和擴充套件之間允許有空格:pre:hover :extend(div pre)。
- 允許多個擴充套件:pre:hover:extend(div pre):extend(.bucket tr)- 注意這是相同的pre:hover:extend(div pre, .bucket tr)
- 這是不允許的:pre:hover:extend(div pre).nth-child(odd)。 extend必須在選擇器末尾。
如果規則集包含多個選擇器,則它們中的任何一個選擇器都可以具有extend關鍵字。在一個規則集中擴充套件的多個選擇器:
.a,
.b:extend(.bag),
.c:extend(.bucket) {
// 這裡啊a,b,c 3個選擇器都可以使用 :extend
}
3. :extend()在樣式規則中使用
把 :extend() 放到多個選擇器共用的樣式規則集中,是把樣式擴充套件到每個選擇器的最佳選擇。
下面來個對比:
- 直接把: extend() 放到樣式規則中,
.a,
.c,
.d{
&:extend(.b);
}
.b{
font-size: 12rem;
}
輸出:
.b,
.a,
.c,
.d {
font-size: 12rem;
}
如果把 :extend 放在選擇器後,那麼需要單獨對 .a , .c , .d單獨處理,會增加程式碼量,後期維護也很繁瑣
.a:extend(.b){}
.c:extend(.b){}
.d:extend(.b){}
4. 擴充套件 巢狀選擇器
將:extend() 直接放在選擇器後,可以擴充套件巢狀選擇器樣式規則,示例:
.my-table{
.my-tr{
font-size: 50px;
}
}
.mt-other-table:extend(.my-table .my-tr){}
5. :extend中選擇符的精確匹配
預設情況下,:extend() 中查詢選擇器的原則是精準匹配,就算是 選擇器 在開始使用(例如 .class .a)也沒用;或者是兩個選擇符表示式韓式一樣,那在匹配過程中也沒有意義,:extend()中選擇器只能匹配到 具有相同形式的選擇器。唯一例外的是屬性選擇器中的 引號 ,Less知道它們具有相同的含義並匹配它們。
示例:
**.a.class,
.class.a,
.class>.a{
color: blue;
}
.test:extend(.class) {}**
編譯下,命令列中報錯了… 沒有匹配到 .class
$ lessc refer.less > refer.css
extend ' .class' has no matches
選擇器前面的符號是很重要的, 雖然 *.class{} 和.class{}是一樣的,但是在:extend(.class)中無法匹配到 *.class
*.class {
color: blue;
}
.noStar:extend(.class) {} // 不會匹配到 *.class
多個偽類在 :extend() 中的順序也很重要,選擇器link:hover:visited和link:visited:hover匹配相同的一組元素,但 :extend() 將它們視為不同。
link:hover:visited {
color: blue;
}
//此時無法匹配到link:hover:visited
.selector:extend(link:visited:hover) {}
6. 使用 n 的選擇器 、使用屬性篩選的選擇器
1n+3和n+3相當,但:extend不會匹配他們:
:nth-child(1n+3) {
color: blue;
}
.child:extend(n+3) {} // 無法匹配
在屬性選擇器中的引用型別無關緊要。以下所有都是相同的。
[title=identifier] {
color: blue;
}
[title='identifier'] {
color: blue;
}
[title="identifier"] {
color: blue;
}
.noQuote:extend([title=identifier]) {}
.singleQuote:extend([title='identifier']) {}
.doubleQuote:extend([title="identifier"]) {}
7. :extend() 中關鍵字 all的使用
在使用extend時,在末尾新增 all 關鍵字,它會告訴Less作為另一個選擇器的一部分匹配該選擇器。選擇器將被複制,只有選擇器的匹配部分將被替換為擴充套件,從而建立一個新的選擇器。
例:
.a.b.test,
.test.c {
color: orange;
}
.test {
&:hover {
color: green;
}
}
.replacement:extend(.test all) {}
輸出:
.a.b.test,
.test.c,
.a.b.replacement,
.replacement.c {
color: orange;
}
.test:hover,
.replacement:hover {
color: green;
}
8. 選擇器插值與extend
:extend不能將選擇器與變數相匹配。如果選擇器包含變數,擴充套件將忽略它;
變數無法與選擇器匹配:
@variable: .bucket; //定義變數
@{variable} { // 變數插值
color: blue;
}
//沒有做任何工作,此時無法匹配到 .selector
.some-class:extend(.bucket) {}
輸出:僅僅只輸出了 .selector 的樣式規則
.bucket {
color: blue;
}
但是,將 :extend 擴充套件直接寫在 變數選擇器後,可正常使用,將上例程式碼改為如下:
.bucket{
color: blue;
}
//此時有中劃線,將 . 移至變數插值前,否則會報錯
@variable: some-class;
// 在變數選擇器後使用 :extend ,正常編譯
[email protected]{variable}:extend(.bucket){}
正常編譯:
.bucket,
.some-class {
color: blue;
}
9. 作用範圍 / extend 在 @media 中的使用
- 在 media 媒體宣告中寫入的 extend 只匹配同一媒體宣告中的選擇器:
@media print {
.screenClass:extend(.selector) {} // extend inside media
.selector { // 這會被匹配到 - 以為和extend在同一個media內
color: black;
}
}
.selector { // 規則集在上一個樣式中 - extend 將忽略這
color: red;
}
@media screen {
.selector { // r規則集在另一個樣式中 - extend 將忽略這
color: blue;
}
}
輸出:
@media print {
.selector,
.screenClass { /* ruleset inside the same media was extended */
color: black;
}
}
.selector { /* ruleset on top of style sheet was ignored */
color: red;
}
@media screen {
.selector { /* ruleset inside another media was ignored */
color: blue;
}
}
- 在媒體宣告中寫入的 extend ,不匹配其巢狀宣告中的選擇器:
@media screen {
.screenClass:extend(.selector) {} // extend inside media
@media (min-width: 1023px) {
.selector { // css在media內部巢狀 - extend 將忽略它
color: blue;
}
}
}
輸出:
@media screen and (min-width: 1023px) {
/* ruleset inside another nested media was ignored */
.selector {
color: blue;
}
}
- 頂級 :extend 將匹配所有內容,包括巢狀媒體中的選擇器
@media screen {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
@media (min-width: 1023px) {
.selector { /* ruleset inside nested media - top level extend works */
color: blue;
}
}
}
.topLevel:extend(.selector) {} /* 定層級 :extend 匹配所有 */
輸出:
@media screen {
.selector,
.topLevel { /* ruleset inside media was extended */
color: blue;
}
}
@media screen and (min-width: 1023px) {
.selector,
.topLevel { /* ruleset inside nested media was extended */
color: blue;
}
}
10. 重複檢測 - Duplication Detection
在使用:extend 時,less目前沒有檢測重複的 功能
.alert-info,
.widget {
/* declarations */
}
.alert:extend(.alert-info, .widget) {}
輸出:
.alert-info,
.widget,
.alert,
.alert {
/* declarations */
}
11. Extend案例擴充套件
1.典型用例
典型的用例是避免在html新增 基本選擇器類別 。
例如,如果你有
.animal {
background-color: black;
color: white;
}
然後你想要一種重寫 background-color 的class類 ,這時你有兩個方法,第一種方法是:改變你的HTML,新增另一個選擇器類 bear
<a class="animal bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
background-color: brown;
}
第二種方法是:簡化html同時使用less的 :extend,例如
<a class="bear">Bear</a>
.animal {
background-color: black;
color: white;
}
.bear {
&:extend(.animal);
background-color: brown;
}
- 減少css大小
mixin將所有屬性複製到一個選擇器中,這會導致不必要的重複。因此,您可以使用 :extend 而不是mixin將選擇器移到您希望使用的屬性,這樣會大大減少生成的css。當使用mixin時:
.my-inline-block() {
display: inline-block;
font-size: 0;
}
.thing1 {
.my-inline-block;
}
.thing2 {
.my-inline-block;
}
輸出:
.thing1 {
display: inline-block;
font-size: 0;
}
.thing2 {
display: inline-block;
font-size: 0;
}
改寫使用 :extend( )
.my-inline-block {
display: inline-block;
font-size: 0;
}
.thing1 {
&:extend(.my-inline-block);
}
.thing2 {
&:extend(.my-inline-block);
}
輸出:
.my-inline-block,
.thing1,
.thing2 {
display: inline-block;
font-size: 0;
}
- 結合樣式 / 更高階的混合
另一個用例是mixin的替代方案——因為mixin只能與簡單的選擇器一起使用,如果您在html上有兩個不同的塊,但是它們需要應用相同的樣式到,那麼您可以使用 :extend 來關聯兩個區域。
li.list > a {
// list styles
}
button.list-style {
&:extend(li.list > a); // use the same list styles
}