حسان امینی لو
حسان امینی لو
خواندن ۱۰ دقیقه·۲ سال پیش

متدلوژی های CSS مثل BEM و OOCSS, SMACSS, Atomic

خب شاید قبلا اسم این چیزا رو شنیده باشید، اسماشون یکم ترسناک میزنن ولی در حقیقت خیلی ساده هستند، مهم هدف این متد هاست. بذارید یه سناریو رو باهم ببریم جلو، فرض کنید یه دیزاین سیستم آقا یا خانم دیزاینر آماده کرده که طبق اون همه صفحات و ... طراحی شده. یه چیزی شبیه این:

این فقط Buttons هست ولی دیزاین سیستم معمولا خیلی بزرگ تر از اینه
این فقط Buttons هست ولی دیزاین سیستم معمولا خیلی بزرگ تر از اینه


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

من قبلا در مورد این موضوع و Storybook یه مطلب نوشته بودم که یکم توضیح داده بودم:

https://virgool.io/@hesanam/%D8%A7%D8%B3%D8%AA%D9%88%D8%B1%DB%8C-%D8%A8%D9%88%DA%A9-%D9%88-react-%DB%8C%D9%87-%D8%AA%D8%B1%DA%A9%DB%8C%D8%A8-%D9%87%DB%8C%D8%AC%D8%A7%D9%86-%D8%A7%D9%86%DA%AF%DB%8C%D8%B2-b53uegmbw5rj


اینجا ولی میخوایم دقیق تر راجع به استایل ها صحبت کنیم و اینکه چطور میتونیم استایل ها رو بهتر manage کنیم.


چرا بهتره از این متد ها استفاده کنیم؟

در کل این متدلوژی ها به ما کمک میکنن که استایل هایی که مینویسیم مرتب و یکدست باشه، مدیریتشون راحت تر باشه و از تکرار جلوگیری بشه. این متد ها به ما یک ساختار مشخص برای نوشتن کد های CSS میدن که اگر این practice ها درست پیاده سازی بشه میتونه خوندن کد رو راحت تر کنه، کار تیمی روی پروژه ساده تر میشه و در کل فرایند توسعه پروژه رو بهبود میده.

چندتا از معروف ترین متدلوژی ها:

  • BEM
  • OOCSS
  • SMACSS
  • Atomic

الان میخوایم باهم این متد های مختلف رو مرور کنیم و ببینیم چطوری میتونیم ازشون استفاده کنیم.


متدلوژی BEM

مخفف Block Element Modifier هست، تقریبا بین همه این متدلوژی ها یکی از معروف ترین هاست که شاید اسمش رو قبلا شنیده باشید و حتی کار کرده باشید باهاش. این متدلوژی در واقع یه استاندارد تعیین میکنه برای اسم گذاری کلاس های CSS.

نحوه تقسیم بندیش هم سادس، اول یه block تعریف میشه، مثلا product-card حالا این کارت محصول قسمت های مختلفی داخلش داره که به اسم element میشناسیم مثل عنوان محصول، رنگ، قیمت و دکمه افزودن به سبد. حالا ممکنه که این دکمه افزودن به سبد حالت های مختلفی داشته باشه (یعنی المان همون هست ولی نحوه نمایشش میتونه متفاوت باشه) که بهش میگیم modifier.

یه نمونه کد ساده ببینیم:

اینجا کلاس card نقش Block رو داره، کلاس card__title و card__description نقش element و card__button--primary هم یک modifier هست.

توی CSS هم این شکلی میشه:


این ساختار خیلی بهمون کمک میکنه که ارتباط بین کلاس های مختلف که همه شون در راستای یک چیز هستند رو متوجه بشیم و بهتر درک کنیم و ساختارشون رو راحت تر بتونیم تغییر بدیم. برای تعریف یک element از دو تا کاراکتر __ استفاده میکنیم و برای modifier هم از دو تا کاراکتر -- . این دیگه میشه یه روش برای اسم گذاری کلاس ها.

اگر بعضی المان هایی که دارید خودشون شامل زیرمجموعه های دیگه میشن حواستون باشه که این nesting رو بیشتر از ۲-۳ مرحله ادامه ندید چون بدتر باعث میشه خوانایی کدتون بیاد پایین. توی اون مواقع بهتره که یک block جدید براش تعریف کنید.

انتهای مطلب یه نمونه کد گذاشتم که حتما ببینیدش.


متدلوژی OOCSS

این Object-Oriented مارو هیچ جا ول نمیکنه نه؟

روشی که این متد پیشنهاد میده جدا کردن ساختار ها Structure از پوسته یا skin هست. مثلا شما ساختار یه چیزی رو تعیین میکنی که جلو گیری میکنه از دوباره تعریف کردنش و skin های مختلف رو بسته به جایی که میخواد استفاده بشه تعیین میکنی. یه مثال ببینیم:

