رفع مشکل نام های طولانی در BEM

BEM یکی از استانداردهای نام گذاری کلاس ها در سی اس اس هست. ممکنه براتون سوال باشه که مگه سی اس اس هم استاندارد نام گذاری نیاز داره؟ ۴تا دونه کلاس که ارزش این حرفا رو نداره! :دی اما باید بگم سی اس اس خیلی قلق داره و استفاده صحیح ازش در پروژه های نسبتا بزرگ بسیار سخته.

برای بهتر متوجه شدن این موضوع کافیه به مطلبم در مورد سی اس اس ماژولار برای پروژه های بزرگ سری بزنین.

مشکل اصلا کجاس؟

در استاندارد BEM، گفته شده که برای نام گذاری اجزا و المنت های یک بلاک، از علامت __ استفاده میشه. یه فرم تماس رو در نظر بگیرید که مثل شکل زیر باشه:

فرم تماس

توی عکس مشخصه که برای طراحی این فرم بر اساس BEM باید نام گذاری های زیر انجام بشه:

  • بلاک: کل فرم: .contactform
  • المنت: هر سطر از فرم: .contactform__row

حالا برای نام گذاری هر کدوم از اعضای درون یه سطر باید چیکار کرد؟ میتونیم یه اسم طبق استاندارد براش بزاریم مثلا .contactform__row__icon , ‍‍.contactform__row__userinput توی مطلبم در مورد سی اس اس ماژولار برای پروژه های بزرگ گفتم که اگر در نامگذاری های BEM به حالتی رسیدین که دارین بیشتر از یک بار از __ استفاده میکنین مثلا حالت .contactform__row__icon بدنید که دارید اشتباه میکنید.

نامگذاری اعضای بلاک نباید زنجیره وار به هم وصل باشه

راه حل

برای حل این مشکل دو راه وجود داره:

  1. اسم های المنت های درونی رو به جای والد اول به والد اصلی بلاک ضمیمه کنین
  2. زمانی که این مشکل به وجود میاد، یه بلاک درونی بسازید و المنت رو توی این بلاک جدید قرار بدین

وصل کردن المنت های درونی به والد اصلی

درسته که BEM به ما دیکته میکنه که کلاس المنت ها باید از فرمت block__element پیروی کنه ، اما محدودیتی وجود نداره که این بلاک توی کدوم رده از والد های اون المنت باشه. مثال زیر رو ببینید:

فرض کنید میخوایم برای یه بلاگ استایل بزنیم و هر مطلب اون بلاگ از سه بخش header, body, footer تشکیل شده باشه. مارک آپ این مطلب در اچ تی ام ال این شکلی خواهد شد:

<article class="article">
  <header class="article__header">
    <h1 class="article__title"></h1>
  </header>
</article>

ببینید به جای اینکه کلاس عنوان هدر رو بزاریم article__header__title، چون این اسم نامعتبره، عنوان رو به جای اتصال به والد اولش که article__header هست، به والد اصلی بلاک یعنی article وصل میکنیم. هیج تداخلی بین این نوع نامگذاری و قوانین BEM وجود نداره و معنی نامربوطی هم نسبت به مارک آپ توی ذهن ایجاد نمیکنه. پس کاملا روش معتبریه.

ولی شرایطی هم هست که این روش جواب نمیده و باید بریم سراغ راه حل دوم. مثلا بلاک کامنت های همون بلاگی که مثالش رو دیدیم. فرض کنید سیستم کامنتینگ این بلاگ به صورت زیر باشه:

<section class="comments">
  <h2 class="comments__title"></h2>
  <article class="comments__comment">
    <h3 class="comments__comment-title"></h3>
  </article>
  <article class="comments__comment">
    <h3 class="comments__comment-title"></h3>
  </article>
  <!-- ... -->
</section>

اگر دقت کنین کلاس comments__comment-title یه کلاس نامعتبره و مثلا باید براش راه حلی پیدا کنیم. توی این شرایط چون کل بلاک کامنتها یه عنوان داره که کلاسش هم شده comments__title، دیگه نمیتونیم عنوان هر کامنت رو هم به والد بالاتر ارجاع بدیم. چون کلاسش با عنوان کل بلاک یکسان میشه درحالیکه دو المنت متفاوت هستن!

توی این شرایط میریم سراغ راه حل دوم:

ساخت بلاک های درونی جدید

توی این راه میایم هر کامنت رو هم یه بلاک درنظر میگیریم و بهش کلاس .comment میدیم. دقت کنید توی این شرایط دیگه هر کامنت وابسته با والدش یعنی بلاک .comments درنظر گرفته نمیشه و استایل هاش به صورت مستقل بهش داده میشه.

حالا نامگذاری عنوان هر کامنت کار ساده ایه. کلاس هرعنوان میشه ‍‍.comment__title به همین سادگی یه همین خوشمزگی :دی

با اینکه بلاک های .comments و .comment مستقل ازهم هستن،‌ اما استایل هاشون رو در یک فایل مثل _comments.scss ذخیره کنید تا محتوای استایل کامنت ها رو در یک نقطه متمرکز کرده باشید. اصل Single source of truth

جمع بندی

پیروی از قوانین خیلی خوبه اما مدیریت شرایطی که به دلیل این پیروی کار رو براتون سخت میکنن مهمه. یکی ازین شرایط در استفاده از BEM همین نامگذاری های زنجیره ای بود که راه حل هاش رو باهم بررسی کردیم.

یادتون نره اگر کنجکاوین در مورد سی اس اس ماژولار بیشتر بدونین مطلب من در این مورد رو حتما مطالعه کنین. مطلبم در مورد سی اس اس ماژولار برای پروژه های بزرگ

امیدوارم از خوندن این مطلب لذت برده باشید.