سی اس اس ماژولار برای پروژه های بزرگ

نوشتن سی اس اس خیلی ساده اس. به سادگی تغییر رنگ و سایز فونت متن. تقریبا هرکسی میتونه سی اس اس بنویسه و از اون تقریبا همه، حداقل ۸۰درصد به هرنحوی هست کارشونو باهاش تموم میکنن و راضی هم هستن. اما نوشتن و مدیریت کردن سی اس اس به صورت استاندارد و درست و به دور از درد و خونریزی!! یکی از سخت ترین تسک های توسعه فرانت انده.

از اونجایی که توی سی اس اس عملا ارور هندلینگی نداریم و استاد سی اس اس خیلی سایلنت از کنار ارورها و کانفلیکت ها میگذرن، توی هر پروژه ممکنه ساعت ها زمان بزاریم تا بتونیم متوجه بشیم که چرا سایز فونت این دکمه شده ۱۳.۷۲ پیکسل!!!

به دلایلی که گفتم و به خاطر خدا (For the sake of GOD) پیروی از یه الگوی استاندارد برای پیاده سازی استایل های پروژه و به همین نسبت پیاده سازی ساختار مارک آپ اچ تی ام ال،‌ خیلی خیلی مهمه. با پیروی از یه استاندارد خوب توی کارهای گروهی هم تسک ها ساده تر پیش میرن و هم مشکلاتی از قبیل عدم هماهنگی و طرز تفکر متفاوت بین اعضای تیم پیش نمیاد. مشکلاتی که حتی توی یه پروژه یه نفره که خودتون هم توسعه دهنده اش هستید گریبان گیرتون میشه چه برسه به یه پروژه که بالغ بر ۸۰ توسعه دهنده میتونن براش استایل بزنن و سی اس اس بنویسن.

خوشبختانه مثل سایر مشکلات در دنیای نرم افزار، پیش از ما دیگران هم به این مشکل برخوردن و براش اتفاقا راه حل های خیلی خوبی هم پیشنهاد دادن. استانداردهایی از قبیل BEM, OOCSS, SMACSS, Atomic Design.

خب برای حل این مشکل چیکار کنم؟

خب فرض میکنیم که تصمیم گرفتیم برای پروژه بعدی از این استانداردها پیروی کنیم. قبلا درگیر این بودیم که نمیدونیم باید چیکار کنیم اما حالا درگیر این شدیم که اصلا از کدوم استاندارد باید پیروی کرد؟؟ از همه استانداردها پیروی کنم؟ فقط از یکیشون پیروی کنم؟ خودم بیام یه استاندارد برای خودم پیدا کنم؟ این استانداردها رو ترکیب کنم؟

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

پارامترهای یک معماری استاندارد سی اس اسی

به نظرم ۴ پارامتر در یک استاندارد صحیح از قرارداد سی اس اسی مهم ان و باید رعایت بشن. یه استاندارد صحیح و درسته تنها زمانیکه بعد از استفاده ازون در پروژه اتون:

  1. با یه نگاه بتونم بفهمم با ویرایش استایل های یک کلاس، تنها اون کلاس رو تغییر دادم و مشکلی ناخواسته برای سایر قسمت های پروژه ایجاد نکردم.
  2. با یه نگاه بتونم بفهمم هر کلاس به کدوم قسمت از مارک آپ ام مرتبطه. یعنی کلاس ها و نام گذاری هاشون بتونن معنی منطقی ای از مارک آپ توی ذهنم ایجاد کنن.
  3. کلاس های سی اس اس تا جایی که ممکنه باید کمترین تغییر در تصوری که از اچ تی ام ال اونها به وجود میاد رو اعمال کنن. (میدونم جمله مبهمیه، بیشتر توضیح میدم بعدا)
  4. با یه نگاه بتونم تشخیص بدم که این کلاس داره توی جاوااسکریپت استفاده میشه یا نه. اینطوری مطمئن میشم اگر استایلش رو تغییر بدم هیچ منطق جی اسی خاصی رو از کار ننداختم.

