SASSで書かれたinuit.cssには.vendorミックスインがあることに気づきました。
@mixin vendor($property, $value...){
-webkit-#{$property}:$value;
-moz-#{$property}:$value;
-ms-#{$property}:$value;
-o-#{$property}:$value;
#{$property}:$value;
}
e()や@ {}のような奇妙な機能を使ってLESSでこれを複製する方法はありますか?
バージョン1.6以降(changelogを参照)、プロパティ名の補間はLESSに実装されています。だからあなたはもう魔法を必要としません。 (古いバージョンについては、私の元の回答を参照してください。)
ミックスインは基本的に次のように機能します。
もっと少なく:
.vendor(@property; @value){
-webkit-@{property}: @value;
-moz-@{property}: @value;
-ms-@{property}: @value;
-o-@{property}: @value;
@{property}: @value;
}
/*example*/
.test {
.vendor(transform, translateX(20px));
}
CSS:
.test {
-webkit-transform: translateX(20px);
-moz-transform: translateX(20px);
-ms-transform: translateX(20px);
-o-transform: translateX(20px);
transform: translateX(20px);
}
私に関する限り、動的に挿入されたプロパティのサポートは追加されていません。これは、以前にSOで何度も説明されていますが、次を参照してください。
したがって、通常行われる方法は、パラメトリックミックスインとパターンマッチングを使用することです...したがって、少しハードコーディングが必要です...しかし、プロパティとベンダーが異なると、パラメーターの形式が少し異なることがあるため、制御が少し強化されます。このように追加されます。
回避策の最初のオプションは少し醜いですが、私はそれを試しましたが、うまくいきました http://less2css.org 。だから、私が試したのは、動的に作成されたプロパティを、ハードコーディングした別のプロパティの値に挿入することでした(ここでランダムな「ベンダー」名-inj
を付け、値ect
を割り当てましたが、すべてのベンダーのミックスインに含まれる要素をすでに追加している場合は、代わりに何か便利なものを使用します)
.vendors(@property, @value, @pre: ect) {
-inj:~"@{pre}; -webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value}";
}
例でそれを試すことができます-多分それを価値あるものにする何か...短く変換してみましょう:
LESS:
.test-class{
.vendors(transform, matrix(1,0,0,1,20,20));
.vendors(transform-Origin,"10px 10px");
}
CSS出力:
.test-class {
-inj: ect; -webkit-transform: matrix(1, 0, 0, 1, 20, 20); -moz-transform: matrix(1, 0, 0, 1, 20, 20); -ms-transform: matrix(1, 0, 0, 1, 20, 20); -o-transform: matrix(1, 0, 0, 1, 20, 20); transform: matrix(1, 0, 0, 1, 20, 20);
-inj: ect; -webkit-transform-Origin: 10px 10px; -moz-transform-Origin: 10px 10px; -ms-transform-Origin: 10px 10px; -o-transform-Origin: 10px 10px; transform-Origin: 10px 10px;
}
これは動作するCSSを生成するようですが、ちょっと間違っていると感じます=)
そこで、このアイデアをもう少し試してみました...そして、不要なプロパティを生成しない方法を考えました。動的に作成されたプロパティを次のクラスの名前に挿入します。私がそれをどのように機能させたかをお見せしましょう:
1)一般的なベンダーミックスインを定義しましょう(@rest
引数は後で複数のベンダーブロックを並べるために使用されます)
.vendors(@property, @value, @rest:"") {
@inject:~"@{rest} -webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value};";
}
2)ベンダーを含める仮想クラス/ルールセットを作成しますが、最後に次のクラスを作成するミックスインとして作成します-したがって、実際には2つ以上のクラスを再帰的に構築するミックスインを作成します。たとえば(上記と同じ例を使用して)、次のように記述できます(2番目の.vendor()
呼び出しで@inject
を使用して、2つのベンダーブロックをバインドすることに注意してください)。
.test(@nextclass){
.vendors(transform, "matrix(2,0,0,2,20,20)");
.vendors(transform-Origin,"10px 10px", @inject);
(~"{@{inject}} .@{nextclass}"){/*next class properties*/};
}
3)ここで、このミックスインを別のクラスにラップして、cssに表示します。
.this-class{
.test(next-class);
}
結果の[〜#〜] css [〜#〜]には次のものが含まれます。
.this-class {
-webkit-transform: matrix(2, 0, 0, 2, 20, 20);
-moz-transform: matrix(2, 0, 0, 2, 20, 20);
-ms-transform: matrix(2, 0, 0, 2, 20, 20);
-o-transform: matrix(2, 0, 0, 2, 20, 20);
transform: matrix(2, 0, 0, 2, 20, 20);
-webkit-transform-Origin: 10px 10px;
-moz-transform-Origin: 10px 10px;
-ms-transform-Origin: 10px 10px;
-o-transform-Origin: 10px 10px;
transform-Origin: 10px 10px;
}
.next-class {
/*next class properties*/
}
出力はすべて1行になります。
編集:より良いフォーマットのために、"\n"
と"\t"
のjavascript補間を含めることができます。以下のコメントで、Scottの提案を参照してください。
このようにして、不要なプロパティなしで、ベンダーのミックスインを使用して複数のクラスをチェーン化できるようになりました。
私はこの原因を追加しています。スコットはコメントの1つで、バージョン1.4で行われる変更では回避策#2が許可されないと指摘しました。しかし、私たちが少し機知に富んでいれば、この問題を克服することができます。上記の回避策の問題点を確認し、修正してみましょう。
1)最初の問題は、「(~".@{index}") { ...
セレクター補間が非推奨」であるため、別のステップで文字列補間を実行する必要があります。これを実装するだけで、上から単一の.vendors
ミックスインを注入できます。
LESS:(スコットの改行の提案を使用):
@nl: `"\n\t"`;
.vendors(@property, @value) {
@inject:~"@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
}
.test(@nextclass){
.vendors(transform, "matrix(2,0,0,2,20,20)");
@inj: ~"{@{inject}`'\n'`} `'\n'`.@{nextclass}";
@{inj} {/*next class properties*/}
}
.this-class{
.test(next-class);
}
CSS出力:
.this-class {
-webkit-transform: matrix(2,0,0,2,20,20);
-moz-transform: matrix(2,0,0,2,20,20);
-ms-transform: matrix(2,0,0,2,20,20);
-o-transform: matrix(2,0,0,2,20,20);
transform: matrix(2,0,0,2,20,20);
}
.next-class {
/*next class properties*/
}
2)2番目の問題は、「ミックスイン内の変数が呼び出しスコープに「リーク」しなくなった」ということですが、1.4.0ベータ版では、変数がミックスインでのみ導入された場合でも、インクルードルールセットから呼び出すことができるため、少し再帰的に.vendors
ブロックを作成し、最後のステップでそれらを新しい変数に割り当てて、インジェクションに使用できます。また、興奮して、このバージョンのlessで導入された新しいextract()
関数を使用しました。変数@i
を使用して、再帰のレベル(注入されるベンダーブロックの数)を割り当てます。
LESS:
@nl: `"\n\t"`;
.multi(@props,@vals,1,@inj) {
@property: extract(@props, 1);
@value: extract(@vals, 1);
@inject:~"@{inj}@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
}
.multi(@props,@vals,@i,@inj:"") when (@i > 0) {
@property: extract(@props, @i);
@value: extract(@vals, @i);
@injnext:~"@{inj}@{nl}-webkit-@{property}: @{value};@{nl}-moz-@{property}: @{value};@{nl}-ms-@{property}: @{value};@{nl}-o-@{property}: @{value};@{nl}@{property}: @{value};";
.multi(@props,@vals,(@i - 1),@injnext);
}
@properties: "transform-Origin" "transform";
@values: "10px 10px" "matrix(2,0,0,2,20,20)";
// string of other properties you want to include in the same class
@p: ~"@{nl}width:20px; @{nl}height:12px; @{nl}background-color:#000;";
.this-class {
.multi(@properties,@values,2,@p);
@inj: ~"{@{inject}`'\n'`} `'\n'`.next-class ";
@{inj} {/**/}
}
CSS出力:
.this-class {
width:20px;
height:12px;
background-color:#000;
-webkit-transform: matrix(2, 0, 0, 2, 20, 20);
-moz-transform: matrix(2, 0, 0, 2, 20, 20);
-ms-transform: matrix(2, 0, 0, 2, 20, 20);
-o-transform: matrix(2, 0, 0, 2, 20, 20);
transform: matrix(2, 0, 0, 2, 20, 20);
-webkit-transform-Origin: 10px 10px;
-moz-transform-Origin: 10px 10px;
-ms-transform-Origin: 10px 10px;
-o-transform-Origin: 10px 10px;
transform-Origin: 10px 10px;
}
.next-class {
/*next class properties*/
}
これは1.4.0ベータ版ではかなりうまく機能しましたが、将来がどうなるか見てみましょう。
'minus'をプロパティ名として使用でき、パーサーはそれを無視しますが、文字列の残りを追加できることを追加したかっただけです。そうすれば、空のinject:;
またはinjプロパティを取得することはありません。それはまだハッキーですがねえ... :)
.prefix(@property, @value) {
-:~";-webkit-@{property}: @{value}; -moz-@{property}: @{value}; -ms-@{property}: @{value}; -o-@{property}: @{value}; @{property}: @{value}";
}
例:
.prefix(transition, "all .2s, color 0s");
出力されます:
-webkit-transition: all .2s, color 0;
-moz-transition: all .2s, color 0;
-ms-transition: all .2s, color 0;
-o-transition: all .2s, color 0;
transition: all .2s, color 0;