چگونه استایل استاندارد بنویسیم (BEM)

استایل استاندارد بنویسیممتد 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=&quotbtn btn--big btn--orange&quot href=&quothttps://www.linkedin.com/in/ehsan-samavati/&quot> <span class=&quotbtn__price&quot>$9.99</span> <span class=&quotbtn__text&quot>Subscribe</span> </a>اگر برنامه نویس دیگه ای این HTML رو نوشته باشه و ما با CSS آشنایی نداشته باشیم، احتمالا هنوز میتونیم ایده های خوبی در رابطه با اینکه کدوم کلاس مسئول چه چیزی هست و کلاس ها چجوری به هم ربط دارن داشته باشیم. بدون نوشتن CSS خیلی زیاد، برنامه نویسا توانایی اینو خواهند داشت که با تغییر خیلی جزئی در HTML ترکیب های مختلفی از دکمه هارو بسازن: https://codepen.io/Ehsan__samavati/pen/yLVWYOK اولش ممکنه فکر کنیم این مدل نوشتن کد خیلی کندتر از اینه که برای هر نوع دکمه، یه کلاس جدید تعریف کنیم. اما به چند دلیل خواهیم گفت که این شکلی نیست.چرا باید به BEM فکر کنیم؟اگر بخوایم به یه کامپوننت، استایل جدیدی بدیم، میتونیم به سادگی ببینیم کدوم modifier ها و element ها توی کامپوننت استفاده شدن. حتی ممکنه خیلی سرع متوجه این بشیم که لازم نیست هیچ CSS جدیدی بنویسیم. چون احتمالا از قبل اون modifier که ما بهش احتیاج داریم نوشته شده هست و وجود داره.اگر داریم به جای اینکه CSS ها رو بخونیم، HTML ها رو میخونیم. باید بتونیم خیلی سریع بفهمیم موضوع چیه و کدوم کلاس ها به همدیگه مرتبط اند(توی مثال قبلی میتونیم ببینیم .btn__price به .btn وابستگی داره حتی بدون اینکه بدونیم هر کدومشون دقیقا دارن چه استایلی میدن).طراحان و برنامه نویسا میتونن به طور ثابت کامپوننت ها رو نام گذاری کنن که ارتباطات توی تیم راحت تر انجام بشه. به عبارت دیگه، BEM به همه ی اعضای تیم دانشی در ارتباط با نحوه ی نوشتن کد میده که همه میتونن خیلی سریع از موضوع سر در بیارن.هری رابرت یه مزیت کلیدی استفاده از روش هایی مثل BEM رو زمانی گفته بود که در رابطه با بهبود اعتماد به نفس توسعه دهنده ها مینوشت:این دلیل اصلی این هست که ما به کدبیس های خیلی عظیم پایان دادیم، که پر از CSS های ناشناخته و یه ارث رسیده اند که حتی جرات دست زدن بهشون رو نداریم. ما اعتماد به نفس کافی برای کار کردن و اصلاح استایل های موجود را نداریم چون از عواقب عملیاتی تغییر دادن CSS های کلی میترسیم. تقریبا تمام مشکلات CSS که در پروژه همواره در حال بزرگ شدن هست، به اعتماد به نفس(یا نداشتن اعتماد به نفس) ربط دارد. افراد دیگه نمیدونن چه چیزایی، چه کارایی میکنن. افراد میترسن تغییر ایجاد کنن چون نمیدونن اثراتش تا کجا خواهد بود.به همین شکل، فیلیپ وارتون بیان میکند که این چنین مشکلات، اگر برنامه نویس ها به اندازه کافی به اصول BEM پایبند باشند، برطرف خواهند شد:در حالیکه کدهای 100% قابل پیش بینی احتمالا هیچگاه امکان پذیر نخواهد بود، این مهم است که داد و ستد(trade-off) ایجاد شده به علت انتخاب یک استاندارد را در نظر بگیرید. اگر شما از BEM پیروی کنید، میتوانید در آینده CSS های خودتون را اصلاح کنید و یا به آن اضافه کنید، بدون ترس از اینکه ممکنه چه عواقب اشتباهی داشته باشد.بنابراین اگر برنامه نویسان بتونن با اعتماد به نفس بیشتری روی پروژه کار کنند، بعدش میتونن با اطمینان، تصمیمات هوشمندانه تری درباره اینکه چگونه کامپوننت های ظاهری استفاده بشن، بگیرند. این متدولوژی احتمالا درمان قطعی و کامل برای همه ی این مشکلات نیست، اما قطعا به برنامه نویسان یک استاندارد ارائه میکنه که بتونن کد های بهتر و با قابلیت نگهداری بیشتری در آینده بنویسند.یه موضوع هوشمندانه دیگه در ارتباط با BEM این هست که همه چیز کلاس هست، و هیچ چیزی تو در تو نیست. این باعث میشه که CSS Specificity خیلی کم و مسطح بشه، که ایده ی خوبیه. این یعنی قرار نیست با خودتون سر specificity بجنگید.خب، حالا بریم چندتا مشکل در ارتباط با BEM ببینیم...مشکلات استفاده از 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=&quotbtn&quot href=&quot#&quot> <div class=&quotnav__listItem&quot>Item one</div> <div class=&quotnav__listItem&quot>Item two</div> </a>چیزی که اینجا اتفاق افتاده اینه که یه برنامه نویس، element های مورد نیازش رو در یک block کاملا غیرمرتبط استفاده کرده است. این کار باعث گیج شدن میشه و به هر قیمتی نباید این کار رو انجام داد. بنابراین میتونیم مشکلات رو به صورت زیر خلاصه کنیم:هیچ وقت modifier ها رو در یک block غیر مرتبط بازنویسی نکنید.از درست کردن parent element های غیر ضروری، وقتی child ها میتونن خودشون به خوبی استفاده بشن جلوگیری کنیم.منبع: https://css-tricks.com/bem-101/