شروع از BEM

استاندارد BEM پایه این ترکیبه. اگر قبلا با BEM کار نکردین و یا اسمش رو نشنیدین، باید بدونید که عبارت BEM یه مخففه از:

  • B: Block
  • E: Element
  • M: Modifier

اگه برای اولین بار به نوع نام گزاری خاصی که برای کلاس های سی اس اسی توی این استاندارد درنظر گرفته میشه نگاه کنین، ممکنه فکر کنین خیلی زشت و ترسناکه!

.block { /* styles */ }
.block__element { /* styles */ }
.block--modifier { /* styles */ }

خلاف ترسناک و عجیب بودن این نوع نام گزاری، BEM خیلی قدرتمنده. اجازه بدین با یه توضیح مختصر از این نام گزاری بیشتر آشناتون کنم باهاش.

BEM میگه هرچیزی توی سی اس اس یا بلاکه یا المنته یا مودیفایر.

Block چیه؟

هر کامپوننت مجزا یه بلاکه. مثلا اگر بخواین یه فرم تماس بسازین، فرم یه بلاکه. توی استاندارد BEM هر بلاک به صورت منطقی و نرمال نامگزاری میشه. مثلا .form یا .modal. حالا چرا BEM میگه برای یه بلاک کلاس درنظر بگیریم و مثلا نیایم به المنت form استایل بدیم اینه که وابستگی مارک آپ به استایل رو کمتر کنه. شاید جایی شما نیاز داشته باشین از استایل یه فرم استفاده کنین و نه خود فرم!

معمولا دکمه ها در یه پروژه مثال خوبی از بلاک هستن که استایل های متفاوتی هم به خودشون میگیرن. اگر بیاین رنگ بک گراند المنت button رو قرمز کنین، اونوقت همه ی button ها این استایل رو به ارث میبرن. بعد اگر جای دیگه نخوایم دکمه مون بک گراند قرمز داشته باشه باید اونو overwrite کنیم. overwite کردن های پیاپی در سی اس اس یه آنتی پترنه که اگر دچارش بشین کار رو براتون خیلی سخت میکنه.

button {
  background-color: red;
}
.something button {
  background-color: blue; /* 😱 */
}

ولی اگر به جای استایل دادن به المنت button به کلاس .button استایل بدین، میتونین نوع دیگری از دکمه ها رو برای کیس های مختلف استایل بزنین. این پترنیه که توی کتابخونه های معروفی مثل Bootstrap هم میبینیم.

انواع مختلف یه بلاک میشه قسمت بعدی تعریف BEM یعنی Modifier ها.

Modifier چیه؟

مودیفایر یه جور فلگه برای نشون دادن حالت های مختلف یه بلاک. اگر به همون مثال دکمه ها برگردیم و استایل های مختلف دکمه ها در Bootstrap رو مثل بزنیم: در بوت استرپ ۴ حالت برای دکمه ها درنظر گرفته شده مانند .btn-primary. با استفاده از اصل نامگزاری مودیفایر حالت متفاوت یه بلاک با علامت -- نشون داده میشه. مثلا .button--primary. اگر بلاکی دارای مودیفایر باشه الگوی صحیح اینه که استایل های مشترک رو به کلاس بلاک بدین و استایل های مختص هر حالت رو به مودیفایر اون حالت بدین. مثال زیر رو ببینید:

/* block */
.button {
  display: inline-block;
  border: 1px solid #4183C4;
  background-color: #4183C4;
  color: #fff;
  padding: .5em .75em;
}
/* modifiers */
.button--large {
  padding: 1em 1.5em;
}
.button--small {
  padding: .25em .5em;
}

حالا که کامل متوجه شدین بلاک و مودیفایر به چی میگن بریم سراغ آخرین قسمت یعنی المنت ها.

Element چیه؟