یه نیمچه OOCSS رو مشاهده میکنیم! تو اینجا ما به کلاس card و btn میگیم یه آبجکت که میتونیم ازشون تو کل اپلیکیشن چندین مرتبه استفاده کنیم بدون اینکه نیاز باشه دوباره تعریف بشن. در کل روش عجیبیه من خودم نمیتونم خیلی باهاش کنار بیام، ولی ناخودآگاه ما خیییییلی اوقات از این روش استفاده کردیم و می‌کنیم بدون اینکه متوجه بوده باشیم اصلا چی هست. معمولا تو این روش ما فقط ساختار المان ها رو مشخص می‌کنیم، بدون اینکه توجه کنیم محتوای داخل این card یا btn چی هست. ما اسکلت اون المان رو تعیین کردیم، کاری نداریم داخلش چی قراره بیاد.


متدلوژی SMACSS

اسمش رو سه بار پشت سر هم تکرار کنید ? خلاصه این عبارته:

Scalable and Modular Architecture for CSS

این چجوری کار میکنه؟ این میگه که بیا بر اساس بخش های مختلفی که تو یک صفحه داری قسمت قسمت کن کد های CSS ات رو. احتمالا شما هم بار ها و بار ها اینکارو قبلا کرده باشید. یه نمونه ببینیم:

همینطور که میبینید استایل ها بر اساس وظیفه ای که دارن طبقه بندی شدن:

  • Base Styles
  • Layout Styles
  • Module Styles
  • State Styles

از نوع استایل ها و پراپرتی هایی که می‌بینید تقریبا مشخصه که هر کدوم چه وظیفه ای دارن ولی برای توضیحات بیشتر:

  • استایل های base معمولا برای استایل های default استفاده میشن که تو کل وبسایت اثر دارن مثل font و این چیزا
  • استایل های layout ساختار وبسایت و چیدمان رو کنترل میکنن مثل header و footer
  • ماژول ها (Module) معمولا UI Component ها هستن مثل button و input و card و این چیزا
  • استایل های State هم باز مشخصه مثلا کلاس معروف sr-only میشه یه دونه از این استایل ها که میتونه وضعیت نمایش یه المان رو تعیین کنه.


متدلوژی Atomic

به نظرم یکی از متدلوژی های دوست داشتنیه. بیشتر هدفش روی کوچیک کردن استایل ها و ریز ریز کردنشون و بنابراین ساختن المان ها و اجزای مختلف وبسایت با کنار هم چیدن این اتم های کوچیک، ممکن میشه. نمونه اش رو ببینید:

اینجا ما کلی کلاس داریم میدیم به هر کدوم از المان ها و هر کدوم این کلاس ها توی CSS فقط یک کار رو انجام میده مثلا flex فقط display: flex هست. یا text-center فقط داخلش text-align: center هست.

یه بدی این روش میتونه این باشه که اگر بخواید المان های پیچیده رو بسازید مجبورید یه دفتر کلاس بدید بهش که خوندن اون کد HTML رو سخت تر میکنه. البته اگر component کرده باشید تا حدی این مشکل حل میشه ولی اصل ماجرا همچنان هست.

مزیتش در عوض بهبود سرعت توسعه میتونه باشه، طوری که شما فقط جایی هستید که دارید HTML یا JSX مینویسید، بدون اینکه مجبور باشید هی بین این فایل ها سوییچ کنید و به نظرم تغییر المان ها به کمک این روش ساده تر انجام میشه. از طرفی اندازه فایل CSS نهایی هم به شدت میتونه کاهش پیدا کنه و در نتیجه پرفورمنس بهتری داشته باشید‌ (البته خیلی فاکتور های دیگه هم هست ها، من دارم یه گوشه کوچیکش رو میگم فقط)


از کدوم بهتره استفاده کنیم؟

واقعا بین این روش ها مثل همیشه باید بگم بهتر و بدتر وجود نداره، ببینید خودتون با کدوم بیشتر حال می‌کنید، همونو انجام بدید. اگه خیلی براتون اهمیت داره انتخاب درست، چندتا فاکتور رو مد نظر قرار بدید:

  • اندازه پروژه: برای پروژه های کوچیک یه روش ساده تر بهتر معمولا جواب میده مثل Atomic. برای پروژه های بزرگ‌تر روش های ساختارمند تر مثل BEM و SMACSS بهتر جواب میده
  • اندازه تیم: اگه با یه تیم رو پروژه کار می‌کنید مهمه که روشی رو انتخاب کنید که همه اعضای تیم باهاش راحت باشن، شاید بهتر باشه جلساتی باهم داشته باشید که این موضوع رو به بحث بذارید و نظر همه رو بگیرید.
  • قابلیت استفاده مجدد: توی پروژه های بزرگ بحث Reusable بودن کد خیلی اهمیت پیدا میکنه، اینجور مواقع بهتره از روش های ساختارمندی مثل BEM یا OOCSS استفاده کنید.
  • پرفورمنس: اگه براتون Performance الویت داره شاید بهتر باشه از روش هایی استفاده کنید که هم خروجی CSS تون کوچیک تر باشه هم سرعت توسعه تون بالاتر بره مثل Atomic.

