LESSのようなネスト可能なスタイルシート言語を使用するよりもBEMが優れているのは何ですか?


27

私の同僚は、彼が手がけているプロジェクトでCSS のBEM(Block Element Modifier)メソッドを強く推し進めており、何年も書いてきたLESS CSSよりも優れているものを理解できません。

彼は「より高いパフォーマンス」を主張していますが、このコードショップで作成する種類のWebアプリにとって、パフォーマンスがどのように重要になるか想像できません。ここでは、TwitterやFacebookを作成していません。最も使用頻度の高いアプリが1か月に10000件以上ヒットし、ほとんどのアプリが1000件を大幅に下回っている場合、私は非常に驚きます。

彼は「読みやすさ」と「再利用」を主張していますが、私の意見では、LESSはすでにそれをはるかに上回っています。そして、BEMはこれらの非常に長いクラス名に特化した数十の余分な文字でマークアップをひどく壊し、読みやすさを根本的に低下せると感じています。

彼は「ネストされたCSSはアンチパターンである」と主張しています。「アンチパターン」とはどういう意味ですか?また、ネストされたCSSが悪いのはなぜですか?

彼は「誰もがBEMを使用する方向に動いているので、私たちもそうすべきだ」と主張しています。私のカウンターは「誰もが橋から飛び降りていたら、あなたはフォローしますか?」です。しかし、彼はまだこれについて完全に頑固です。

誰かがBEMをLESSより良くする理由を詳細に説明してもらえますか?私の同僚は完全に私を説得することに失敗しているが、私は選択肢に従うかどうかはわからない。私は、BEMを不承不承に受け入れるよりも、むしろむしろBEMに感謝することができます。


1
BEMとLESSは異なる目的を果たします。BEMとLESSの両方を使用します。
zzzzBov

4
BEMは主にCSSに関するものではないことに注意してください。デザイン内の繰り返しカプセル化されたパターンを識別し、そのブロックに必要なすべて(動作、テンプレート、スタイル)を1か所に集めます。CSSのみに制限されていても、BEMはスタイルを整理し、名前の衝突を確実に防ぐ優れた方法です。これらはすべて、マクロや変数、簡略表記、あらゆる種類の優れた機能を提供するため、プレーンCSSよりも生産的なスタイリング言語であるLESSやSASSなどのプリプロセッサから完全に独立しています。LESS = win、BEM = win、ただしLESS×BEM =win²!
アモン

回答:


29

私の同僚は、彼が手がけているプロジェクトでCSSのBEM(Block Element Modifier)メソッドを強く推し進めており、何年も書いてきたLESS CSSよりも優れていることを理解できません。

BEMはCSSの方法論です。その他には、OOCSSおよびSMACSSが含まれます。これらの方法論は、大規模で優れたパフォーマンスを発揮するモジュール式の拡張可能な再利用可能なコードを記述するために使用されます。

LESSはCSSプリプロセッサです。その他には、SassおよびStylusが含まれます。これらのプリプロセッサは、それぞれのソースを拡張されたCSSに変換するために使用されます。

BEMとLESSはお互いに「優れている」とは比較できず、異なる目的に役立つツールです。特定の問題を解決するためのユーティリティを検討する場合を除き、ドライバーはハンマーよりも優れているとは言いません。

彼は「より高いパフォーマンス」を主張しています...

次の古典的なCSSスタイルの間でパフォーマンスを測定する必要があります。

.widget .header

およびBEMスタイル:

.widget__header

しかし、一般的に言えば、CSSセレクターのパフォーマンスはボトルネックではなく、最適化する必要はありません。

BEMの「パフォーマンス」は、通常、開発者のパフォーマンス記述コードに関するものです。BEM方法論が一貫して正しく使用されている場合、開発者のグループはスタイルの衝突なしに個別のモジュールを同時に簡単に作成できます。

彼は「読みやすさ」と「再利用」を主張しています...

新しい開発者に、BEMの方が読みやすいと伝えるかどうかはわかりません。クラスの意味と構造に関して明確に定義されたガイドラインを提供していると言えます。

のようなクラスを見る

.foo--bar__baz

