مقدمة لمنهجية BEM

نشرت: 2022-03-11

ما هي منهجية BEM؟

عندما تقوم بإنشاء مواقع ويب أصغر ، فإن طريقة تنظيم أنماطك ليست مشكلة كبيرة عادةً. يمكنك إنشاء ملفاتك المعتادة ، وكتابة كل CSS المطلوبة ، وهذا كل شيء. ومع ذلك ، عندما يتعلق الأمر بمشاريع أكبر وأكثر تعقيدًا ، فإن كيفية تنظيم الكود الخاص بك يصبح أمرًا بالغ الأهمية . تعتبر كيفية هيكلة الكود أكثر أهمية إذا كنت تعمل في فريق يتكون من عدة مطورين للواجهة الأمامية والخلفية.

ستعمل منهجية BEM على تحسين إمكانية صيانة الكود بشكل كبير وتسريع عملية التطوير

ستعمل منهجية BEM على تحسين إمكانية صيانة الكود بشكل كبير وتسريع عملية التطوير
سقسقة

اليوم ، هناك الكثير من المنهجيات التي تهدف إلى تقليل كود CSS وجعل كود CSS الخاص بك أكثر قابلية للصيانة. في هذه المقالة ، سأشرح وأقدم بعض الأمثلة على أحدهم: BEM. يرمز BEM إلى B lock E lement M. الفكرة الرئيسية وراءها هي تسريع عملية التطوير ، وتيسير العمل الجماعي للمطورين من خلال ترتيب فئات CSS في وحدات مستقلة. إذا رأيت اسم فئة مثل header__form--search ، فهذا هو BEM قيد التشغيل. نعم ، يمكن تسمية الفصول الدراسية بمدة طويلة جدًا ، لكنها جميعًا مقروءة ومفهومة.

لاحظ أن أفضل ممارسة هي استخدام BEM فقط مع الفئات ، وليس المعرفات لأن الفئات تسمح لك بتكرار الأسماء إذا لزم الأمر وإنشاء بنية تشفير أكثر اتساقًا. أيضًا ، إذا كنت ترغب في تقسيم موقع الويب الخاص بك إلى وحدات نمطية منظمة ، فيجب أن يتكون من نفس البنية: الكتلة والعنصر والمُعدِّل. حيث يمكن أن تحتوي كل كتلة على عناصر متعددة ، ويمكن أن تحتوي كل من الكتلة والعناصر على مُعدِّلات متعددة. ومع ذلك ، لنبدأ أولاً ببنية BEM الأساسية وشرحها بأمثلة.

حاجز

الكتلة تمثل كائنًا في موقع الويب الخاص بك. فكر في الأمر على أنه أجزاء هيكلية أكبر من التعليمات البرمجية الخاصة بك. الكتل الأكثر شيوعًا على كل موقع ويب اليوم هي الرأس والمحتوى والشريط الجانبي والتذييل والبحث. تعد الكتل في BEM دائمًا نقطة بداية لتسلسل فئات CSS الخاصة بك إلى. ألق نظرة على بعض أمثلة الكتلة:

  • محتوى
  • قائمة
  • نموذج البحث
 .content {/* Styles */} .menu {/* Styles */} .search {/* Styles */}

جزء

العنصر هو مكون داخل الكتلة يؤدي وظيفة معينة. يجب أن يكون له معنى فقط في سياق الكتلة الخاصة به:

  • مقال المحتوى
  • عنصر القائمة
  • حقل إدخال البحث
 .content__article {/* Styles */} .menu__item {/* Styles */} .search__input {/* Styles */}

المعدل

المعدل هو كيف نمثل الاختلافات في الكتلة. إذا سبق لك استخدام Bootstrap ، فسيكون أفضل مثال على ذلك هو أحجام الأزرار. أحجام الأزرار هي مجرد اختلافات في حجم الزر نفسه ، مما يجعله المعدل:

  • مقال مميز بالمحتوى
  • ارتباط القائمة
  • حقل بحث مع رمز أو بدونه
 .content__article--featured {/* Styles */} .menu__item--link {/* Styles */} .search__input--icon {/* Styles */}

اصطلاحات التسمية

الغرض الأساسي من منهجية BEM هو جعل أسماء محددات CSS مفيدة وشفافة قدر الإمكان. يتم تعريف نمط BEM الأصلي بهذه الطريقة:

عادةً ما يكون اسم الكتلة كلمة واحدة مثل .header ، ولكن إذا كان لديك تعريف كتلة أطول ، فسيتم تقسيمه بواصلة واحدة - :

 .lang-switcher {/* Styles */}