المنت ها اجزای کلیدی بلاک هستن. مثلا تایتل و فوتر یه مودال. برای اینکه بگیم یه کلاس المنتی از یه بلاکه باید اونو با علامت __ اسم گزاری کنیم. اگر همون مثال دکمه ها رو ادامه بدیم، فکر کنین به دکمه ها استایل دادیم و انواع مختلف دکمه ها رو هم با مودیفایر ها تعریف کردیم. حالا میخوایم گروهی از دکمه های کنار هم درست کنیم مثل این شکل: دکمه های گروهی توی این مثال کل گروه دکمه ها یه بلاکه. دکمه های این گروه هرکدوم یه المنت هستن و دکمه های گوشه های راست و چپ، با مودیفایر مشخص میشن. طبق توضیحاتی که تا اینجا از BEM بهتون دادم نامگزاری ها میتونه به این صورت باشه: کل بلاک .btngroup هر المنت .btngroup__button دکمه های گوشه راست و چپ .btngroup--rightbtn, .btn-group--leftbtn

شرط میبندم الان دیگه این نوع نامگزاری براتون ترسناک نیست و کاملا هم منطقی به نظر میاد. در بلند مدت و در پروژه های بزرگ، هرچقدر بیشتر به این استاندارد تکیه کنید، کار رو برای خودتون و همکارانتون در آینده راحت تر کردید. پیروی از این استاندارد نه تنها نامگزاری ها رو یکدست میکنه بلکه نقش هر کلاس رو شفاف تر هم میکنه و خیلی راحت میشه از روی فایل سی اس اس، یه داکیومنتیشن خوب از استایل های پروژه ساخت.

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

یادتون باشه، اگر تو پیروی از استاندارد BEM به جایی رسیدین که اسم یه کلاس رو گذاشتین .btngroup__button__innertext مطمئن باشین که دارین اشتباه بزرگی میکنین. اسم های طولانی و چندقسمتی در BEM معمولا نشونه اشتباه در منطق تون هستن. برای اینکه با روش های حل این مشکل بیشتر آشنا بشین، به مطلبی که قبلا در این مورد نوشتم رجوع کنین.

گذر از BEM و ترکیب با سایر استانداردها

توی استاندارد BEM اگر دقت کرده باشین حرفی از لی اوتینگ زده نمیشه. BEM همه چیز رو در یکی از سه نقش بلاک، المنت یا مودیفایر خلاصه میکنه. اما اگر وب سایت طراحی کرده باشید حتما متوجه شدین که گاهی اوقات بعضی از اجزای یه لی اوت توی این ۳تا خلاصه نمیشه. مثل کانتینرها.

به عکس زیر از سایت Sussy نگاه کنید: کانتینر در طراحی وب سایت Sussy

به تجربه برام ثابت شده در طراحی لی اوت این عکس مارک آپ اچ تی ام ال زیر مناسبه:

<section>
  <div class="l-wrap">
    <div class="block">
      <!-- ... -->
    </div>
  </div>
</section>

ولی سوالی که پیش میاد اینه که تگ section باید چه کلاسی بهش داده بشه؟ باید المنتی از والدش باشه؟ یا نه، باید خودش یه بلاک باشه؟ اصلا اون کلاس l-wrap چیه؟

خب برای دونستن جواب سوال های بالا توضیحات کاملی در مورد NameSpacing باید بدم که میتونین اون رو در قسمت دوم این مطلب دنبال کنید.

جمع بندی

توی این مطلب راجع به مشکلات کار با سی اس اس بدون یه استاندارد مناسب صحبت کردیم و فهمیدیم که بدون استاندارد کار تیمی خیلی سخت میشه. برای حل این مشکل رفتیم سراغ استاندارد BEM و اونو شناختیم. درنهایت هم رسیدیم به مرحله ای که ‌ٍBEM رو با ترکیبی از استانداردهای لی اوت دیزاین تکمیل تر باید تکمیل کنیم تا به یه چارچوب جامع برسیم.

این مطلب تنها شامل قسمت اول کل مفهوم سی اس اس برای پروژه های بزرگ بود. برای خوندن قسمت دوم این مطلب منتظر باشید.