web-dev-qa-db-ja.com

少ないCSS:引数の数が可変のMixin

LESSでは、次のようなパラメトリックミックスインを使用できます。

.transition(@property, @duration){
    transition:         @property @duration;
    -moz-transition:    @property @duration; /* Firefox 4 */
    -webkit-transition: @property @duration; /* Safari and Chrome */
    -o-transition:      @property @duration; /* Opera */
}

ただし、これは遷移などのプロパティで常に機能するとは限りません。複数のトランジションを作成しようとしていて、ミックスインを複数回呼び出そうとすると、最後のミックスインが以前に定義されたすべてのトランジションをオーバーライドします。これは、複数の遷移を定義するための適切なCSS3構文が次のとおりであるためです。

... {
    transition: @property1 @duration1, @property2 @duration2, ...;
}

複数のトランジションをミックスインとして定義する唯一の方法は、ミックスインをオーバーロードすることです。

.transition(@property, @duration){...}
.transition(@property, @duration, @prop2, @dur2){...}
.transition(@property, @duration, @prop2, @dur2, @prop3, @dur3){...}

可変数の引数を取り、適切な遷移CSSを構築するための遷移ミックスインを定義する、より堅牢で簡潔な方法はありますか?

Context:複数のプロパティで遷移したい場合があります。たとえば、:hoverは、背景色、ボックスシャドウ、テキスト色などの遷移をトリガーする可能性があります...

26
Tuanderful

ここで私の答えを参照してください: 複数のプロパティがミックスインで個別の引数として扱われます

概要:可変数の引数にこのミックスインを使用します。

.transition (@value1,@value2:X,...)
{
    @value: ~`"@{arguments}".replace(/[\[\]]|\,\sX/g, '')`;

    -webkit-transition: @value;
    -moz-transition: @value;
    -ms-transition: @value;
    -o-transition: @value;
    transition: @value;
}
32

LESS 1.3.3以降のアップデート

出力は同じですが、エスケープされた文字列を実行する代わりにセミコロンを使用して、LESSの新しいバージョンでプロパティを渡す方法の違いに注意してください。

@prop1: color;
@prop2: opacity;
@dur1: 3s;
@dur2: 4s;

.transition(@transString: 0) when not (@transString = 0) {
    transition:         @transString;
    -moz-transition:    @transString; /* Firefox 4 */
    -webkit-transition: @transString; /* Safari and Chrome */
    -o-transition:      @transString; /* Opera */
}

.class1 {.transition();}
.class2 {.transition(width 2s, height 2s;);}
                                        ^
                                   semicolon here
.class3 {.transition(@prop1 @dur1, @prop2 @dur2;);}
                                               ^
                                         semicolon here

セミコロンにより、コンマはパラメーターの区切り文字ではなくリストの区切り文字として評価されます。

LESS 1.3.3より前の1つのソリューション

transitionの文字列として正しいプロパティ引数を作成し、エスケープされた値(~)演算子を使用して、必要な独自の構文に変換します。文字列補間(@{variableName})変数をプロセスに埋め込むこともできますが、実際の入力はエスケープされた文字列の形式である必要があります。

LESSコード

@prop1: color;
@prop2: opacity;
@dur1: 3s;
@dur2: 4s;

.transition(@transString: 0) when not (@transString = 0) {
    transition:         @transString;
    -moz-transition:    @transString; /* Firefox 4 */
    -webkit-transition: @transString; /* Safari and Chrome */
    -o-transition:      @transString; /* Opera */
}

.class1 {.transition();}
.class2 {.transition(~" width 2s, height 2s");}
.class3 {.transition(~" @{prop1} @{dur1}, @{prop2} @{dur2}");}

CSS出力

注:いいえ.class1は、ガード式が何かが入力されていることを保証するために出力されます(ただし、不適切な入力に対してはガードされません)。

.class2 {
  transition: width 2s, height 2s;
  -moz-transition: width 2s, height 2s;
  -webkit-transition: width 2s, height 2s;
  -o-transition: width 2s, height 2s;
}
.class3 {
  transition: color 3s, opacity 4s;
  -moz-transition: color 3s, opacity 4s;
  -webkit-transition: color 3s, opacity 4s;
  -o-transition: color 3s, opacity 4s;
}
21
ScottS

LESSでは、カンマを使用して引数を区切ることができますORセミコロン。カンマを含む単一の値の場合、リストを単一として送信するために、セミコロンで単一の値を終了できます。このような値:

.class {
  .background-size(100%, auto;);
}

複数の値の場合は、次の構文を使用します。

/* Example mixin */
.set-font-properties(@font-family, @size) {  
  font-family: @font-family;
  font-size: @size;
}
/* Usage with comma-separated values */
.class {
  .set-font-properties(Arial, sans-serif; 16px);
}

/* Output */
.class {
  font-family: Arial, sans-serif;
  font-size: 16px;
}

