簡體   English   中英

較少CSS傳遞mixin作為另一個mixin的參數

[英]LESS CSS Pass mixin as a parameter to another mixin

有沒有辦法將一個mixin或style的聲明傳遞給另一個mixin作為輸入參數?

我們來看一個動畫關鍵幀的例子。 以下是我們如何在純CSS中定義關鍵幀:

@-moz-keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

@-webkit-keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

@keyframes some-name
{
    from { color: red; }
    to { color: blue; }
}

想法是使用mixins簡化這些聲明,所以我們可以使用以下內容:

.keyframes(name, from, to)
{
    // here we need somehow to reproduce structure
    // that we have in an example above
}

// define one animation
.my-from() { color: red; }
.my-to() { color: blue; }
// the following won't work because you cannot pass mixin as a parameter
// in way I have here, so I am looking for a way to solve this problem
.keyframes('some-name', .my-from, .my-to);

// define another animation
.another-from() { font-size: 1em; }
.another-to() { font-size: 2em; }
.keyframes('another-name', .another-from, .another-to);

系統將具有可以動態附加到應用程序以及移除的不同模塊。 所以,不要建議我使用@import因為事實並非如此。 使用有關模塊及其自己的LESS樣式的信息以及諸如mixins庫等的基本LESS依賴性,動態地動態編譯輸出CSS。

注意:如果你知道一種傳遞類定義而不是mixin的方法,它對我有用。 在上面的例子中,它將是.my-from而不是.my-from()等。

更新的LESS 1.7.0+(WAY簡單)

我們現在可以更直接地使用1.7.0更新和創建規則集的能力,以及在設置@keyframes使用變量

現在我們真的可以通過規則集傳遞一個參數mixin,或者我們可以自己傳遞屬性stings。 所以考慮一下:

少(使用1.7)

.keyframes(@name, @from, @to) {
    @frames: {
        from { @from(); }
        to { @to(); }
    };
    @pre: -moz-keyframes;
    @-moz-keyframes @name
    {
       @frames();
    }

    @-webkit-keyframes @name
    {
       @frames();
    }

    @keyframes @name
    {
       @frames();
    }
}

.keyframes(testName, {color: red; .myMix(0);}, {color: blue; .myMix(1);});

.myMix(@value) {opacity: @value;}

請注意,我傳遞了屬性設置和mixin調用,我的輸出是:

CSS輸出

@-moz-keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}
@-webkit-keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}
@keyframes testName {
  from {
    color: red;
    opacity: 0;
  }
  to {
    color: blue;
    opacity: 1;
  }
}

注意規則集如何通過括號{...}傳遞,然后通過@from()@to()調用(看起來很像mixin調用)。 我正在使用這些傳遞的規則集來設置@frames另一個規則集,然后調用它來填充關鍵幀定義。

更一般地說

在這里,我將私有mixin傳遞給另一個mixin,然后從其他mixin調用它:

.someMixin(@class; @expectedMixin) {
    .@{class} {
      @expectedMixin();
      .myPrivateMix(0.6);
      test: 1;
    }
}

.someMixin(newClass; {.myClass;});

.myClass {
  .myPrivateMix(@value) {opacity: @value;}
}

CSS輸出

.newClass {
  opacity: 0.6;
  test: 1;
}

保留下面的遺留信息。

更新(添加了LESS 1.4.0+支持)

哇,這需要做一些,但我想我有一些你可以使用的東西。 但是,它確實需要在模塊中對mixin進行一些特殊定義,特別是使用模式匹配 所以...

首先,定義模塊混合

請注意,在特定的未來mixin中使用的模塊mixin是如何使用相同的mixin名稱定義的,但具有不同的模式名稱。 這是實現這項工作的關鍵。

// define one animation in a module
.from(my-from){ color: red; }
.to(my-to) { color: blue; }

// define one animation in another module
.from(another-from){ font-size: 1em; }
.to(another-to) { font-size: 2em; }