状態にあり、要素を含むfooブロックがあることを教えてくれます。barbaz

私は絶対に、BEMは古典的なモデルよりも再利用可能であると言います。

2人の開発者がブロック(fooおよびbar)を作成し、それらのブロックの両方に見出しがある場合、命名の衝突を心配することなく、異なるコンテキストでブロックを安全に再利用できます。

これは、古典的な文脈で、あるためだ、.foo .heading.bar .heading競合する、そしておそらく、ケースバイケースで、解決される必要があるであろう特異性の競合を紹介します。

BEMサイトでは、クラスはとに.foo__headingなり.bar__heading、競合することはありません。

彼は「ネストされたCSSはアンチパターンだ」と主張しています。「アンチパターン」とはどういう意味で、ネストされたCSSが悪いのはなぜですか?

「アンチパターン」は、経験の浅い開発者がより適切な代替手段よりも簡単に学習して使用できるコーディングパターンです。

ネストされたCSSが悪い理由に関しては、ネストはセレクターの特異性を高めます。特異性が高いほど、オーバーライドするのに多くの労力がかかります。経験の浅い開発者はしばしば、CSSが複数のページに影響を与えるのではないかと心配するため、次のようなセレクターを使用します。

#something .lorem .ipsum .dolor ul.sit li.amet a.more

経験豊富な開発者がCSS 複数のページに影響を与えないかもしれないと心配する場合、次のようなセレクタを使用します

.more

彼は「誰もがBEMを使用する方向に動いているので、私たちもそうすべきだ」と主張しています。...

それは時流の誤りであるので、それを悪い議論として無視してください。BEMを支持する悪い議論は、BEMが良くないと信じる理由ではないので、誤acyの fallに陥らないでください。

誰かがBEMをLESSより良くする理由を詳細に説明してもらえますか?

これについては前に説明しましたが、BEMとLESSは比較できません。リンゴとオレンジなど

私の同僚は完全に私を説得することに失敗しているが、私は選択肢に従うかどうかはわからない。

OOCSS、SMACSS、およびBEMを見て、各方法論の長所と短所をチームとして検討することをお勧めします。私はBEMを使用していますが、それは形式が厳密であることを好み、selectorいセレクターを気にしないからです。率直な人にショーを実行させないでください。BEMに慣れていない場合は、チームがサポートしやすい他の代替手段があることに注意してください。同僚との立場を守る必要があるかもしれませんが、長期的にはプロジェクトの成果にプラスの影響を与える可能性があります。

私は、BEMを不承不承に受け入れるよりも、むしろむしろBEMに感謝することができます。

StackOverflowで、BEMの仕組みを説明した回答を書きました。理解しておくべき重要なことは、理想的なセレクターは、0-0-1-0オーバーライドおよび拡張しやすいように特定性を持つ必要があるということです。

BEMを使用することを選択しても、LESSを放棄する必要があるわけではありません。引き続き変数を使用でき、@ importsを使用でき、ネストを引き続き使用できます。違いは、レンダリングされた出力を、子孫チェーンではなく単一のクラスにすることです。

あなたがいたかもしれない場所

.widget {
    .heading {
        ...
    }
}

BEMでは次を使用できます。

.widget {
    &__heading {
        ...
    }
}

さらに、BEMは個々のブロックを中心に展開するため、コードを個別のファイルに簡単に分離できます。ブロックのwidget.lessスタイルが含まれる.widget一方component.lessで、.componentブロックのスタイルが含まれます。これにより、特定のクラスのソースを簡単に見つけることができますが、ソースマップを使用したい場合もあります。


4
@CoreDumpError、問題はモジュール内でモジュールのネストを開始するときです。「各開発者は特定のウィジェットのコードを1レベルだけネストできる」というのはまったく正しくありません。各開発者特定のウィジェットのコードをさらに深くネストする必要があります。名前の衝突を回避する唯一の方法は、ある種の名前空間を使用することです。BEMは、一貫して名前空間クラスを作成する簡単な方法を提供します。
zzzzBov

3
@CoreDumpError、この例を検討してください。BEMを使用せずに作成する著者は、モジュール内に追加される可能性のあるすべてのモジュールのすべての組み合わせを検証するために、追加の労力を費やす必要あります。BEMを使用する作成者は使用しません。
zzzzBov