يبدأ اسم العنصر بشرطة سفلية مزدوجة __ :

 .lang-switcher__flag {/* Styles */}

يبدأ اسم المعدل بشرطة سفلية واحدة _ :

 .lang-switcher__flag_basic {/* Styles */}

لا توجد سوى قاعدة واحدة بالغة الأهمية في منهجية BEM - لا يمكن استخدام معدل خارج سياق مالكه.

مثال:

 .btn_big {/* Styles */}

يمكنك استخدام btn_big فقط إذا تم تعريف العنوان أيضًا.

مثالا سيئا:

 <div class=”btn_big”>...</div>

مثال جيد:

 <div class=”btn btn_big”>...</div>

بجانب أنماط BEM الأصلية ، هناك مخططات تسمية بديلة مثل أنماط Harry Roberts و CamelCase.

مثال على أسلوب هاري روبرتس:

 .block-name__element-name--modifier-name {/* Styles */}

مثال على نمط حالة الجمل:

 .BlockName__ElementName_ModifierName {/* Styles */}

هناك القليل من الآخرين أيضًا ، لكن هذين هما الأكثر شيوعًا. أنا شخصياً معجب باتفاقية التسمية التي اقترحها هاريس روبرتس ، والتي لها القواعد التالية:

  • الأسماء مكتوبة بحروف صغيرة
  • يتم فصل الكلمات داخل أسماء كيانات BEM بواصلة -
  • يتم فصل اسم العنصر عن اسم الكتلة بشرطة سفلية مزدوجة __
  • يتم تحديد المعدلات المنطقية بشرطة مزدوجة --
  • لا يتم استخدام معدِّلات نوع القيمة الرئيسية

السبب في كون اصطلاح التسمية هذا أفضل بكثير من غيره هو أنه يمكنك بسهولة تمييز عنصر التعديل عن العناصر الأخرى. في اصطلاحات التسمية الأصلية ، يمكن تعريف المُعدِّل على النحو التالي:

 .block__element_modifier {/* Styles */}

ولكن كما ترى ، لا يوجد فرق كبير بين الشرطة السفلية المفردة والمزدوجة. من ناحية أخرى ، توفر الواصلة المزدوجة فصلًا نظيفًا ، ويمكنك رؤية المعدل على الفور:

 .block__element--modifier {/* Styles */}

مثال BEM بتنسيقات مختلفة

يرجى ملاحظة أنه بالإضافة إلى CSS ، يعد BEM مفيدًا جدًا أيضًا في تنظيم JSON أو XML أو ملفات الشجرة أو أي تنسيق يدعم التداخل. فكر في منهجية BEM كطريقة جيدة لبناء واجهة المستخدم الخاصة بك.

منظم HTML بتنسيق BEM

لنفكر في HTML التالي ، المنظم بتنسيق BEM:

 <header class=”header”> <img class=”header__logo”> <form class=”header__search-from”> <input class=”header__search-from__input” type=”input”> <button class=”header__search-from__button” type=”button”> </form> <div class=”header__lang-switcher”></div> </header>

يمكن تحقيق نفس الشيء باستخدام تنسيق JSON و XML.

XML:

 <block:header> <block:logo/> <block:search-from> <block:input/> <block:button/> </block> <block:lang-switcher/> </block>

جسون:

 { block: 'header', content: [ { block: 'logo' }, { block: 'search-form', content: [ { block: 'input' }, { block: 'button' } ] }, { block: 'lang-switcher' } ] }

تنظيم نظام الملفات لمشروع BEM

في BEM ، من الأهمية بمكان تنظيم ملفاتك بطريقة صحيحة. لا يوفر لك BEM تنظيمًا رائعًا لفصول CSS ويجعلها مفهومة تمامًا فحسب ، بل يمنحك أيضًا بنية ملف قابلة للصيانة. لنأخذ مثالاً على مشروع ، باستخدام تقنية تنظيم ملفات BEM مع ملفات SASS:

 blocks/ input/ __box/ --big/ input__box--big.scss input__box.scss button/ --big/ button--big.scss

كما ترى أعلاه ، بمجرد رؤية بنية المجلد الفرعي داخل المجلد الرئيسي ، يكون كل شيء واضحًا ومنظمًا. بهذه الطريقة ، لا فرق بين من يعمل بعدك أو إذا كنت تعمل خلف شخص ما ، لأنه من السهل للغاية اتباع نفس النمط.

تقسيم مشروع BEM إلى منصات

