متد Block، Element، Modifier (که معمولاً بهش BEM میگن) یه نامگذاری معروف برای کلاسها در HTML و CSS هست. هدفش کمک به برنامه نویس ها برای درک بهتر رابطه بین HTML و CSS در یک پروژه داده شده
هستش که توسط تیم Yandex معرفی شده.
اینجا یه مسال از کدی که ممکنه یه برنامه نویس با متد BEM بنویسه رو میبینیم:
/* Block Component */ .btn { } /* Element that depends upon the block */ .btn__price { } /* Modifier that changes the style of the block */ .btn--orange { } .btn--big { }
تو این متدولوژی CSS، یک Block بالاترین سطح انتزاع تو تعریف یک کامپوننت رو مشخص میکنه، مثلا تو یه دکمه:
.btn { }
این بلاک رو به عنوان parent(بلاک در برگیرنده)، در نظر میگیریم. child ها یا element ها را می توان در داخل block قرار داد و این عناصر با دو زیر خط به همراه اسم block نام گذاری میشن. مثل:
.btn__price { }
در آخر، modifier ها میتونن استایل یا تم یه کامپوننت رو عوض کنن بدون اینکه روی یک ماژول دیگه ای که قصد نداریم تغییرش بدیم، اثری بذاره و نام گذاری این موجودات هم با دو خط تیره به همراه اسم block انجام میشه. مثل:
.btn--orange { }
خب با این اوصاف احتمالا HTML مون به این شکل بشه:
<a class="btn btn--big btn--orange" href="https://www.linkedin.com/in/ehsan-samavati/"> <span class="btn__price">$9.99</span> <span class="btn__text">Subscribe</span> </a>
اگر برنامه نویس دیگه ای این HTML رو نوشته باشه و ما با CSS آشنایی نداشته باشیم، احتمالا هنوز میتونیم ایده های خوبی در رابطه با اینکه کدوم کلاس مسئول چه چیزی هست و کلاس ها چجوری به هم ربط دارن داشته باشیم. بدون نوشتن CSS خیلی زیاد، برنامه نویسا توانایی اینو خواهند داشت که با تغییر خیلی جزئی در HTML ترکیب های مختلفی از دکمه هارو بسازن:
اولش ممکنه فکر کنیم این مدل نوشتن کد خیلی کندتر از اینه که برای هر نوع دکمه، یه کلاس جدید تعریف کنیم. اما به چند دلیل خواهیم گفت که این شکلی نیست.
هری رابرت یه مزیت کلیدی استفاده از روش هایی مثل BEM رو زمانی گفته بود که در رابطه با بهبود اعتماد به نفس توسعه دهنده ها مینوشت:
این دلیل اصلی این هست که ما به کدبیس های خیلی عظیم پایان دادیم، که پر از CSS های ناشناخته و یه ارث رسیده اند که حتی جرات دست زدن بهشون رو نداریم. ما اعتماد به نفس کافی برای کار کردن و اصلاح استایل های موجود را نداریم چون از عواقب عملیاتی تغییر دادن CSS های کلی میترسیم. تقریبا تمام مشکلات CSS که در پروژه همواره در حال بزرگ شدن هست، به اعتماد به نفس(یا نداشتن اعتماد به نفس) ربط دارد. افراد دیگه نمیدونن چه چیزایی، چه کارایی میکنن. افراد میترسن تغییر ایجاد کنن چون نمیدونن اثراتش تا کجا خواهد بود.
به همین شکل، فیلیپ وارتون بیان میکند که این چنین مشکلات، اگر برنامه نویس ها به اندازه کافی به اصول BEM پایبند باشند، برطرف خواهند شد:
در حالیکه کدهای 100% قابل پیش بینی احتمالا هیچگاه امکان پذیر نخواهد بود، این مهم است که داد و ستد(trade-off) ایجاد شده به علت انتخاب یک استاندارد را در نظر بگیرید. اگر شما از BEM پیروی کنید، میتوانید در آینده CSS های خودتون را اصلاح کنید و یا به آن اضافه کنید، بدون ترس از اینکه ممکنه چه عواقب اشتباهی داشته باشد.
بنابراین اگر برنامه نویسان بتونن با اعتماد به نفس بیشتری روی پروژه کار کنند، بعدش میتونن با اطمینان، تصمیمات هوشمندانه تری درباره اینکه چگونه کامپوننت های ظاهری استفاده بشن، بگیرند. این متدولوژی احتمالا درمان قطعی و کامل برای همه ی این مشکلات نیست، اما قطعا به برنامه نویسان یک استاندارد ارائه میکنه که بتونن کد های بهتر و با قابلیت نگهداری بیشتری در آینده بنویسند.
یه موضوع هوشمندانه دیگه در ارتباط با BEM این هست که همه چیز کلاس هست، و هیچ چیزی تو در تو نیست. این باعث میشه که CSS Specificity خیلی کم و مسطح بشه، که ایده ی خوبیه. این یعنی قرار نیست با خودتون سر specificity بجنگید.
خب، حالا بریم چندتا مشکل در ارتباط با BEM ببینیم...
قطعا اگر قوانین BEM رو بشکنید و درست ازشون استفاده نکنید، کسی قرار نیست دستتون و بپیچونه. مثلا میتونید CSS این شکلی بنویسید:
.nav .nav__listItem .btn--orange { background-color: green; }
اینطور به نظر میرسه که کد بالا از قوانین BEM داره پیروی میکنه، ولی اون BEM نیست. تکه کد بالا nested selector داره و modifier به درستی شرح نمیده که چه اتفاقی داره میفته. اگر این کار رو بکنیم داریم مسطح بودن specificity رو هم خراب میکنیم.
یه block (مثل nav.) هیچوقت نباید استایل یه block یا modifier دیگه ای رو بازنویسی کنه
(مثل btn--orange.). در غیر اینصورت تقریبا غیرممکن میشه که HTML رو بخونیم و متوجه بشیم که این کامپوننت داره چیکار میکنه؛ اینجوری مطمئن میشیم که توسعه دهنده های دیگه به اعتماد به نفس میتونن به کار خودشون ادامه بدن. اگر تیکه کد زیر رو ببینید چه انتظاری خواهید داشت؟
<a class="btn" href="#"> <div class="nav__listItem">Item one</div> <div class="nav__listItem">Item two</div> </a>
چیزی که اینجا اتفاق افتاده اینه که یه برنامه نویس، element های مورد نیازش رو در یک block کاملا غیرمرتبط استفاده کرده است. این کار باعث گیج شدن میشه و به هر قیمتی نباید این کار رو انجام داد. بنابراین میتونیم مشکلات رو به صورت زیر خلاصه کنیم:
منبع: https://css-tricks.com/bem-101/