簡體   English   中英

LESS CSS:重新生成。@ {name}類作為mixin

[英]LESS CSS: Reuse generated .@{name} class as a mixin

我正在使用LESS CSS 1.3.3。 對不起,如果已經提出這個問題,我在網上找不到任何相關內容。

我有幾個看起來像這樣的類生成器(示例非常簡化,足以觸發錯誤):

#genMarginTop (@name, @size) {
    .@{name} { margin-top: @size; }
}

然后我用它們來生成一些實際的類:

#genMarginTop(mtStandard, 40px);
#genMarginTop(mtHalf, 20px);

到目前為止,很好,LESS正確生成了這些類,我可以在HTML中使用它們。 但是當我想在其他地方重用這樣生成的類作為mixin時,我收到一個錯誤:

.someClass {
    .mtStandard; // won't work, see error below
    // more stuff
}

我得到的錯誤是:

NameError: .mtStandard is undefined in /.../example.less:161:4
160 .someClass {
161     .mtStandard;
162     // more stuff

當然,我嘗試在生成類之后使用mixin。 看起來像 LESS以某種方式在生成它們之后不會在內部注冊這些生成的類,但我可能錯了。

有沒有辦法在其他類中重用這些生成的類作為mixins? 作為LESS的新手,他們的文檔對生成的類相當稀疏,我完全失去了(特別是因為這是mixins似乎接受的唯一語法)。

謝謝你讀我


注意:我使用這樣的類生成器的原因是因為它們比上面的例子復雜得多(想想所有依賴於一組公共參數的嵌套類),並且我將生成的類嵌入到各種@media查詢中以“Zen”方式支持任何設備類型。 最后我得到了類似的東西:

@media (max-width: 1024px) {
    #genSomething(something, somethingParam1, ...);
    #genSomething(somethingElse, somethingElseParam1, ...);
    #genStuff(stuff, stuffParam1, ...);
}
@media (max-width: 240px) {
    #genSomething(something, somethingParam2, ...);
    #genSomething(somethingElse, somethingElseParam2, ...);
    #genStuff(stuff, stuffParam2, ...);
}
// etc

解決方案/測試用例

這是@MartinTurjak解決方案的測試用例,我可以確認這是按預期工作的,嵌套類和所有內容:

.explicit {
  margin-top: 1;
  input { margin-top: 1; }
}
.reuseExplicit {
  .explicit;
  margin-bottom: 1;
}
#generator (@arg) {
  margin-top: @arg;
  input {
    margin-top: @arg;
  }
}
.generated { #generator(1); }
.reuseGenerated {
  .generated;
  margin-bottom: 1;
}

哪個正確生成:(注意顯式/生成如何產生相同的結果)

.explicit {
  margin-top: 1;
}
.explicit input {
  margin-top: 1;
}
.reuseExplicit {
  margin-top: 1;
  margin-bottom: 1;
}
.reuseExplicit input {
  margin-top: 1;
}
.generated {
  margin-top: 1;
}
.generated input {
  margin-top: 1;
}
.reuseGenerated {
  margin-top: 1;
  margin-bottom: 1;
}
.reuseGenerated input {
  margin-top: 1;
}

不幸。 選擇器插值只是字符串插值,然后將字符串打印到css中,因此在較少的運行中不會生成類對象。

所以你可以設計一個發電機/混合,包括你的操作:

#genMarginTop (@size) {
  margin-top: @size;
}

但是通過調用mixins / generators來構建類:

.mtStandard {#genMarginTop(40px);}
.mtHalf {#genMarginTop(20px);}

這樣它們就是你可以用於mixin =)的類對象

.someClass {
  background-color: #FFF;
  .mtStandard;
  //more of this stuff
}

在這個簡單的例子中,這看起來有點傻,但也許是這樣的:

 #bggenerator (@color) {
    background-color: @color;
 }
 #bggenerator (@color, dark) {
    @blend : @color + #842210;
    background-color: darken(@blend, 30%);
 }
 #bggenerator (@color, @url, @rest) {
    background: "@{color} url('@{url}') @{rest}";
 }

 .mtStandard {
    #genMarginTop(40px);
 }