إلى جانب مجرد تنظيم ملفاتك باستخدام تقنيات منهجية BEM ، يمكنك أيضًا الخوض في أشياء أكثر تحديدًا. على سبيل المثال ، إذا كنت تقوم ببناء مشروع ويب سيكون مستجيبًا تمامًا ، وحدد العميل أن بعض الكتل على الهاتف المحمول مختلفة تمامًا عن تلك الموجودة على أجهزة سطح المكتب ، فمن الأفضل تقسيم بنية مجلد BEM إلى منصات. مثال على تنظيم الأزرار على منصات مختلفة:

 common.blocks/ button/ button.scss desktop.blocks/ button/ buttons.scss mobile.blocks/ button/ button.scss

لاحظ أن هذا مجرد مثال إذا كنت تريد تنظيم مشروعك بالكامل باستخدام منهجية BEM. شجرة الملفات مع بنية BEM ليست إلزامية لاستخدام BEM بشكل صحيح ، يمكنك استخدام BEM فقط في بعض أجزاء المشروع. حتى الآن لم أستخدم هذه المنظمة الصارمة لهيكل ملفات BEM حيث يتم إنشاء ملف لكل عنصر ومُعدِّل. بدلاً من ذلك ، أقوم فقط بإنشاء بنية ملف للكتل التي لديها إعلان عن عناصرها ومعدلاتها.

تنظيم شجرة لمشروع BEM

BEM في الممارسة

نظرًا لأنك الآن على دراية باتفاقيات التسمية ، فسوف أعرض منهجية BEM في الممارسة العملية. لنفترض أن لدينا كود HTML هذا قيد التنفيذ:

 <a class=”btn btn--big btn--primary-color” href=”#” title=”Title”> <span class=”btn__price”>$3.99</span> <span class=”btn__text”>Product</span> </a>

مع تطبيق ترميز CSS التالي:

 .btn__price {/* Styles */} .btn__text {/* Styles */} .btn--big {/* Styles */} .btn--primary-color {/* Styles */}

الآن ، لا تكن مضللا. في الأمثلة التي لدينا حتى الآن ، كان لدينا دائمًا كتلة ، عنصر ، ومُعدِّل ، وهو الأمر الذي لا يجب أن يكون عليه الحال دائمًا.

على سبيل المثال ، لنفترض أن لدينا كتلة باسم الشخص . الشخص لديه أرجل ويد ، ويمكن أن يكون أيضًا أنثى أو ذكرًا. إذا أردنا تعريف الرجل باليد اليمنى سيبدو كما يلي:

 .person--male__hand--right {/* Styles */}

الآن يمكنك أن ترى المعنى الحقيقي لـ BEM. لقد حددنا الشخص الذي يعدل هو الجنس. نظرًا لأنه لا يهم إذا كان الشخص ذكرًا أو أنثى ، فإن له يدًا ، واليد عنصر. ومرة أخرى ، يمكن أن يكون لكل شخص يده اليمنى أو اليسرى والتي تعد مرة أخرى معدلًا.

في حالة أخرى ، إذا أردنا تعريف الشخص العام بيد واحدة ، فسنقوم بذلك على النحو التالي:

 .person__hand {/* Styles */}

كما تلاحظ ، بمجرد أن تشعر بالراحة مع BEM ، من السهل جدًا هيكلة بنية CSS و HTML الخاصة بك معها.

استخدام BEM مع معالجات CSS الأولية

أنا شخصياً لا أستطيع أن أتخيل بدء أي مشروع جديد دون استخدام أحد معالجات CSS الأولية. كما تعلمون جميعًا ، تعتبر المعالجات المسبقة شيئًا رائعًا وتوفر لنا الكثير من الفوائد ، والأهم من ذلك أنها تتطابق تمامًا مع منهجية BEM.

الموضوعات ذات الصلة: احتضان Sass: لماذا يجب عليك التوقف عن استخدام Vanilla CSS

في المثال التالي ، يمكنك رؤية المثال الأكثر شيوعًا لـ BEM ، بالاقتران مع SASS:

 .person { &__hand {/* Styles */} &__leg {/* Styles */} &--male { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } &--female { /* Styles */ &__hand { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } &__leg { /* Styles */ &--left {/* Styles */} &--right {/* Styles */} } } }

