web-dev-qa-db-ja.com

OOCSS / BEM / SMACSSアーキテクチャ

私は この記事 を通じて、フロントエンドコードを整理しています。 BEM/SMACSSの記事を参照し、次に他の記事を参照します。

私は本当にベストプラクティスが何であるかを理解しようとしています...私はこの「標準」を決定するために数日を持っており、次に優先度が高く、可視性が高く、限られたタイムラインのプロジェクトを実行する必要があります。そのため、アプリと同じように拡張できる基盤から始めたいと思います。

segmentという名前のコンポーネントが与えられた場合...ページあたり最大10 segmentsのページを作成しています。各segmentは同じ基本クラスを共有します。ただし、特定のsegmentsには修飾子(異なる背景色)があります。さらに、(BEMアプローチの)各ブロック内の要素にも修飾子があります。実例として、これは単純な実装です(単一の要素arrowのみですが、フルサイトでは各segmentに4〜5個の要素があります):

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    @extend .segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    @extend .segment__arrow;
    background-image: url('/images/arrow_white.png');
}

したがって、これは単一クラスのアプローチです。

<div class="segment__arrow--white"> ... </div>

または、マルチクラスアプローチを使用することもできます。

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow--orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--white {
    background-image: url('/images/arrow_white.png');
}

私のマークアップはどこにあるでしょう:

<div class="segment__arrow segment__arrow--white"> ... </div>

第三に、私はできる:

.segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}
.segment__arrow.orange {
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow.white {
    background-image: url('/images/arrow_white.png');
}

そして、私のクラスのdefは

<div class="segment__arrow orange"> ... </div>

おそらく、sa_orange緩やかなセレクターを避けるため。

私が探している最終結果は、コードが少ない/保守が簡単です(これは、スケーラブルなアーキテクチャでこの 素晴らしい記事 で説明されているように、おそらく単一クラスのアプローチ(オプション1)を除外します)。マルチクラスアプローチ(オプション2)は多くの冗長性(特に私のHTML)をもたらしますが、非常に明示的です。3番目はマルチクラスアプローチを使用しますが、名前空間修飾子(.segment__arrowなど)を使用しないため、少し冗長です(しかし、衝突の可能性が低く、可能性も高い)。

これに関する実世界の経験を持つ誰かがこれに取り組む最良の方法についてフィードバックを持っていますか?

8
Scott Silvi

長い間、私はexplicit multi-classアプローチ(2番目の例)を使用および推奨してきました。 。ここで私はこの主張を支持しようとします。

シングルクラス

このアプローチは、修飾子のカテゴリが2つ以上ある場合に大きな問題があります。たとえば、。button修飾子smalllargehugeサイズ、primarysuccessinfo、および「色」の警告通常の7(= 3 + 4)クラスに加えて、12の組み合わせもすべて作成する必要があります。

.button--small--primary
.button--small--success
.button--small--info
…

これまでのところ少し不便ですが、災害ではありません。

もう1つの煩わしさ-より大きなもの-は、正しい順序「サイズが最初、色が2番目」を使用する必要があるため、覚えておく必要があります(十分に文書化されています)。

最悪なのは、JavaScriptが関係している場合です。このボタンの「色」を変更して、現在のサイズを維持したいですか?クラス属性を解析してください! success修飾子を削除したいですか?クラス属性を解析してください!

それを数えますBootstrapには7つの「色」、4つのサイズ、およびアクティブ/無効の状態があります。そのため、119(= 13 + [7 * 4 + 7 * 2 + 4 * 2] + 7 * 4 * 2)単一クラスのアプローチを維持するには、クラスを宣言する必要があります!これは大きな問題です。

明示的なマルチクラスには、13のクラス(各修飾子に1つ)だけが必要です。順序は任意です。最後に、1つを追加、削除、および変更しながら、他のものを保持すると、jQueryでは次のようになります。

$('#login-button').removeClass('button--primary').addClass('button--success');

ショートカットマルチクラス

まず、あなたが言ったように、衝突の可能性があります-それ自体は悪いことです。

第二に、それが意味することは、.segment__arrow.orangeはより高い特異性を持ち、単一のクラスセレクターで上書きできません。これは、要素がたとえば大きなボタンだけでなく、たとえばログインボタン。そのコードは次のようになります。

<a href="#" class="button large primary login__button">Log in</a>

ログインボタンの左右のパディングを大きくしたいが、largeの高さは維持したい場合があります。これにより、ますます特定のセレクターが得られ、特定性の地獄-OOCSSが私たちを救うべき場所に連れて行くでしょう。

これは明示的なマルチクラスアプローチでは発生しないことは明らかです。

明示的なマルチクラス

これの唯一の問題(私が知る限り)は、マークアップに非常に長いクラスがいくつかあることです。私はこれを認めます。

これは、パフォーマンスへの影響がごくわずか(まったくない)であるため、開発者の好みの問題にすぎないことに注意してください。標準の圧縮がこれを処理します。

そうは言っても、適切なIDE=を使用すると、これらを書くのに役立ちます(そうです、私は知っていますが、それでも少しばかげているように見えます)。

一方で、そのような長いクラスを見ると、構造についてもっと考えるように強いられます。例えば別のコンポーネントにネストするのではなく、新しい(再利用可能な)コンポーネントを導入する方が良いかどうか。

8
Robin Pokorny

私は今、このシングル/マルチクラスの問題についてチームメイトと議論しています

これは、ベストプラクティスに基づく私の個人的なビューの一部です

ベストプラクティス

  • htmlは要素を宣言します
  • CSSコントロールのレンダリング

単一クラスは常にベストプラクティスに従っています

良い名前でそれが達成できる追加の維持の利点で

  • スタイルの変更にはhtmlの更新は必要ありません*(デモを参照)

  • hTMLのロックスタイル(適切なスタイルまたは何もない)

デモ

@mixin segment__arrow {
    position: absolute;
    bottom: -24px;
    left: 50%;
    margin-left: -11px;
    background-position: center no-repeat;
    height: 21px;
    width: 21px;
    z-index: 2;
}

.segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
.segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}

@ mixin includeは@extendよりも優れています

  1. 最終CSSでコードの順序を制御できます
  2. gzipバージョンの小さいサイズ

@extendと同じで、再利用でき、HTMLのマルチクラスを置き換えることができます

@mixinを使用すると、柔軟性が向上します

@mixin segment__arrow--type1 {
    @include segment__arrow;
    background-image: url('/images/arrow_orange.png');
}
@mixin segment__arrow--type2 {
    @include segment__arrow;
    background-image: url('/images/arrow_white.png');
}
.segment__margic-arrow {
    @include screen(mobile) {
       @include segment__arrow--type1
    }
    @include screen(desktop) {
       @include segment__arrow--type2
    }
}

javascriptの場合

smacssの状態規則

単一クラスの欠点

一つだけ:

cSSファイルサイズが大きい場合でも、ページ内のWebサイトセクションまたはコンポーネントに基づいてCSSをいつでも簡単に最適化する

0
Liang