1
@CoreDumpError、確かにそうかもしれません。BEMは新しい開発者のトレーニングを容易にし、コードレビューを容易にしますが、SMACSSとOOCSSは優れた代替手段です。選択肢としてこれらのオプションを検討することを強くお勧めします。私は自分自身、特に愚かで物事を忘れる将来の私と対立しないように、自分の開発にBEMを使用すると言います。
zzzzBov

1
BEMは、あらゆる種類の複雑さを伴うプロジェクトで優れています。WordPress上にあり、JavaScriptのみを使用してスクロールをトリガーするサイトを作成できますが、それでもCSSのWebアプリと同じくらい複雑です。それは(マーケティングのサイトの多くが好きです)純粋に視覚的な分野でのものの大半を行うという理由だけで「私のサイトではなく、複雑である」思考の罠に落ちないようにすることが重要だ
トニ・リー

1
@CoreDumpError私の以前のプロジェクトのほとんどは単独の努力であり、私は自分自身のre:特異性とユニークなセレクターで多くのBEMに到達しました。コードベースの維持は、BEMで非常に明らかになる大きな問題です。コードはメンテナンスです。ものを作るのは簡単です。完全なパターンを保持することは、特にコードベースから数か月離れた後は困難です。特異性の問題は時間とともに悪化します。メリットは、あらゆる規模のチームIMOに適用されます!
富田裕二

8

編集2017

2017年にこれを読んでいる場合、シャドウDOMとシャドウDOMポリフィル、およびコンポーネントは、これらの問題をすべて解決すると同時に、コードを小さく、タイトで、モジュール化したままにします。グリーンフィールドプロジェクトIMOでBEMを使用しないでください。

BEMの代わりに、ViewEncapsulation、Polymer、StyledJSX、SASS Modules、Styled Componentsなどのツールがあります。

コンポーネント指向のアーキテクチャがない場合は、BEMの使用を検討してください。サポートするレガシーコードがある場合; または、ツールを使用せずにすべてを手動で行うことに完全に満足していない場合。


BEMは、DOMのネストに依存しないスタイル設定を行います。これは、スタイルを設定したいすべての要素に、ページ上で一意である可能性が高い大きなクラス属性を与えることでこれを行います。その後、ほとんどのスタイリングはクラスで行われます。

これにより、コードがよりモジュール化されます。これは、ネストが考慮されなくなったため、かなりの冗長性が犠牲になります。

BEMなし

BEMがなければ、これを書くかもしれません:

<div class="widget">
  <a>Hello!</a>
  <ul>...</ul>
</div>

標準のCSSスタイルは次のようになります。

.widget {
  border: 1px solid red;
}

.widget a {
  color: green;
}

SASSでの同じことは次のようになります。

.widget {
  border: 1px solid red;
  a {
    color: green;
  }
}

誰もがCSSを高水準にコーディングできる小規模なチームであり、プロジェクトが十分に小さいために十分な認知度を維持できる場合、これは適切かつ合理的なソリューションです。

BEMを使用

ただし、コードが大きくなり、大規模な混合能力チームがある場合、これはそれほど単純なソリューションではない可能性があります。たとえば、別のウィジェットに緑色のアンカーが必要な場合はどうでしょう。そこで、アンカーをモジュール化し、子孫セレクターを削除します。

今、私たちのHTMLはもっと冗長です:

<div class="widget">
  <a class="widget__anchor">Hello!</a>
  <ul class="widget__ul">...</ul>
</div>

CSSには子孫セレクターがありません。

.widget {
  border: 1px solid red;
}

.widget__anchor {
  color: green;
}

しかし、これを行うことができます。

<div class="widget__2">
  <a class="widget__anchor">Hello!</a>
</div>

widget__anchorはモジュール式です。.widget__anchorの別の定義がページに存在することはほとんどありません。

トレードオフ:

BEM:

  • よりモジュール化されたコードを提供します。任意のピースを分離して取ることができます。
  • 誰でもCSSを記述できます。マスタースタイリングとカスタムオーバーライドを意識する必要はありません。大規模なチームでは、これは素晴らしいことです。
  • 特異性の問題を削除します。
  • かなり冗長です。