سيتم تجميع كود SASS في CSS التالية:

 .person__hand {/* Styles */} .person__leg {/* Styles */} .person--male {/* Styles */} .person--male__hand {/* Styles */} .person--male__hand--left {/* Styles */} .person--male__hand--right {/* Styles */} .person--male__leg {/* Styles */} .person--male__leg--left {/* Styles */} .person--male__leg--right {/* Styles */} .person--female {/* Styles */} .person--female__hand {/* Styles */} .person--female__hand--left {/* Styles */} .person--female__hand--right {/* Styles */} .person--female__leg {/* Styles */} .person--female__leg--left {/* Styles */} .person--female__leg--right {/* Styles */}

إذا كنت تريد الذهاب إلى أبعد من ذلك ، فيمكنك استخدام مزيج SASS مفيد لـ BEM:

 /// Block Element /// @param {String} $element - Element's name @mixin element($element) { &__#{$element} { @content; } } /// Block Modifier /// @param {String} $modifier - Modifier's name @mixin modifier($modifier) { &--#{$modifier} { @content; } }

ويمكنك استخدامه على النحو التالي:

 .person { @include element('hand') {/* Person hand */} @include element('leg') {/* Person leg */} @include modifier('male') { /* Person male */ @include element('hand') { /* Person male hand */ @include modifier('left') { /* Person male left hand */ } @include modifier('right') { /* Person male right hand */ } } } }

والذي سينتج مخرجات CSS التالية:

 .person__hand { /* Person hand */ } .person__leg { /* Person leg */ } .person--male { /* Person male */ } .person--male__hand { /* Person male hand */ } .person--male__hand--left { /* Person male left hand */ } .person--male__hand--right { /* Person male right hand */ }

أعلم أنه على الأرجح لن يكون لديك حالة استخدام لفترة طويلة ، ولكن هذا مثال رائع على كيفية استخدام BEM ولماذا هو قوي جدًا ، في كل من المشاريع الصغيرة والكبيرة.

بدء مشروع BEM الخاص بك

كما هو موضح في وثائق BEM الرسمية ، فإن أسهل طريقة لبدء امتلاك مشروع BEM جديد هو استخدام مستودع GIT الحالي. ببساطة استخدم أمر Git clone:

 $ git clone https://github.com/bem/project-stub.git

بعد ذلك ، انتقل إلى دليل تم إنشاؤه حديثًا وقم بتثبيت جميع التبعيات:

 $ npm install

سيتم تثبيت جميع التبعيات المطلوبة:

تبعيات BEM

بناء المشروع باستخدام ENB:

 $ node_modules/.bin/enb make

قم بتشغيل وضع الخادم للتطوير:

 $ node_modules/.bin/enb server

نتيجة لذلك ، تظهر الرسالة التالية:

 Server started at 0.0.0.0:8080

الآن ، هذا يعني أن الخادم يعمل. يمكنك الآن التحقق من النتائج على هذا العنوان:

 http://localhost:8080/desktop.bundles/index/index.html

كما ترى ، هناك الكثير من العناصر التي تم إنشاؤها بالفعل والتي تم تعريفها داخل ملف bemjson الموجود هنا:

 project-stub/desktop.bundles/index/index.bemjson.js