در نهایت میتونم بگم بهتره این متد ها رو خودتون امتحان کنید و ببینید با کدوم بیشتر راحت هستید و همون رو انجام بدید، در نهایت بر اساس این پارامتر ها تصمیم نهایی رو بگیرید.

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


فریمورک های معروف از کدوم روش ها استفاده میکنن؟

شاید براتون سوال پیش بیاد که مثلا Tailwind یا Bootstrap از کدوم یکی از این متدلوژی ها استفاده می‌کنن، اگر مطلب رو خوب خونده باشید احتمالا جوابش رو الان میدونید.

مثلا Tailwind بیشتر یه فریمورک Utility-based هست که از متد Atomic استفاده میکنه در کنارش از مفاهیمی مثل Functional CSS هم بهره میبره که نوشتن CSS رو ساده میکنه. از این طریق سرعت توسعه رو به شدت بالا میبره و با خرت و پرت های کنارش بحث Performance رو هم خوب مدیریت میکنه.

از طرف دیگه Bootstrap بیشتر از BEM و OOCSS استفاده میکنه البته تو ورژن های اخیر امکانات خاص دیگه ای هم اضافه شده که یکم به Atomic نزدیکه. توی Bootstrap بر خلاف Tailwind به شما یک سری کامپوننت از پیش طراحی شده رو میده و با کلاس ها و المان های HTML شما میتونید المان ها رو ایجاد کنید. یه چیزی که من رو خیلی در مورد بوتسترپ اذیت میکنه اینه که معمولا اگه شما خیلی استایل های خودش رو کاستوم نکنید در نهایت خیلی تابلو هست که تو سایتتون دارید از Bootstrap استفاده میکنید.


کدوم Performance بهتری داره؟

اگه بخوایم ‌Bootstrap و Tailwind رو به نمایندگی از متدلوژی های مختلف بررسی کنیم، اول باید در نظر داشته باشیم که هر دو این فریمورک ها موضوع پرفورمنس رو خیلی خوب manage میکنن ولی شاااید Tailwind یکم وضعیت بهتری داشته باشه مخصوصا اینکه قابلیت Purge داره که میتونه CSS هایی که هیچ جا استفاده نشدن رو از فایل باندل نهایی حذف کنه که خب این خوبه.

در مقابل رویکرد Bootstrap یکم سنتی تره، به صورتی که یک سری کامپوننت از پیش استایل دهی شده رو در اختیار شما میذاره که هرجا دوست دارید ازشون استفاده کنید. من دقیق نمیدونم که آیا Bootstrap هم قابلیت Purge رو داره یا نه ولی اگر نداشته باشه خب مشکلی که بوجود میاد کلی کد CSS هست که هیچ کجا هم استفاده نشده و همراه فایل داره میاد.

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


پنیر اضافه: CSS Modules

بحثم راجع به متدولوژی ها تقریبا تموم شد، ولی برای خودم این موضوع سوال بوده همیشه که CSS Modules کجای این داستان قرار میگیره. خب حقیقت اینه که این موضوع خیلی ربطی به اون متدلوژی ها نداره ولی به نظرم خوب اومد که راجع بهش یه صحبتی بکنم.

این روش استایل دادن که به CSS Module معروفه، کاری که میکنه اینه: فرض کنید شما همون Button رو دارید و میخواید بهش استایل بدید، به جای اینکه استایل های Button رو داخل یه فایل CSS Global تعریف کنید، میتونید توی ماژول خودش انجامش بدید، ابزار هایی مثل Rollup و Webpack به شما اجازه میدن که این استایل ها scope شون فقط مختص همون module بشه. این استایل ها مرسوم هستند به CSS-in-JS و به طور کل ایده اینه که هر کامپوننت استایل های خودش رو در قالب CSS Module کنارش داشته باشه.

با این وجود شما آزادی عمل دارید که بخواید از کدوم متد استفاده کنید.


نون اضافه: Sass

خب تو این مطلب یاد گرفتیم که این متد ها چطوری کار میکنن ولی خیییلی قشنگ تر میشه اگه به کمک Sass استایل ها رو تعریف کنید. برای نمونه همون BEM رو به کمک Sass اگر بخوایم بنویسیم:

قابلیت Nesting که Sass بهمون میده واقعا کمک میکنه که کد خیلی خوانا تر بشه.

حتی یه مرحله میتونیم این رو هم بهبود بدیم و به کمک Mixin های Sass باز هم این کد رو تمیز تر کنیم البته برای اینکه عکس خیلی بزرگ نشه من فقط اسکلت اصلی رو میذارم:

اینجا ما ۲ تا Mixin تعریف کردیم برای تعریف کردن element و modifier که نحوه استفاده ازشون هم پایینش میتونید ببینید. منبع این قسمت هم اینجا میتونید بخونید.



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

bemcssدیزاین سیستم
برنامه نویس از جلو
شاید از این پست‌ها خوشتان بیاید