如果您還需要模塊中的各個mixin名稱 ,您應該能夠這樣做:

// define one animation in a module
.my-from(){ color: red; }
.my-to() { color: blue; }

.from(my-from){ .my-from() }
.to(my-to) { .my-to() }   

// define one animation in another module
.another-from(){ font-size: 1em; }
.another-to() { font-size: 2em; }

.from(another-from){ .another-from() }
.to(another-to) { .another-to() }

這應該允許一個人調用直接mixin .my-from()或者在后來的mixins中通過模式匹配訪問單個.from() mixin組,使其可以變化地訪問。

接下來,定義您的Mixin

對於你的@keyframes示例,這非常困難。 事實上, 堆棧溢出答案對於幫助我解決應用@name的問題至關重要,因為它遵循@keyframes定義,因此不能在正常的LESS規則下應用。 應用@name的解決方案看起來很討厭,但它確實有效。 它確實有一個非常不幸的必要,即定義一個選擇器字符串來播放動畫(因為它使用該字符串來幫助構建關鍵幀的最后一個} )。 這種命名限制只適用於以@ like @keyframes開頭的css字符串,可能是@media

此外,因為我們的模塊文件中使用了標准的mixin名稱,所以我們可以在新的mixin中一致地訪問它,同時傳遞變量以通過模式匹配選擇該mixin的正確變體 所以我們得到:

少於1.3.3或以下

// define mixin in mixin file

.keyframes(@selector, @name, @from, @to) {
    @newline: `"\n"`; // Newline
    .setVendor(@pre, @post, @vendor) {
        (~"@{pre}@@{vendor}keyframes @{name} {@{newline}from") {
            .from(@from); 
        }    
        to  { 
            .to(@to);
        }
       .Local(){}
       .Local() when (@post=1) {
           (~"}@{newline}@{selector}") {
              -moz-animation: @name;
              -webkit-animation: @name;
              -o-animation: @name;
              -ms-animation: @name;
              animation: @name;
           } 
       }    
       .Local;
    } 
    .setVendor(""            , 0,    "-moz-");
    .setVendor(~"}@{newline}", 0, "-webkit-");
    .setVendor(~"}@{newline}", 0,      "-o-");
    .setVendor(~"}@{newline}", 0,     "-ms-");
    .setVendor(~"}@{newline}", 1,         "");
}

少1.4.0+

.keyframes(@selector, @name, @from, @to) {
    @newline: `"\n"`; // Newline
    .setVendor(@pre, @post, @vendor) {
        @frames: ~"@{pre}@@{vendor}keyframes @{name} {@{newline}from";
        @{frames} {
            .from(@from); 
        }    
        to  { 
            .to(@to);
        }
       .Local(){}
       .Local() when (@post=1) {
           @animationSector: ~"}@{newline}@{selector}";
           @{animationSector} {
              -moz-animation: @name;
              -webkit-animation: @name;
              -o-animation: @name;
              -ms-animation: @name;
              animation: @name;
           } 
       }    
       .Local;
    } 
    .setVendor(""            , 0,    "-moz-");
    .setVendor(~"}@{newline}", 0, "-webkit-");
    .setVendor(~"}@{newline}", 0,      "-o-");
    .setVendor(~"}@{newline}", 0,     "-ms-");
    .setVendor(~"}@{newline}", 1,         "");
}

現在打電話給你的Mixin

您可以給它自己的名字,並且只為模塊mixins上的模式匹配傳遞直線模式(所有都沒有點[。]和沒有引號),但不要忘記您還需要一個選擇器字符串(這是引用)讓mixin正常工作:

.keyframes('.changeColor', some-name, my-from, my-to);
.keyframes('.changeFontSize', another-name, another-from, another-to);

這給了你想要的輸出

