17

CSS を簡素化するために、大規模な Web アプリ プロジェクトに LESS を導入しています。さまざまな数のプロパティにトランジションを適用するいくつかの CSS ルールがあります。たとえば、次のようになります。

.movable {
    transition-property: top, left;
    transition-duration: 0.2s;
    transition-timing-function: ease;
}

.fadeAndStretchable {
    transition-property: opacity, width, height, margin;
    transition-duration: 1.5s;
    transition-timing-function: ease-out;
}

-webkit(注: ここでは、簡潔にするために-mozとプロパティを省略しまし-oた。実際には、これらの各ルールは 3 行ではなく 12 行の長さです。)

の値transition-propertyはコンマで区切られていることに注意してください。これは CSS では珍しいことです。通常、複数の値はスペースで区切られます ( のようにborder: 1px solid #f00)。LESS ミックスインは特別な@arguments値を使用して、すべてのミックスイン引数のスペース区切りのリストを生成できますが、可変数のパラメーターを取り、それらをカンマ区切りの値リストに変換する LESS ミックスインを定義することは可能transition-propertyですか?

必要に応じて、2 つの mixin を必要とするソリューションに満足してtransition-propertytransition-durationますtransition-timing-function。これが私がこれまでに試したことです:

試行 1: 名前のないパラメーターで @arguments を使用する

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

.movable {
    .transition-property(top, left);
}

結果: LESS エラー (「'.transition-property(top, left)' に一致する定義が見つかりませんでした」)

試行 2: 名前付きパラメーターで @arguments を使用する

.transition-property(@p1, @p2, @p3, @p4, @p5) {
    -webkit-transition-property: @arguments;
    -moz-transition-property: @arguments;
    -o-transition-property: @arguments;
    transition-property: @arguments;
}

.movable {
    .transition-property(top, left);
}

結果: LESS エラー (「'.transition-property(top, left)' に一致する定義が見つかりませんでした」)

試行 3: ダミーのデフォルト値を持つ名前付きパラメーターを使用する

.transition-property(@p1:p1, @p2:p2, @p3:p3, @p4:p4, @p5:p5) {
    -webkit-transition-property: @p1, @p2, @p3, @p4, @p5;
    -moz-transition-property:  @p1, @p2, @p3, @p4, @p5;
    -o-transition-property:  @p1, @p2, @p3, @p4, @p5;
    transition-property:  @p1, @p2, @p3, @p4, @p5;
}

.movable {
    .transition-property(top, left);
}

結果: LESS エラーは発生しませんが-webkit-transition-property: top, left, p3, p4, p5、プロパティが認識されないためにブラウザーが無視する CSS ルールが生成されます。

私は他のさまざまなアプローチを試しました (たとえば、プロパティを string として渡す'top,left') が、すべて同じ結果になります: LESS エラーまたは無効な CSS のいずれかです。

これを回避する方法はありますか?それとも、弾丸を噛んで、アリティにオーバーロードされた一連のミックスインを定義する必要がありますか?

.transition-property(@p1) {...}
.transition-property(@p1, @p2) {...}
.transition-property(@p1, @p2, @p3) {...}
.transition-property(@p1, @p2, @p3, @p4) {...}
etc.
4

4 に答える 4

29

Luke Page...が構文を教えてくれたおかげで、なんとか理解できました。

解決策は、次を使用することでした。

ふぅ。結果のミックスインは次のとおりです。

.transition-properties(...) {
    -webkit-transition-property: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
}

そして、ブラウザ拡張機能の完全なセットを備えたフルバージョンは次のとおりです。

.transition-properties(...) {
    @props: ~`"@{arguments}".replace(/[\[\]]/g, '')`;
    -webkit-transition-property: @props;
    -moz-transition-property: @props;
    -o-transition-property: @props;
    transition-property: @props;
}
于 2012-05-02T12:05:59.380 に答える
22

おそらく私はあなたのニーズを誤解しています。エスケープされた文字列を使用できないのはなぜですか?

そのようです:

.transition ( @property, @duration, @style: ease-in-out ) {
  -webkit-transition-property: @property;  
  -webkit-transition-duration: @duration;
  -webkit-transition-timing-function: @style;

  -moz-transition-property: @property;  
  -moz-transition-duration: @duration;
  -moz-transition-timing-function: @style;

  -ms-transition-property: @property;  
  -ms-transition-duration: @duration;
  -ms-transition-timing-function: @style;

  -o-transition-property: @property;  
  -o-transition-duration: @duration;
  -o-transition-timing-function: @style;

  transition-property: @property;  
  transition-duration: @duration;
  transition-timing-function: @style;
}

#my-id {
  .transition( ~"background, border-color, color", 2s );
}

これはまさに、マルチプロパティ トランジションに使用するものです。問題はありませんでした。

于 2012-08-16T08:04:46.793 に答える
7

フレキシブル (LESS 1.5.1+)

