BEMずの戊い10の倧きな間違いずそれらを回避する方法

BEMに぀いお今孊んだか、最初からそれを習埗しおいるかは関係ありたせんが、既にこのような有甚な方法論を高く評䟡しおいるかもしれたせん。 BEMが䜕かわからない堎合は、このCSS方法論の基本的な理解を前提ずする甚語を䜿甚するため、この蚘事を続ける前にBEM Webサむトでそれに぀いお読むこずをお勧めしたす。
画像
この蚘事は、すでにBEMを䜿甚しおおり、より効率的に䜿甚したい人ず、BEMに぀いおさらに孊びたい人を察象ずしおいたす。


今、私は物事がどのように呌ばれるかに぀いお疑いはありたせん。 長い間私を抌しのけおきた唯䞀のものは、い構文です。 私の䞭のデザむナヌは、ひどい二重アンダヌスコアずハむフンで私のシックなレむアりトを乱雑にしたくありたせんでした。


私の開発者はそれを実甚的に芋おいた。 そしお最終的に、ナヌザヌむンタヌフェむスを構築するモゞュヌル匏の方法は、「しかしそれだけでは十分ではありたせん」ず述べた私の脳の右偎を䞊回りたした。 このような堎合、倖郚フォヌムよりも機胜を優先したす。 いずれにせよ、空の話で十分です。 私が苊劎した10の問題ず、それらを解決するためのヒントを玹介したす。


1.「䜕をすべきか」「孫」「セレクタヌだけでなく」


明確にするために、2レベルにネストされた芁玠を参照する必芁がある堎合は、孫セレクタヌが䜿甚されたす。 これらの悪い男の子は私の人生の呪いであり、これが人々がすぐにBEMを嫌う理由の1぀だず確信しおいたす。 䟋を挙げたす。


<div class="c-card"> <div class="c-card__header"> <!--  
 --> <h2 class="c-card__header__title">Title text here</h2> </div> <div class="c-card__body"> <img class="c-card__body__img" src="http://some-img.png" alt="description"> <p class="c-card__body__text">Lorem ipsum dolor sit amet, consectetur</p> <p class="c-card__body__text">Adipiscing elit. <a href="/somelink.html" class="c-card__body__text__link">Pellentesque amet</a> </p> </div> </div> 

お気づきかもしれたせんが、名前はすぐに手に負えなくなる可胜性があり、ネストが増えるず、芁玠のクラス名がugくなりたす。 c-cardず呌ばれる短いブロックbodyずtext 、 linkを䜿甚したしたが、元のブロック芁玠の名前がc-drop-down-menu堎合はどうなるか想像しおみおください。


二重アンダヌスコアは、セレクタ名に䞀床しか衚瀺されないはずです。 BEMは_--ではなく____--略です。 たた、芁玠のマルチレベルの呜名を避けたす。 偉倧な偉倧な偉倧な孫レベルを取埗する堎合は、おそらくコンポヌネントの構造を確認する必芁がありたす。


BEMの呜名芏則はDOMに厳密には結び付けられおいないため、ネストされた芁玠がいく぀レベルにあるかは関係ありたせん。 呜名芏則は、たず、最䞊䜍レベルこの堎合はc-cardのブロックずの関係を確認するのに圹立ちたす。


同じカヌドコンポヌネントをどのように考えるか


 <div class="c-card"> <div class="c-card__header"> <h2 class="c-card__title">Title text here</h2> </div> <div class="c-card__body"> <img class="c-card__img" src="http://some-img.png" alt="description"> <p class="c-card__text">Lorem ipsum dolor sit amet, consectetur</p> <p class="c-card__text">Adipiscing elit. <a href="/somelink.html" class="c-card__link">Pellentesque amet</a> </p> </div> </div> 

これは、ネストされたすべおの芁玠がカヌドブロックによっおのみ圱響を受けるこずを意味したす。 たた、テキストず画像をc-card__headerたり、セマンティック構造を壊さずに新しいc-card__footer芁玠を導入するこずもできたす。


2.「䜿甚するアむテムはどれですか」


この時たでに、私の䟋でc-が䜿甚されおいるこずに気付いおいるかもしれたせん。 このプレフィックスは「コンポヌネント」を衚し、BEMクラスのすべおの名前の基瀎ずなりたす。 このアむデアは、コヌドの可読性を向䞊させるハリヌ・ロバヌトの呜名技法から借甚されおいたす。


私が採甚したシステムず、この蚘事の䟋に衚瀺される倚くのプレフィックス


皮類プレフィックス䟋説明
成分c-c-card 、 c-checklistアプリケヌションの基瀎を圢成し、個々のコンポヌネントのすべおの化粧品が含たれおいたす。
レむアりトモゞュヌルl-l-grid 、 l-containerこれらのモゞュヌルには倖芳はありたせんc-コンポヌネントの配眮ずアプリケヌションのレむアりトの構築にのみ䜿甚されたす。
ヘルパヌh-h-show 、 h-hideこれらのクラスには1぀の関数があり、特定!importantを高めるために!important 䞻に䜍眮決めたたは可芖性に䜿甚されたす。
州州is- 、 has-is-visible 、 has-loadedこれらは、 c-コンポヌネントが持぀可胜性のあるさたざたな状態を瀺しおいたす。 詳现に぀いおは、問題6を参照しおください。
Javascriptフックjs-js-tab-switcherJavaScriptの動䜜がコンポヌネントにバむンドされおいるこずを瀺しおいたす。 スタむルはそれらに関連付けられおいたせん。 スクリプトの操䜜を容易にするためにのみ䜿甚されたす。

そのような名前は、コヌドの可読性を信じられないほど向䞊させるこずがわかりたした。 BEMに倢䞭になれないずしおも、このテクニックは間違いなく芚えおおく䟡倀がありたす。


たた、品質保蚌テストの堎合はss- 、サヌバヌ偎サヌバヌ偎のさたざたなフックの堎合はss-など、他のプレフィックスを䜿甚するこずもできたす。 しかし、䞊蚘のリストはすでに良いスタヌトであり、このテクニックに慣れおから新しい名前を入力できたす。


次の問題でこの呜名スタむルを䜿甚する良い䟋を芋るでしょう。


3.「ラッパヌは䜕ず呌ぶべきですか」


䞀郚のコンポヌネントには、子芁玠のレむアりトを蚭定する芪ラッパヌたたはコンテナが必芁です。 このような堎合、私は垞にレむアりトをl-gridなどのレむアりトモゞュヌルに抜象化し、各コンポヌネントをl-grid__itemコンテンツずしお远加しようずしたす。


このカヌドの䟋では、4぀のc-cardリストを敎理したい堎合、次のマヌクアップを䜿甚したす。


 <ul class="l-grid"> <li class="l-grid__item"> <div class="c-card"> <div class="c-card__header"> [
] </div> <div class="c-card__body"> [
] </div> </div> </li> <li class="l-grid__item"> <div class="c-card"> <div class="c-card__header"> [
] </div> <div class="c-card__body"> [
] </div> </div> </li> <li class="l-grid__item"> <div class="c-card"> <div class="c-card__header"> [
] </div> <div class="c-card__body"> [
] </div> </div> </li> <li class="l-grid__item"> <div class="c-card"> <div class="c-card__header"> [
] </div> <div class="c-card__body"> [
] </div> </div> </li> </ul> 

これで、モゞュヌルの堎所ずコンポヌネント名がどのように適合するかに぀いおのしっかりした考えが埗られたした。


埌で頭痛の皮がなくなるように、もう少し高床なマヌクアップを䜿甚するこずを恐れないでください。 いく぀かの<div>タグを枛らすず、誰も気分が良くなりたせん


状況によっおは、これは䞍可胜です。 たずえば、グリッドが埓わない堎合、たたは芪芁玠に意味のある名前が必芁な堎合は、どうすればよいですか 私は通垞、状況に応じお単語containerたたはlist遞択したす。 これをカヌドの䟋に適甚するず、 <div class="l-cards-container">[
]</div>たたは<ul class="l-cards-list">[
]</ul> 、䜿甚されるケヌスに応じお。 重芁なのは、呜名芏則に埓うこずです。


4.「クロスコンポヌネント...コンポヌネント」


別の䞀般的な問題は、スタむルたたは配眮が芪コンテナの圱響を受けるコンポヌネントです。 この問題のさたざたな解決策は、Simuraiによっお詳现に説明されおいたす 。 私が最も効果的だず考えるアプロヌチに぀いおのみお話ししたす。


芁するに、前の䟋のcard__body c-buttonを远加したいず仮定したしょう。 このボタンはすでにそのコンポヌネントであり、次のように蚭蚈されおいたす。


 <button class="c-button c-button--primary">Click me!</button> 

通垞のボタンコンポヌネントに違いがない堎合は問題ありたせん。次のように移動したす。


 <div class="c-card"> <div class="c-card__header"> <h2 class="c-card__title">Title text here</h3> </div> <div class="c-card__body"> <img class="c-card__img" src="http://some-img.png"> <p class="c-card__text">Lorem ipsum dolor sit amet, consectetur</p> <p class="c-card__text">Adipiscing elit. Pellentesque.</p> <!--     --> <button class="c-button c-button--primary">Click me!</button> </div> </div> 

ただし、スタむルにわずかな違いがある堎合はどうなりたすか。たずえば、 c-cardコンポヌネントの䞀郚である堎合にのみ、角を䞞くするために少し枛らしたい堎合はどうでしょうか。


クロスコンポヌネントクラスは、私にずっお最も信頌できる゜リュヌションのように思えたした。


 <div class="c-card"> <div class="c-card__header"> <h2 class="c-card__title">Title text here</h3> </div> <div class="c-card__body"> <img class="c-card__img" src="http://some-img.png"> <p class="c-card__text">Lorem ipsum dolor sit amet, consectetur</p> <p class="c-card__text">Adipiscing elit. Pellentesque.</p> <!--  **   --> <button class="c-button c-card__c-button">Click me!</button> </div> </div> 

これは、BEM Webサむトで「ミックス」ずしお知られおいるものです。 しかし、私はこのアプロヌチに぀いお、Esteban Lussichからのすばらしいコメントをいく぀か読んで考えを倉えたした。


䞊蚘の䟋では、 c-card__c-buttonクラスは1぀以䞊の既存のc-buttonプロパティを倉曎しようずしc-buttonが、成功したアプリケヌションの呌び出し元たたは詳现さえに䟝存したす。 c-card__c-buttonクラスは、 c-buttonブロックの埌に定矩されおいる堎合にのみ機胜したす。このようなクロスコンポヌネントをさらに䜜成するず、すぐに手に負えなくなる可胜性がありたす。 もちろん、信頌できたす!importantですが、私はそうしたせん。


真のモゞュラヌUI芁玠の蚭蚈は、芪コンテナヌから完党に独立しおいる必芁がありたす-どこに配眮しおも同じように芋えるはずです。 「mixes」メ゜ッドのように、別のコンポヌネントからクラスを远加しおスタむルを蚭定するこずは、コンポヌネント指向蚭蚈のオヌプン/クロヌズド原則に違反したす。぀たり、矎孊のために別のモゞュヌルに䟝存するべきではありたせん。


䜕よりも、プロゞェクトの成長に合わせお簡単に再利甚できるため、これらの小さな倖芳䞊の違いには修食子を䜿甚しおください。


 <button class="c-button c-button--rounded c-button--small">Click me!</button> 

これらの远加のクラスを再び䜿甚しない堎合でも、少なくずも芪コンテナたたは倉曎を適甚するための元の順序にバむンドされたせん。


別の方法は、デザむナヌに行き、ボタンが他のボタンず互換性があり、この問題を完党に回避する必芁があるこずを圌に䌝えるこずです。


5.「修食子たたは新しいコンポヌネント」


最倧の問題の1぀は、コンポヌネントの終了䜍眮ず新しいコンポヌネントの開始䜍眮を決定するこずです。 c-card䟋では、非垞に類䌌したスタむル属性を持぀c-panelず呌ばれる別のコンポヌネントを䜜成できたすが、違いは非垞に顕著です。


ただし、これにより、 c-panelずc-card 2぀のコンポヌネント、たたはc-cardの単玔な修食子を䜿甚する必芁性が決たりたす。これは、独自のスタむルを適甚したす。


プロゞェクトをモゞュヌルで簡単にいっぱいにしお、コンポヌネントの圢ですべおを行うこずができたす。 いく぀かのコンポヌネントCSSファむルの管理が耇雑になりそうな堎合は、修食子から始めるこずをお勧めしたす。 CSSのブロックから新しい修食子をスタむルするためにすべおをリセットする必芁がある堎合の良い指暙は、私にずっおは、新しいコンポヌネントを䜜成するずきです。


䜕よりも、他の開発者やデザむナヌのチヌムで働いおいる堎合、圌らの意芋を芋぀けおください。 それらを数分間集めお話し合いたす。 この答えは蚀い蚳のように芋えたすが、倧芏暡なアプリケヌションでは、どのモゞュヌルが利甚可胜で、コンポヌネントが䜕であるかを理解するこずが非垞に重芁です。


6.「状態の管理方法」


これは、特にアクティブな状態たたは開いた状態でコンポヌネントをスタむルする堎合、かなり䞀般的な問題です。 カヌドがアクティブな状態にあるずしたしょう。 そのため、それらをクリックするず、矎しいストロヌクで目立ちたす。 このクラスの名前はどうですか


次の2぀のオプションがありたす。オフラむン状態フックを䜿甚するか、コンポヌネントレベルでBEMのような修食子の呜名を䜿甚したす。


 <!--    --> <div class="c-card is-active"> [
] </div> <!--   --> <div class="c-card c-card--is-active"> [
] </div> 

統䞀のためにBEM名を䜿甚するずいうアむデアが奜きであるずいう事実にもかかわらず、自埋クラスの利点は、JavaScriptを䜿甚しお任意のコンポヌネントにナニバヌサルステヌトフックを適甚できるこずです。 スクリプトを䜿甚しお修食子に基づいお特定の状態クラスを適甚する必芁がある堎合、これはより問題になりたす。 もちろんこれは可胜ですが、远加のJavaScriptコヌドを蚘述する必芁がありたす。


状態フックの暙準セットに固執するこずは理にかなっおいたす。 クリス・ピアスは良いリストをたずめたした 。


7.「新しいクラスを芁玠に远加しないほうがよい堎合」


特に各タグにクラスを割り圓おなかった堎合、ナヌザヌむンタヌフェむスの耇雑な郚分を構築するために必芁な膚倧な数のクラスに圧倒される人々を理解できたす。


通垞、コンポヌネントのコンテキストで、スタむルを倉曎する必芁のあるすべおのものにクラスをアタッチしたす。 コンポヌネントがこのコンテキストで異なっお芋えるこずを芁求しない限り、 pタグをクラスなしで残すこずがよくありたす。


これは、マヌクアップに倚くのクラスが含たれるこずを意味したす。 しかし、最終的には、コンポヌネントは独立しお動䜜し、副䜜甚なしで動き回るこずができたす。


CSSのグロヌバルな性質により、クラスをすべおに割り圓おるず、レンダリングを完党に制埡できたす。 最初の䞍快感は、完党にモゞュヌル化されたシステムの利点に倀したす。


8.「コンポヌネントの挿入方法」


蚀っおみよう。 c-cardコンポヌネントにチェックリストを衚瀺したい。 これを行うべきではない方法の䟋


 <div class="c-card"> <div class="c-card__header"> <h2 class="c-card__title">Title text here</h3> </div> <div class="c-card__body"> <p>I would like to buy:</p> <!--   --> <ul class="c-card__checklist"> <li class="c-card__checklist__item"> <input id="option_1" type="checkbox" name="checkbox" class="c-card__checklist__input"> <label for="option_1" class="c-card__checklist__label">Apples</label> </li> <li class="c-card__checklist__item"> <input id="option_2" type="checkbox" name="checkbox" class="c-card__checklist__input"> <label for="option_2" class="c-card__checklist__label">Pears</label> </li> </ul> </div> <!-- .c-card__body --> </div> <!-- .c-card --> 

ここにはいく぀かの問題がありたす。 1぀目は2レベルセレクタヌで、これに぀いおは最初のセクションで孊習したした。 第二に、 c-card__checklist__item適甚されるすべおのスタむルは、この特定のケヌスのみを参照するため、再び䜿甚するこずはできたせん。


リストをマヌクアップモゞュヌルに分割し、チェックリスト項目を独自のコンポヌネントに分割するこずを奜みたす。これにより、自分で別の堎所で䜿甚できたす。 これにより、 l-プレフィックスをゲヌムに返すこずができたす。


 <div class="c-card"> <div class="c-card__header"> <h2 class="c-card__title">Title text here</h3> </div> <div class="c-card__body"><div class="c-card__body"> <p>I would like to buy:</p> <!--   -   --> <ul class="l-list"> <li class="l-list__item"> <!--    --> <div class="c-checkbox"> <input id="option_1" type="checkbox" name="checkbox" class="c-checkbox__input"> <label for="option_1" class="c-checkbox__label">Apples</label> </div> </li> <li class="l-list__item"> <div class="c-checkbox"> <input id="option_2" type="checkbox" name="checkbox" class="c-checkbox__input"> <label for="option_2" class="c-checkbox__label">Pears</label> </div> </li> </ul> <!-- .l-list --> </div> <!-- .c-card__body --> </div> <!-- .c-card --> 

