ویژگی تصویر

روش نام‌گذاری BEM در CSS — راهنمای جامع

  /  CSS   /  روش نام‌گذاری BEM در CSS
بنر تبلیغاتی الف

روش نام‌گذاری BEM (Block, Element, Modifier) یک الگوی ساختاری و قابل فهم برای نوشتن CSS است که به خوانایی، قابلیت نگهداری و مقیاس‌پذیری کمک می‌کند. در این مقاله به زبان فارسی توضیح می‌دهیم که BEM چیست، قوانین پایه، مثال‌های عملی، اشتباهات رایج و نکات پیشرفته برای پروژه‌های بزرگ.

مبانی BEM — Block، Element و Modifier

  • Block (بلوک): یک جزء مستقل که مفهوم و عملکرد مشخصی دارد، مثل menu یا card.
  • Element (المان): قسمت داخلی بلوک که وابسته به آن است و بدون بلوک معنی ندارد؛ با دو underscore جدا می‌شود: block__element.
  • Modifier (مدیفایر): حالت یا تغییر در بلوک/المان که با دو hyphen نمایش داده می‌شود: block--modifier یا block__element--modifier.

قواعد نوشتاری پیشنهادی

  • از حروف کوچک و خط تیره برای جدا کردن کلمات استفاده کنید (kebab-case).
  • هر کلاس فقط یک مسئولیت داشته باشد: استایل یا هوک برای JS، نه هر دو همزمان.
  • از انتخابگرهای descendant عمیق و جمله‌ای پرهیز کنید؛ بهتر است با کلاس‌های BEM کار کنید تا specificity کنترل شود.

نمونه ساده HTML و CSS با BEM

<!-- HTML -->
<div class="card card--featured">
  <h3 class="card__title">عنوان کارت</h3>
  <p class="card__description">توضیحات کوتاه...</p>
  <button class="card__action card__action--primary">خرید</button>
</div>

در این کد، card بلاک است، card__title و card__description المان‌‌ها هستند و card--featured و card__action--primary مدیفایرها.

/* CSS */.card { border: 1px solid #ddd; padding: 16px; border-radius: 6px; }
.card--featured { box-shadow: 0 4px 14px rgba(0,0,0,0.08); }
.card__title { margin: 0 0 8px; font-size: 1.1rem; }
.card__description { color: #666; font-size: 0.95rem; }
.card__action { background: none; border: 1px solid #ccc; padding: 8px 12px; }
.card__action--primary { background: #0069ff; color: #fff; border-color: #0069ff; }

در CSS بالا، هر کلاس تنها به خودش وابسته است؛ بنابراین می‌توان کارت‌ها را در جاهای مختلف بدون نگرانی از تداخل استفاده کرد.

مقایسه‌ی مفهومی — جدول

نوعنمونه نامتوضیح
Blockmenuکامپوننت مستقل
Elementmenu__itemقسمت داخلی وابسته به menu
Modifiermenu__item–activeحالت یا تغییر در item

مثال عملی: تبدیل CSS به سبک BEM

فرض کنید استایل اولیه شما به شکل زیر است (غیر BEM):

<!-- Non-BEM HTML -->
<ul class="nav">
  <li class="active">Home</li>
  <li>About</li>
</ul>

مشکل: کلاس عمومی active می‌تواند در هرجای پروژه تداخل ایجاد کند. بهتر است با BEM:

<ul class="nav">
  <li class="nav__item nav__item--active">Home</li>
  <li class="nav__item">About</li>
</ul>

این نگارش، محدوده کلاس را به بلاک nav محدود می‌کند و از تداخل جلوگیری می‌شود.

نکات پیشرفته و بهترین شیوه‌ها

  • حالت‌های جاوااسکریپتی: به‌جای استفاده از مدیفایرهایی که وابسته به JS هستند، می‌توانید از کلاس‌های state مثل is-open یا has-error استفاده کنید تا واضح باشد که این کلاس‌ها برای وضعیت هستند و نه استایل دائمی.
  • Namespace: در پروژه‌های بزرگ از پیشوند بلوکی (مثلاً app-) برای جلوگیری از تداخل بین پکیج‌ها استفاده کنید: app-card.
  • فایل‌بندی: هر بلوک را در فایل جداگانه نگه دارید (مثلاً _card.scss) و در یک فایل مرکزی آن‌ها را ایمپورت کنید.
  • ابزارها: از stylelint با پلاگین BEM یا قوانین محتاطانه برای جلوگیری از نام‌گذاری نادرست بهره ببرید.

اشتباهات رایج و راه‌حل‌ها

  • استفاده از انتخابگرهای بیش از حد خاص (مانند .block .element > .sub) — راه حل: استفاده از کلاس‌های صریح BEM.
  • ترکیب BEM با selector-based overrides — باعث سردرگمی و specificity بالا می‌شود. بهتر است overrides با مدیفایرها انجام شود.
  • استفاده از تگ HTML به عنوان کلید کلاس — کلاس‌ها باید معنایی مستقل داشته باشند، نه وابسته به تگ.

وقتی BEM کافی نیست

در پروژه‌های خیلی بزرگ یا زمانی که از CSS Modules/Styled Components استفاده می‌کنید، برخی مفاهیم BEM خودکار یا غیرضروری می‌شوند. اما اصول جداسازی و نام‌گذاری واضح که BEM ترویج می‌دهد، همچنان مفید است. می‌توان از نسخه‌های ترکیبی استفاده کرد: نام‌گذاری اساسی BEM به‌علاوه scoping محلی توسط ابزارهای مدرن.

جمع‌بندی و توصیه‌های عملی

  • با قواعد ساده شروع کنید: block__element–modifier.
  • قواعد تیمی (style guide) بنویسید و قوانین را در lint قرار دهید.
  • از BEM به عنوان قرارداد برای همکاری بین تیم CSS، HTML و JS استفاده کنید.
  • در صورت نیاز، از namespace و state-classes برای وضوح بیشتر بهره ببرید.

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

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: