یک استایل برای چند Selector: Grouping Selectors

گاهی وقتا می‌خوایم دقیقاً یک استایل رو، بدون هیچ تفاوتی، روی چند Selector مختلف اعمال کنیم. به‌جای تکرار همون بلوک استایل چند بار، CSS این امکان رو می‌ده که Selectorها رو با هم گروه‌بندی کنیم.

مشکل بدون Grouping

فرض کن می‌خوای تمام تیترها (از h1 تا h3) رنگ یکسانی داشته باشن:

h1 {
  color: #1a1a2e;
}

h2 {
  color: #1a1a2e;
}

h3 {
  color: #1a1a2e;
}

همون‌طور که می‌بینی، یه Property و Value کاملاً یکسان (color: #1a1a2e;) سه بار تکرار شده. این نه‌تنها کد رو طولانی‌تر می‌کنه، بلکه اگه بخوایم بعداً این رنگ رو تغییر بدیم، باید هر سه جا رو دستی ویرایش کنیم.

راه‌حل: Grouping با کاما

می‌شه همین سه Selector رو با یک کاما (,) از هم جدا کرد و در یک Rule واحد قرار داد:

h1,
h2,
h3 {
  color: #1a1a2e;
}

این Rule دقیقاً همون نتیجه مثال قبلی رو می‌ده، ولی با کد بسیار کوتاه‌تر و قابل‌نگهداری‌تر. اگه بعداً بخوایم رنگ رو عوض کنیم، فقط کافیه یک جا تغییرش بدیم.

Syntax دقیق Grouping

Selectorهای گروه‌بندی‌شده با کاما از هم جدا می‌شن. فاصله یا خط جدید بین اون‌ها صرفاً برای خوانایی‌ست و از نظر فنی الزامی نیست:

h1, h2, h3 {
  color: #1a1a2e;
}

این دقیقاً معادل همون مثال قبلیه که هر Selector رو در یک خط جدا نوشتیم. رایج‌ترین سبک نوشتاری در پروژه‌های واقعی، قرار دادن هر Selector در یک خط جداست، چون خوانایی بیشتری داره؛ مخصوصاً وقتی تعداد Selectorها زیاد می‌شه.

Grouping با انواع مختلف Selector

Grouping فقط محدود به Type Selectorها نیست؛ می‌شه هر ترکیبی از Type، Class، ID، Attribute Selector یا حتی Selectorهای ترکیبی رو با هم گروه‌بندی کرد:

.error,
#warning-box,
input[type="email"] {
  border: 1px solid red;
}
<p class="error">پیام خطا</p>
<div id="warning-box">جعبه هشدار</div>
<input type="email">

در این مثال، سه عنصر کاملاً متفاوت (یک Class، یک ID و یک Attribute Selector)، همگی یک بوردر قرمز مشترک می‌گیرن؛ با اینکه هیچ ارتباط ساختاری یا نوعی با هم ندارن.

هر Selector گروه، Specificity مستقل خودش را دارد

نکته‌ای که خیلی مهمه: Grouping فقط یک روش خلاصه‌نویسیه؛ از نظر مرورگر، هر Selector داخل گروه، دقیقاً مثل اینه که در یک Rule جدا نوشته شده باشه. یعنی Specificity هر Selector، کاملاً مستقل و بر اساس نوع خودش محاسبه می‌شه، نه بر اساس کل گروه.

.title,
#main-heading {
  font-size: 24px;
}

در این مثال، .title Specificity برابر (0,0,1,0) داره و #main-heading جدا و مستقل، Specificity برابر (0,1,0,0) داره. این دو هیچ تأثیری روی Specificity همدیگه نمی‌ذارن.

ترکیب Grouping با Combinatorها

می‌شه Grouping رو با Combinatorهایی که در درس قبل دیدیم هم ترکیب کرد:

article h2,
aside h2 {
  font-weight: bold;
}
<article>
  <h2>این تیتر Bold می‌شود</h2>
</article>

<aside>
  <h2>این تیتر هم Bold می‌شود</h2>
</aside>

<section>
  <h2>این تیتر Bold نمی‌شود</h2>
</section>

در این مثال، هر h2ای که داخل article یا داخل aside باشه Bold می‌شه؛ ولی h2 داخل section که در گروه ذکر نشده، بدون تغییر باقی می‌مونه.

یک اشتباه رایج: کاما فراموش‌شده

فراموش کردن کاما بین دو Selector، معنای Rule رو کاملاً عوض می‌کنه:

/* Grouping درست: دو Selector مستقل */
h2, p {
  margin-bottom: 10px;
}

/* بدون کاما: این دیگر Grouping نیست، بلکه Descendant Combinator است */
h2 p {
  margin-bottom: 10px;
}

Rule اول یعنی «هم h2 و هم p، رنگ یکسان بگیرن». اما Rule دوم (بدون کاما) کاملاً معنای متفاوتی داره: «فقط pهایی که داخل h2 قرار دارن» (که در عمل بی‌معنیه، چون تگ p نمی‌تونه داخل h2 قرار بگیره). این تفاوت، یکی از رایج‌ترین منابع خطای ناخواسته در CSS‌ه.

چرا Grouping مفید است؟

  • کاهش تکرار کد و حجم فایل CSS
  • سهولت در نگهداری؛ تغییر یک استایل مشترک فقط در یک محل
  • خوانایی بهتر وقتی چند عنصر واقعاً باید استایل یکسانی داشته باشن

نکات مهم

  • Grouping فقط برای Selectorهایی مناسبه که واقعاً قراره استایل کاملاً یکسانی داشته باشن؛ نه استایل مشابه با چند تفاوت جزئی.
  • هر Selector داخل گروه، Specificity مستقل خودش رو داره.
  • فراموش کردن کاما، معنای Rule رو به یک Combinator کاملاً متفاوت تبدیل می‌کنه.

اشتباهات رایج

  • فراموش کردن کاما بین دو Selector، که باعث تبدیل ناخواسته Grouping به Descendant Combinator می‌شه.
  • گروه‌بندی کردن Selectorهایی که فقط بخشی از استایل‌شون مشترکه، در حالی که بهتر بود یه Rule جدا با اون بخش مشترک نوشته بشه.

جمع‌بندی

Grouping Selectors با استفاده از کاما، امکان اعمال یک استایل یکسان روی چند Selector مختلف رو در یک Rule واحد فراهم می‌کنه؛ بدون نیاز به تکرار کد. هر Selector داخل گروه، Specificity مستقل خودش رو حفظ می‌کنه، و باید دقت کرد که فراموش کردن کاما، معنای Rule رو کاملاً تغییر می‌ده.