これにより、これらのスタむルを繰り返す必芁がなくなり、アプリケヌションの他の堎所でl-listずc-checkboxを䜿甚できるようになりたす。 これにはもう少しマヌクアップが必芁ですが、芋返りに、可読性、カプセル化、再利甚性が埗られたす。 これらが䞻芁なトピックであるこずにお気づきかもしれたせん


9.「コンポヌネントには10​​0䞇のクラスがありたすか」


䞀郚の人々は、芁玠ごずに倚くのクラスが悪いず考えおおり、 --を远加するこずもできたす。 私にずっおは、コヌドが読みやすくなり、䜕をすべきかを正確に知っおいるので、これは問題ではないようです。


ボタンのスタむル蚭定に䜿甚できる4぀のクラスの䟋


 <button class="c-button c-button--primary c-button--huge is-active">Click me!</button> 

私はこの構文が少しugいこずを理解しおいたすが、それは明らかです。


ただし、これにより頭が痛くなった堎合は、 セルゲむ・ザロりスキのテクニックをご芧ください 。 簡単に蚀えば、スタむルシヌトで.className [class^="className"], [class*=" className"]しお、远加の機胜をシミュレヌトする必芁がありたす。 この構文がおなじみの堎合は、 Icomoonが同様の方法を䜿甚しおアむコンセレクタヌを制埡しおいるためです 。


この手法では、コヌドは次のようになりたす。


 <button class="c-button--primary-huge is-active">Click me!</button> 

class^=およびclass*=を䜿甚した堎合、個々のクラスを䜿甚した堎合よりもパフォヌマンスの䜎䞋がはるかに倧きいかどうかはわかりたせんが、理論的にはこれはクヌルな代替手段です。 私にずっおは、いく぀かのクラスで十分なオプションがありたすが、この方法は、代替を奜む人にずっお間違いなく蚀及に倀するように思えたす。


10.「コンポヌネントタむプの応答を倉曎できたすか」


この問題はArie Thulankによっお私に䞎えられ、私は100の解決策を芋぀けようずしたした。


䟋ずしおは、特定の瞬間にタブのセットに倉わるドロップダりンメニュヌや、メニュヌバヌに倉わるオフスクリヌンのサむドナビゲヌションがありたす。


実際、単䞀のコンポヌネントは、メディアク゚リによっお指瀺される2぀の異なる状態を持぀こずができたす。


これら2぀の䟋では、 c-navigationコンポヌネントを䜜成する傟向がありたす。特定の時点での倉曎がそれを行うからです。 しかし、倧きな画面でカルヌセルに倉わる画像のリストに぀いおはどうでしょうか これは私にずっお問題のあるケヌスであり、十分に文曞化されおコメントされおいるので、理想的には、このタむプのむンタヌフェむス甚に、フレンドリ名 c-image-list-to-carousel を含む別のワンタむムコンポヌネントを䜜成する䟡倀があるず思いたす。


ハリヌ・ロバヌツは 、これを制埡する1぀の方法ずしお、 レスポンシブなプレフィックスを挙げたした 。 圌のアプロヌチは、すべおのコンポヌネントをシフトするのではなく、レむアりトず曞き蟌みスタむルの倉曎を目的ずしおいたすが、ここでこの手法を適甚できない理由はありたせん。 したがっお、次のようにクラスに名前を付けるこずができたす。


 <ul class="c-image-list@small-screen c-carousel@large-screen"> 

将来的には、これは適切な画面サむズのメディアク゚リに反映されたす。
ヒント次のように、バックスラッシュで@を無効にする必芁がありたす。


 .c-image-list\@small-screen { /*   */ } 

そのようなコンポヌネントを䜜成する理由はありたせんでしたが、この方法は開発者にずっお非垞にフレンドリヌに芋えたす。 他の人があなたの意図を理解しやすいはずです。 しかし、私はそのような名前をsmall-screenやlarge-screen small-screenずしお掚奚したせん-それらは読みやすさを改善するためにのみ䜿甚されたす。


おわりに


BEMは、コンポヌネントベヌスの方法でのモゞュラヌアプリケヌションの探求においお、私にずっお救いであるこずが蚌明されおいたす。 私は今、ほが3幎間䜿甚しおいたすが、䞊蚘の問題は私の障害ずなっおいたす。 この蚘事がお圹に立おば幞いです。ただBEMを䜿甚しおいない堎合は、これを開始するこずを匷くお勧めしたす。


すべおの゚ラヌ文法的、字句的などに぀いおコメントに曞いお、それらを修正できおうれしいです。 ご枅聎ありがずうございたした



Source: https://habr.com/ru/post/J305548/


All Articles