يمكنك رؤية واستكشاف الهيكل الحالي للملف الذي يقوم بإنشاء كل تلك HTML ، والتي تراها في ملف localhost index.html . سنقوم بتعديل هذا الملف للحصول على مشروع BEM "الشخص" الذي شرحناه في فصل سابق. يمكنك إزالة (أو التعليق) الكود بالكامل من ملف index.bemjson.js ، واستبداله بهذا:

 module.exports = { block: 'page', title: 'Person BEM', favicon : '/favicon.ico', head : [ { elem : 'meta', attrs : { name : 'description', content : '' } }, { elem : 'meta', attrs : { name : 'viewport', content : 'width=device-width, initial-scale=1' } }, { elem : 'css', url : 'index.min.css' } ], scripts: [{ elem : 'js', url : 'index.min.js' }], content: [ { block: 'person', content: [ { elem: 'male', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Male person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Male person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Male person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Male person hand -- right' } ] }, { elem: 'female', content: [ { elem: 'leg', mods: {side: 'left'}, content: 'Female person leg -- left' }, { elem: 'leg', mods: {side: 'right'}, content: 'Female person leg -- right' }, { elem: 'hand', mods: {side: 'left'}, content: 'Female person hand -- left' }, { elem: 'hand', mods: {side: 'right'}, content: 'Female person hand -- right' } ] }, ] } ] };

الآن ، سيتم إنشاء HTML التالي:

 <div class="person"> <div class="person__male"> <div class="person__leg person__leg_side_left"> Male person leg -- left </div> <div class="person__leg person__leg_side_right"> Male person leg -- right </div> <div class="person__hand person__hand_side_left"> Male person hand -- left </div> <div class="person__hand person__hand_side_right"> Male person hand -- right </div> </div> <div class="person__female"> <div class="person__leg person__leg_side_left"> Female person leg -- left </div> <div class="person__leg person__leg_side_right"> Female person leg -- right </div> <div class="person__hand person__hand_side_left"> Female person hand -- left </div> <div class="person__hand person__hand_side_right"> Female person hand -- right </div> </div> </div>

كما ترون من الكود أعلاه ، تم استخدام مخطط تشفير BEM الافتراضي في هذا السيناريو لأننا نستخدم فقط الإعدادات الافتراضية التي قدمها لنا BEM. هناك الكثير من الأوامر والخيارات التي يمكنك استكشافها واستخدامها ، مثل إنشاء صفحات جديدة أو كتل أو تعديل BEM HTML. لن أتعمق في هذا الأمر ، ويمكن العثور عليه جميعًا في وثائق BEM الرسمية.

مزايا ومخاوف BEM

المزايا والاهتمامات

مزايا

  • BEM ممتاز للصيانة. كم مرة اضطررت إلى العمل بعد شخص ما في مشروع كبير الحجم وكنت خائفًا جدًا من تغيير أي شيء دون انهيار شيء غير معروف؟ عند استخدام BEM ، فأنت تعرف الغرض الدقيق للعنصر وفي أي كتلة قد يظهر.
  • أسماء الفئات منطقية وبديهية ، ويعرف كل عضو في الفريق ما يفعله هذا العنصر على موقع الويب. يمنح BEM كل شخص في مشروع بناء جملة تعريفي يمكنهم مشاركته حتى يكونوا في نفس الصفحة.
  • يزيل BEM محددات CSS المتداخلة. كل عنصر HTML له فئة CSS الخاصة به ، وباسمه تعرف الغرض منه. مُحدِّد واحد للحكم عليهم جميعًا .

المخاوف والأخطاء الشائعة

  • لا تتعمق في التعشيش. يجب أن تكون القاعدة الرئيسية هي عدم استخدام أكثر من مستويين من الوالدين والطفل.
  • كن حذرًا من أين تبدأ نطاق الكتلة الخاص بك. الخطأ الشائع هنا هو عندما يستخدم المطور الكتلة ، لكنه لا يدرك أنه في وقت لاحق من التطوير ، سيكون لتلك الكتلة نفسها الكتلة الرئيسية الرئيسية التي من المحتمل أن تكسر القاعدة مع التداخل.
  • تجنب SASSextend. للاقتباس من هاري روبرتس في هذا الصدد:

يمكنك إنشاء عدد أكبر من التركيبات في طريقة العرض من خلال عدم "ربط" الفئات معًا في Sass. يحتوي HTML على مسار ورقي أفضل بكثير حيث يمكنك رؤية كل فصل يعمل على جزء من DOM. يظل CSS الخاص بك أقل نحافة حيث لا يتعين عليك إنشاء فئات عناصر نائبة جديدة (أو فئات البيان التي تجمعهم) في كل مرة تريد إنشاء جزء جديد من واجهة المستخدم.

خاتمة

عندما رأيت مخطط ترميز BEM لأول مرة ، كان أول ما فكرت به هو:

هذه الفصول الدراسية طويلة جدًا للكتابة والقراءة.

لكن بعد تجربته ، لا يمكنني الآن تخيل بدء مشروع جديد دون استخدامه. بالنسبة لي ، حسّن BEM بشكل كبير قابلية صيانة الكود الخاص بي ، ويمكنني بالتأكيد أن أقول إن كل مطور سيتم "طرحه" في المشروع القائم على BEM سوف يلحق بسرعة بهيكل الكود بأكمله.

على الرغم من كل هذا ، هناك الكثير من النقاش على الشبكات الاجتماعية حول BEM. يقول البعض إن BEM ليس جيدًا ، متسائلين لماذا يجب أن يكتبوا مثل هذه الفئات الطويلة من الأسماء بدلاً من مجرد استخدام عناصر HTML الافتراضية المتداخلة. حسنًا ، لا أحد يقول أنه يجب أن تعجبك BEM ، ولكن الحقيقة هي أن غالبية مطوري الواجهة الأمامية يتبنونها ويجدونها مفيدة للغاية.

الموضوعات ذات الصلة: وظف أفضل 3٪ من مطوري الواجهة الأمامية المستقلين.