標準CSS(子孫セレクターの使用に依存):

  • スタイルがコンテキストに依存していることを意味します。
  • カスケードの認識が必要です。一度配置したコードは、他の場所のコードに影響を与える可能性があります。小さなチームでは、これは良いことです。
  • 初心者の開発者がデバッグするのが難しいかもしれない特異性の問題に苦しむことができます。
  • かなりタイトです。

3番目の方法-実コンポーネント。

React、Angular 2、またはその他の最新のフロントエンドフレームワードのようなものを使用している場合、別のソリューションがあります。ツールを使用してカプセル化を強制できます。

この例ではReactとStyledJSXを使用していますが、多くのオプションがあります。ウィジェットは次のとおりです。

const Widget = () => 
  <div>
    <a>Hello</a>
  </div>
  <style jsx>
    div {border:red }
    a { background: pink }
  </style>

次に、このような新しいウィジェットを使用します。

<Widget />

ウィジェットで宣言されたすべてのスタイルはカプセル化され、コンポーネント外の要素には適用されません。ページ上の他のものを誤ってスタイリングすることを心配することなくdiv、単純にスタイルをa直接設定できます。


1
長所と短所はどちらの側にも賛成せず、私はそれが好きです。
エイドリアンモイサ

「カスケードを理解していない人が理解できるように、このようにコードを書いてください」と言うのは本当に悲しいことだと思います。「チームのジュニアメンバーの1人が配列の仕組みを理解していないため、配列なしでコードを記述しています」と言っているようなものです。個人的には、カスケードスタイルシートの自然なカスケード側を優先する、より簡潔な方法を好みます。
マットフレッチャー

@MattFletcher-プロジェクトの規模の問題だと思います。カスケードは本質的にグローバルです。値を設定してから、ツリー全体でオーバーライドおよびオーバーライドします。完全な可視性を備えた小さなプロジェクトがある場合はこれで問題ありませんが、大きなプロジェクトでは脆弱になります。カスケードの上位の変更が他の場所のランダムなものを壊すため、人々は物事を変えることを恐れます。コンポーネントのカプセル化は、実際には大規模なプロジェクトで非常に便利です。すべてが機能します。
超光度

2

完璧なアプローチはありません。私見、私たちはそれぞれの方法論(BEM、SMACSS、OOCSS、DRY)の最良の部分を取得する必要があります。SMACSSを使用して、CSSでフォルダー構造を整理します。特に、CSS全体の論理レベルの内訳を定義するために使用します。DRYを使用してユーティリティライブラリを作成するか、BEMベースのクラスと組み合わせて使用​​されることがある共通の修飾子ライブラリである場合があります。コンポーネントのOOCSS。そして、小さなコンポーネントまたはサブコンポーネントのBEM。そこで、あなたは複雑さを分散し、大きなチームの中で働く自由を得ることができます。

その本質を理解せずに使用すると、何も悪い結果になります。

BEMは大規模なチームには適したアプローチですが、いくつかの欠点もあります。1.大きなHTML構造で非常に長い名前になることがあります。結果として大きなCSSファイルサイズ。2. 2-3レベルを超えるhtmlをネストする場合、名前を定義するのは頭痛の種になります。

コンポーネント構造と基本スタイルの非常に基本的なセットを考えれば、競合の解決は簡単に管理できます。これは、2レベルの継承のみです。コンポーネント内のすべての要素には、グローバルスタイルルールがあるか、そのコンポーネント固有のものがあります。これは簡単なオプションの1つです。


非常に良い議論。開発者は自分で考え、問題の範囲を分析できる必要があります。盲目的に方法論に従うだけでも、トラブルにつながります。私が持っている同僚は、ページに対する変更の影響をまったく考慮しておらず、どの方法論が南に進んでいるかは関係ありません。私は、チームのCSS認識レベルを上げるように力を入れています。ローカルスタイルとグローバルスタイルの入れ子のSASSは、プロジェクトを読みやすくするために十分です。
エイドリアンモイサ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.