@-moz-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-webkit-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-o-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@-ms-keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
@keyframes some-name {
from {
  color: red;
}
to {
  color: blue;
}
}
.changeColor {
  -moz-animation: some-name;
  -webkit-animation: some-name;
  -o-animation: some-name;
  -ms-animation: some-name;
  animation: some-name;
}
@-moz-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-webkit-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-o-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@-ms-keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
@keyframes another-name {
from {
  font-size: 1em;
}
to {
  font-size: 2em;
}
}
.changeFontSize {
  -moz-animation: another-name
  -webkit-animation: another-name;
  -o-animation: another-name;
  -ms-animation: another-name;
  animation: another-name;
}

簡單化

我只是簡化了一點ScottS的方式,將@keframes-animation分開:

.keyframes(@name, @from, @to) {
    @newline: `"\n"`;
    .Local(@x){};
    .Local(@x) when (@x="") {(~"}@{newline}/*"){a:a}/**/};

    .setVendor(@pre, @vendor) {
        (~"@{pre}@@{vendor}keyframes @{name} {@{newline}from") {
            .from(@from);
        }
        to {
            .to(@to);
        }
        .Local(@vendor);
    }
    .setVendor(""            , "-webkit-");
    .setVendor(~"}@{newline}",    "-moz-");
    .setVendor(~"}@{newline}",      "-o-");
    .setVendor(~"}@{newline}",         "");
}

.animation(...) {
  -webkit-animation: @arguments;
     -moz-animation: @arguments;
       -o-animation: @arguments;
          animation: @arguments;
}

使用:

.from(a1-from){ width: 10px; }
.to(a1-to) { width: 20px; }
.keyframes(a1-animation, a1-from, a1-to);


.selector {
    // some other css
    .animation(a1-animation 1s infinite linear);
}

輸出:

@-webkit-keyframes a1-animation {
from {
  width: 10px;
}
to {
  width: 20px;
}
}
@-moz-keyframes a1-animation {
from {
  width: 10px;
}
to {
  width: 20px;
}
}
@-o-keyframes a1-animation {
from {
  width: 10px;
}
to {
  width: 20px;
}
}
@keyframes a1-animation {
from {
  width: 10px;
}
to {
  width: 20px;
}
}
/* {
  a: a;
}
/**/


.selector {
  // some other css
  -webkit-animation: a1-animation 1s infinite linear;
  -moz-animation: a1-animation 1s infinite linear;
  -o-animation: a1-animation 1s infinite linear;
  animation: a1-animation 1s infinite linear;
}

小問題:

因此動畫現在與@keyframes分開,但我們必須付出代價 有一個令人討厭的:

/* {
  a: a;
}
/**/

但它不應該是一個問題 - >可能我們所有人都推動CSS文件通過任何類型的縮小器,削減評論。

您還可以使用我的解決方案生成CSS關鍵幀: https//github.com/thybzi/keyframes

特征:

  • 跨瀏覽器關鍵幀生成(Firefox 5 +,Chrome 3 +,Safari 4 +,Opera 12 +,IE 10+)
  • 每個keyframes規則中最多16個時間點(如果需要,可以輕松擴充該數量)
  • 混合,變量和函數可用於樣式時間點
  • 關鍵幀與animation規則分開創建,因此:
    • 多個animation規則可以使用具有不同值的相同關鍵幀進行計時,重復等,
    • 可以在同一animation規則中使用多個動畫
    • 動畫可以在任何父選擇器中應用(不創建!)
  • 輕量級(幾乎)整潔的LESS代碼

基本用法:

// Preparing styles for animation points
.keyframes-item(fadeIn, 0%) {
    opacity: 0;
}
.keyframes-item(fadeIn, 100%) {
    opacity: 1;
}
// Generating keyframes
.keyframes(fadeIn);

// Applying animation to fade-in block in 1.5 seconds
.myBlock {
    .animation(fadeIn 1.5s);
}

它不是你如何使用mixins。

你應該做的事情是這樣的:

.mixin-one { ... }
.mixin-two { ... }
.target-style {
    .mixin-one;
    .mixin-two;
    font-family: 'Comic Sans MS';
    color: magenta;
}

暫無
暫無

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

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