このソリューションはインライン JavaScript を使用せず、次のことを可能にします。

  1. 設定するデフォルト
  2. 渡されるプロパティ、期間、遅延などの任意の数
  3. 長い形式またはコンパクトな形式で出力
  4. 必要に応じて、パラメーターのグループを入力する代わりに生のリストを入力

プロパティの数が継続時間、遅延、またはタイミングの数より多い場合、compact出力が設定されている場合、継続時間/遅延/タイミングの最終値は、渡された数を超えるすべての追加プロパティのそのパラメーターの値になりますが、が設定されていない場合compactは、長い形式が出力され、ブラウザが CSS 標準を解釈するたびに値が複製されます

LESS ミックスイン

.transition (@props: all; 
             @duration:1s; 
             @delay: 0s; 
             @timing: ease; 
             @compact: true;
             @raw-input: false) {
  .output() when (@raw-input = false) and not (@compact = true) {
  -webkit-transition-property:@props; 
     -moz-transition-property:@props;
      -ms-transition-property:@props;
       -o-transition-property:@props; 
          transition-property:@props;
  -webkit-transition-duration:@duration; 
     -moz-transition-duration:@duration;
      -ms-transition-duration:@duration;
       -o-transition-duration:@duration; 
          transition-duration:@duration;
  -webkit-transition-delay:   @delay; 
     -moz-transition-delay:   @delay;
      -ms-transition-delay:   @delay;
       -o-transition-delay:   @delay; 
          transition-delay:   @delay;
  -webkit-transition-timing-function:@timing; 
     -moz-transition-timing-function:@timing;
      -ms-transition-timing-function:@timing;
       -o-transition-timing-function:@timing; 
          transition-timing-function:@timing;
  }
  .output() when (@raw-input = false) and (@compact = true) {
    @propsLength: length(@props);
    @durationLength: length(@duration);
    @delayLength: length(@delay);
    @timingLength: length(@timing);
    .buildString(@i, @s: ~'') when (@i <= @propsLength) {
      @prop: extract(@props, @i);
      .setDuration() when (@i <= @durationLength) {
        @dur: extract(@duration, @i);
      }
      .setDuration() when (@i > @durationLength) {
        @dur: extract(@duration, @durationLength);
      }
      .setDuration();
      .setDelay() when (@i <= @delayLength) {
        @del: extract(@delay, @i);
      }
      .setDelay() when (@i > @delayLength) {
        @del: extract(@delay, @delayLength);
      }
      .setDelay();
      .setTiming() when (@i <= @timingLength) {
        @time: extract(@timing, @i);
      }
      .setTiming() when (@i > @timingLength) {
        @time: extract(@timing, @timingLength);
      }
      .setTiming();
      .setDivider() when (@i > 1) {
        @divider: ~'@{s},';
      }
      .setDivider() when (@i = 1) {
        @divider: ~'';
      }
      .setDivider();
      @string: @divider @prop @dur @del @time;
      .buildString((@i + 1), @string);  
    }
    .buildString(1);
    .buildString(@i, @s: ~'') when (@i > @propsLength) {
      .compact(@s);
    }
  }
  .output() when not (@raw-input = false) {
    .compact(@raw-input);
  }
  .compact(@string) {
    -webkit-transition:@string; 
       -moz-transition:@string;
        -ms-transition:@string;
         -o-transition:@string; 
            transition:@string;    
  }
  .output();
} 

LESS 使用例

.test {
  .transition();
}
.test-props {
  .transition(width);
}
.test-duration {
  .transition(@duration: 3s);
}
.test-delay {
  .transition(@delay: 10s);
}
.test-timing {
  .transition(@timing: linear);
}
.test-all {
  .transition(height, 4s, 12s, ease-out);
}
.test-multitransitions {
  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
}
.test-not-compact {
  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease; false);
}
.test-raw-input {
  .transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
}

上記の例では、特に次の 2 つの点に注意してください。(1) リストを区切るためにカンマを使用し、パラメータ グループを区切るためにセミコロンを使用して、複数の値を渡す必要がある方法。視覚化すると、次のようになります。

  .transition(width, height, top; 1s, 2s; 0s, 1s, 3s; ease-in, ease-out, ease);
              |---Properties----|-Dur.--|---Delay---|---------Timing--------|
                                |       |           |
                          semicolons divide groups of parameters

(2)raw-inputコンマをリスト アイテムと見なすために、この例では末尾のセミコロンが必要です。

  .transition(@raw-input: top 1s, bottom 1s, color 3s 1s linear;);
                                                               |
                                                    semicolon here needed

例の CSS 出力

