web-dev-qa-db-ja.com

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

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

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

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

「入れ子になったCSSはアンチパターンだ」と彼は言う。 「アンチパターン」とは意味であり、ネストされたCSSが悪いのはなぜですか?

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

誰かがBEMがLESSより優れている理由を詳しく説明していただけませんか?私の同僚は私を完全に説得することに失敗していますが、私が従うしかありませんかどうかわかりません。私は、不本意にそれを受け入れるよりも、実際にBEMを高く評価できるようにしたいのです。

29
coredumperror

私の同僚は、彼が担当しているプロジェクトで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状態のbarブロックがあり、baz要素が含まれていることを通知します。

BEMは古典的なモデルよりも再利用可能だと私は断言します。

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

これは、古典的なコンテキストでは、.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を使用する方向に動いているので、私たちもそうすべきです」と述べています...

それは bandwagon fallacy なので、それを悪い議論として無視してください。 fallacy fallacy にトラップを落とさないでください。BEMをサポートする悪い議論は、BEMが良いことではないと信じる理由にはならないからです。

誰かがBEMがLESSより優れている理由を詳しく説明していただけませんか?

これについては以前説明しましたが、BEMとLESSは比較できません。りんご、みかんなど.

私の同僚は私を完全に説得することに失敗していますが、私が従うしかありませんかどうかわかりません。

OOCSS、SMACSS、およびBEMを確認し、各方法論の長所と短所を比較検討することをお勧めします...チームとして。 BEMを使用するのは、形式の厳密さが好きであり、醜いセレクターは気にしないからです。しかし、あなたやあなたのチームにとって何が適切であるかはわかりません。率直な個人がショーを実行しないようにしてください。 BEMに慣れていない場合は、チームがサポートしやすい他の選択肢があることに注意してください。あなたは同僚と自分の立場を守る必要があるかもしれませんが、長期的にはあなたのプロジェクトの結果に良い影響を与えるでしょう。

私は、不本意にそれを受け入れるよりも、実際にBEMを高く評価できるようにしたいのです。

BEMの動作を説明するStackOverflowで回答を書きました 。理解しておくべき重要なことは、理想的なセレクターは0-0-1-0の固有性を持つ必要があるということです。これにより、それらは簡単にオーバーライドおよび拡張できます。

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

あなたが持っていたかもしれない場所

.widget {
    .heading {
        ...
    }
}

BEMを使用すると、以下を使用できます。

.widget {
    &__heading {
        ...
    }
}

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

32
zzzzBov

2017年を編集

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

BEMの代わりに、ViewEncapsulation、Polymer、StyledJSX、SASSモジュール、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 />

ウィジェットで宣言されたすべてのスタイルはカプセル化され、コンポーネントの外部の要素には適用されません。 divaを直接スタイル設定するだけで、ページ上の他のアイテムを誤ってスタイリングする心配はありません。

10
superluminary

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

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

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

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

2
user224551