.someClass {
  .mtStandard;
  #bggenerator(#FFF, "bgimage.png", left top no-repeat);
  //more of this stuff
}

或者用參數做更令人興奮的事情

更新1.7+(按預期工作)

.@{name}語法現在可以像原始問題所希望的那樣工作。

實際使用動態類名稱的工作量少於1.4+

我在處理另一個問題時想出了一個解決方法,所以我將它作為第二個答案發布,因為它與我之前的答案完全不同。

這個解決方案需要幾個步驟(因此不像LESS中的最終修復那么方便),但是會給出能夠使用動態生成的類名的實際功能

第一:定義動態類

這和你的計划一樣。

#genMarginTop (@name, @size) {
    .@{name} { margin-top: @size; }
}

#genMarginTop(mtStandard, 40px);
#genMarginTop(mtHalf, 20px);

第二步:將該文件編譯為CSS

因此,假設您將dynamicClasses.less編譯為dynamicClasses.css 這會導致動態類名稱“解析”為實際的類。

第三步:將CSS作為LESS導入到使用動態類名的第二個 LESS文件中

使用@import 類型轉換 ,我們這樣做:

@import (less) dynamicClasses.css;

這將在dynamicClasses.css文件中獲取這些已解析的類名,並將它們作為LESS導入 ,這使得所有類名現在都可用作mixins。 所以你可以按照自己的意願去做:

.someClass {
    .mtStandard; // will work
    // more stuff
}

我同意。 看起來LESS沒有為mixin目的注冊這些類。

不完整的解決方案

這個LESS代碼:

#genMarginTop (@name, @size) {
  @genMarginTopNameCheck: @name; 
  .get(@name) when (@name = @genMarginTopNameCheck) { margin-top: @size; }
  .@{name} { .get(@name); }
}
#genMarginBot (@name, @size) {
    @genMarginBotNameCheck: @name; 
    .get(@name) when (@name = @genMarginBotNameCheck)  { margin-bottom: @size; }
    .@{name} { .get(@name); }
}


#genMarginTop(mtStandard, 40px);
#genMarginBot(mbStandard, 20px);
#genMarginTop(mtSpecial, 80px);

.myClass {
  .get(mtStandard);
  .get(mbStandard); 
}

.myClass2 {
  .get(mtSpecial);
  .get(mbStandard); 
}

生成這個CSS

.mtStandard {
  margin-top: 40px;
}
.mbStandard {
  margin-bottom: 20px;
}
.mtSpecial {
  margin-top: 80px;
}
.myClass {
  /* NOTE the mtStandard definition is missing here !!! */
  margin-bottom: 20px;
}
.myClass2 {
  margin-top: 80px;
  margin-bottom: 20px;
}

對最終解決問題的解釋和討論

每個mixin都根據@name定義一個受保護的.get() mixin來獲取樣式,然后交叉檢查該mixin的唯一NameCheck變量名。 所有實際代碼都在.get()定義,而mixin用於實際生成.@{name}類代碼。

每次生成實際的類名時都可以正常工作。 但是,目前的getter函數僅適用於最后使用mixin 定義的類名。 正如你在上面看到的那樣,我對mtStandard 調用不起作用,因為mtSpecial 設置 mtSpecial已經用mtSpecial定義覆蓋了#genMarginTop .get() mixin。

現在我假設您要#getMarginTop調用#getMarginTop和其他類似的mixin,所以顯然這仍然是一個不完整的解決方案 我已經弄清楚如何使用.get()將頂層mixin生成的類用作另一個類的'mixin',但我還沒弄明白如何制作.get()當再次調用頂級mixin時,不會被覆蓋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM