7

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 は、そのような生成されたクラスを生成後に内部的に登録しないように見えますが、間違っている可能性があります

そのような生成されたクラスを他のクラスのミックスインとして再利用する方法はありますか? LESS に関してはまったく新しいものであり、生成されたクラスに関するドキュメンテーションがかなりまばらであるため、私は完全に途方に暮れています (特に、これが mixin で受け入れられると思われる唯一の構文であるため)。

私を読んでくれてありがとう。


注:このようなクラス ジェネレーターを使用する理由は、上記の例よりもはるかに複雑であるためです (すべてが共通のパラメーター セットに依存するネストされたクラスを考えてください)。生成されたクラスをさまざまな@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;
}
4

3 に答える 3

6

不運にも。セレクター補間は単なる文字列補間であり、文字列は css に出力されるため、少ない実行ではクラス オブジェクトは生成されません。

したがって、操作を含むジェネレーター/ミックスインを設計できます。

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

ただし、ミックスイン/ジェネレーターを呼び出してクラスを構築します。

.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
}

または、引数を使用してさらにエキサイティングなことを行うもの

于 2013-02-28T18:07:30.407 に答える
6

UPDATE LESS 1.7+ (希望どおりに動作)

元の.@{name}質問が望んでいたように、構文が機能するようになりました。

LESS 1.4+ 動的クラス名を実際に使用するための回避策

別の質問に取り組んでいるときにこれを回避する方法を思いついたので、以前の回答とはまったく異なる方向に進んでいるため、2番目の回答として投稿しています。

このソリューションにはいくつかの手順が必要ですが (そのため、LESS の最終的な修正ほど便利ではありません)、動的に生成されたクラス名を使用できるという実際の機能が提供されます。

最初: 動的クラスを定義する

これはあなたが計画したとおりです。

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

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

2番目:そのファイルをCSSにコンパイルします

それで、あなたがあなたをにコンパイルするとdynamicClasses.lessしましょうdynamicClasses.css。これにより、動的クラス名が実際のクラスに「解決」されます。

3 番目: その CSS を LESS として、動的クラス名を使用する 2番目の LESS ファイルにインポートします。

の型キャストを使用して@import、これを行います。

@import (less) dynamicClasses.css;

dynamicClasses.cssこれにより、ファイル内の解決されたクラス名が取得され、それらが LESS としてインポートされます。これにより、すべてのクラス名が mixin として使用できるようになります。したがって、必要に応じて次のことができます。

.someClass {
    .mtStandard; // will work
    // more stuff
}
于 2013-11-06T20:23:38.580 に答える
3

同意します。LESSはミックスインの目的でこれらのクラスを登録していないようです。

不完全な解決策

この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;
}

解決すべき最終問題の説明と議論

各ミックスインは、スタイルを取得するためにに.get()基づいて保護されたミックスインを定義しており、そのミックスインの一意の変数名@nameとクロスチェックされます。NameCheck実際のコードはすべて、で定義されており.get()、そのミックスインを使用して実際に.@{name}クラスコードが生成されます。

これは、実際のクラス名を生成するたびに正常に機能します。ただし、現在のgetter関数は、ミックスインを使用して最後に定義されたクラス名に対してのみ機能します。上記のように、の設定がミックスインを定義で上書きしたため、 get呼び出しが機能しmtStandardていません。mtSpecial#genMarginTop .get()mtSpecial

#getMarginTop今、私はあなたがあなたとあなたの他のそのようなミックスインを複数回呼び出したいと思うだろうと思います、それで明らかにこれはまだ不完全な解決策です。トップレベルのミックスインによって生成されたクラスを、を使用して別のクラスの「ミックスイン」として使用する方法を理解しましたが、トップレベルのミックスイン時にオーバーライドされない.get()ようにする方法を理解していません.get()再び呼び出されます。

于 2013-02-28T17:00:46.053 に答える