かんたん簡単!

6
Matthew Dean

注:この回答は、既存の回答が正しくないか廃止されていると言う目的で追加されていません。すべての回答は有効であり、引き続き機能します。これは、私の意見では少し複雑ですが、各引数をキーと値のペアとしてどのように説明できるかという点でより柔軟な別のメソッドを提供するだけです。

このメソッドを使用する利点:このメソッドは、値に追加の操作(unit as degpxまたは追加の数学演算など)、または@propertyのベンダープレフィックスも動的に追加します。たとえば、transformのみを入力プロパティとしてミックスインに渡したいが、-webkit-transformには-webkit-transitionを、-moz-transformには-moz-transitionを追加したい場合があります。

このメソッドでは、...機能を使用して、可変数の引数をミックスインに渡し、渡された各引数をループし、extractプロパティの名前と追加のパラメーター(持続時間、回転の程度など)、次にLess-が提供する merge feature を使用して、プロパティ。

  • +: はプロパティ値をカンマで連結し、Less v1.5.0で導入されました
  • +_: は、プロパティ値をスペースで連結し、Less v1.7.0で導入されました。
.transition(@args...){
    .loop-args(@argCount) when (@argCount > 0) {
        .loop-args(@argCount - 1);
        @arg: extract(@args, @argCount);
        @property: extract(@arg,1);
        @duration: extract(@arg,2);
        -webkit-transition+: @property @duration;
        -moz-transition+: @property @duration;
        -o-transition+: @property @duration;
        transition+: @property @duration;
    }
    .loop-args(length(@args));    
}

div{
    .transition(background, 1s; border-color, 2s; color, 2s);
}

.transform(@args...){
    .loop-args(@argCount) when (@argCount > 0) {
        .loop-args(@argCount - 1);
        @arg: extract(@args, @argCount);
        @property: extract(@arg,1);
        @param: extract(@arg,2);
        -webkit-transform+_: ~"@{property}(@{param})";
        -moz-transform+_: ~"@{property}(@{param})";
        -o-transform+_: ~"@{property}(@{param})";
        transform+_: ~"@{property}(@{param})";
    }
    .loop-args(length(@args));    
}

div#div2{
    .transform(rotate, 20deg; scale, 1.5; translateX, 10px);
}

上記のコードをコンパイルすると、以下の出力が生成されます。

div {
    -webkit-transition: background 1s, border-color 2s, color 2s;
    -moz-transition: background 1s, border-color 2s, color 2s;
    -o-transition: background 1s, border-color 2s, color 2s;
    transition: background 1s, border-color 2s, color 2s;
}
div#div2 {
    -webkit-transform: rotate(20deg) scale(1.5) translateX(10px);
    -moz-transform: rotate(20deg) scale(1.5) translateX(10px);
    -o-transform: rotate(20deg) scale(1.5) translateX(10px);
    transform: rotate(20deg) scale(1.5) translateX(10px);
}

関連回答:

  • ここseven-phases-max からの回答です。これは、この方法を使用して、利点の段落で述べたように、ベンダープレフィックスを自動追加する方法を詳しく説明しています。
4
Harry

これはうまくいくと思います:

.transition(...) {
    transition:         @arguments;
    -moz-transition:    @arguments; /* Firefox 4 */
    -webkit-transition: @arguments; /* Safari and Chrome */
    -o-transition:      @arguments; /* Opera */
}

...-有効なless構文であり、置き換えるものではありません。

4
esp

LESS 1.4現在、ドキュメント( http://lesscss.org/features/#mixins-parametric-feature-mixins-with-multiple-parameters )はこれを処理する適切な方法を提案しています:

コンマ区切り記号としてコンマを使用すると、引数としてコンマ区切りリストを作成できなくなります。一方、コンパイラーがmixin呼び出しまたは宣言内に少なくとも1つのセミコロンを見つけると、引数はセミコロンで区切られ、すべてのコンマはcssリストに属していると想定します。

具体的には、mixin

.transition(@prop-or-props) {
    -webkit-transition: @prop-or-props;
       -moz-transition: @prop-or-props;
         -o-transition: @prop-or-props;
            transition: @prop-or-props;
}

使用量

.transition(opacity .2s, transform .3s, -webkit-transform .3s;);

複数のプロパティはカンマで区切られ、末尾のセミコロンにより、コンマで区切られたリストがミックスインの単一のパラメータとして扱われることに注意してください。

rest...パラメータを使用してミックスインを定義し、任意の長さの引数の各要素を抽出して個別に処理できるようにするとよいでしょうが、私が考えているユースケースは、トランジションを変換するベンダープレフィックスを追加することです。 (したがって、.transition(opacity .2s, transform .3s)で簡単に呼び出すことができ、-webkit-transformビットが自動的に追加されます)おそらく、とにかくこれは別のユーティリティ(gulp-autoprefixerなど)でより適切に処理されます。

2
Jon z