.test {
  -webkit-transition:  all 1s 0s ease;
  -moz-transition:  all 1s 0s ease;
  -ms-transition:  all 1s 0s ease;
  -o-transition:  all 1s 0s ease;
  transition:  all 1s 0s ease;
}
.test-props {
  -webkit-transition:  width 1s 0s ease;
  -moz-transition:  width 1s 0s ease;
  -ms-transition:  width 1s 0s ease;
  -o-transition:  width 1s 0s ease;
  transition:  width 1s 0s ease;
}
.test-duration {
  -webkit-transition:  all 3s 0s ease;
  -moz-transition:  all 3s 0s ease;
  -ms-transition:  all 3s 0s ease;
  -o-transition:  all 3s 0s ease;
  transition:  all 3s 0s ease;
}
.test-delay {
  -webkit-transition:  all 1s 10s ease;
  -moz-transition:  all 1s 10s ease;
  -ms-transition:  all 1s 10s ease;
  -o-transition:  all 1s 10s ease;
  transition:  all 1s 10s ease;
}
.test-timing {
  -webkit-transition:  all 1s 0s linear;
  -moz-transition:  all 1s 0s linear;
  -ms-transition:  all 1s 0s linear;
  -o-transition:  all 1s 0s linear;
  transition:  all 1s 0s linear;
}
.test-all {
  -webkit-transition:  height 4s 12s ease-out;
  -moz-transition:  height 4s 12s ease-out;
  -ms-transition:  height 4s 12s ease-out;
  -o-transition:  height 4s 12s ease-out;
  transition:  height 4s 12s ease-out;
}
.test-multitransitions {
  -webkit-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -moz-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -ms-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  -o-transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
  transition:  width 1s 0s ease-in, height 2s 1s ease-out, top 2s 3s ease;
}
.test-not-compact {
  -webkit-transition-property: width, height, top;
  -moz-transition-property: width, height, top;
  -ms-transition-property: width, height, top;
  -o-transition-property: width, height, top;
  transition-property: width, height, top;
  -webkit-transition-duration: 1s, 2s;
  -moz-transition-duration: 1s, 2s;
  -ms-transition-duration: 1s, 2s;
  -o-transition-duration: 1s, 2s;
  transition-duration: 1s, 2s;
  -webkit-transition-delay: 0s, 1s, 3s;
  -moz-transition-delay: 0s, 1s, 3s;
  -ms-transition-delay: 0s, 1s, 3s;
  -o-transition-delay: 0s, 1s, 3s;
  transition-delay: 0s, 1s, 3s;
  -webkit-transition-timing-function: ease-in, ease-out, ease;
  -moz-transition-timing-function: ease-in, ease-out, ease;
  -ms-transition-timing-function: ease-in, ease-out, ease;
  -o-transition-timing-function: ease-in, ease-out, ease;
  transition-timing-function: ease-in, ease-out, ease;
}    
.test-raw-input {
  -webkit-transition: top 1s, bottom 1s, color 3s 1s linear;
  -moz-transition: top 1s, bottom 1s, color 3s 1s linear;
  -ms-transition: top 1s, bottom 1s, color 3s 1s linear;
  -o-transition: top 1s, bottom 1s, color 3s 1s linear;
  transition: top 1s, bottom 1s, color 3s 1s linear;
}

長い形式がまったく望ましくない場合は、mixin コードを次のように縮小できます。

.transition (@props: all; 
             @duration:1s; 
             @delay: 0s; 
             @timing: ease; 
             @raw-input: false) {
  .output() when (@raw-input = false) {
    @propsLength: length(@props);
    @durationLength: length(@duration);
    @delayLength: length(@delay);
    @timingLength: length(@timing);
    .buildString(@i, @s: ~'') when (@i <= @propsLength) {
      @prop: extract(@props, @i);
      .setDuration() when (@i <= @durationLength) {
        @dur: extract(@duration, @i);
      }
      .setDuration() when (@i > @durationLength) {
        @dur: extract(@duration, @durationLength);
      }
      .setDuration();
      .setDelay() when (@i <= @delayLength) {
        @del: extract(@delay, @i);
      }
      .setDelay() when (@i > @delayLength) {
        @del: extract(@delay, @delayLength);
      }
      .setDelay();
      .setTiming() when (@i <= @timingLength) {
        @time: extract(@timing, @i);
      }
      .setTiming() when (@i > @timingLength) {
        @time: extract(@timing, @timingLength);
      }
      .setTiming();
      .setDivider() when (@i > 1) {
        @divider: ~'@{s},';
      }
      .setDivider() when (@i = 1) {
        @divider: ~'';
      }
      .setDivider();
      @string: @divider @prop @dur @del @time;
      .buildString((@i + 1), @string);  
    }
    .buildString(1);
    .buildString(@i, @s: ~'') when (@i > @propsLength) {
      .compact(@s);
    }
  }
  .output() when not (@raw-input = false) {
    .compact(@raw-input);
  }
  .compact(@string) {
    -webkit-transition:@string; 
       -moz-transition:@string;
        -ms-transition:@string;
         -o-transition:@string; 
            transition:@string;    
  }
  .output();
}
于 2013-12-28T02:40:56.777 に答える
5

less.js 1.3 以降では、引数リストに ... を指定して、より多くの引数を追加できることを示す必要があります。例えば

.transition-property(...) {
 foo: @arguments;
}
于 2012-05-02T11:35:24.990 に答える