هنگامی که برای اولین بار CSS را یاد می‌گیریم با انواع مختلفی از selectorها مانند class selector و id selector آشنا می‌شویم، اما صدها ترکیب selector دیگر در CSS وجود دارد که برای رسیدن به تسلط کافی باید آن‌ها را بدانیم. در این مقاله قصد داریم تا با انواع selector در CSS آشنا شویم.

selectorهای پایه‌ای

برای شروع باید با ابتدایی‌ترین شکل selectorها آشنا شویم و همچنین در مورد چیستی selector در CSS صحبت کنیم. selector کدی است که به سادگی آن را می‌نویسیم و از طریق آن تعیین می‌کنیم که استایل‌های CSS موردنظرمان به کدام المنت HTML ارجاع داده شوند. در مثال زیر .class-nameسلکتور CSS است زیرا قبل از {}قرار می‌گیرد.

.class-name {
  color: blue
}

به‌طور کلی چهار نوع selector پایه‌ای وجود دارد و همه selectorهای دیگر براساس آن‌ها ساخته شده‌اند که عبارتند از: universal، type، class و id.

Universal Selector

Universal Selector که یک *می‌باشد، همانطور که از نامش مشخص است همه چیز را انتخاب می‌کند. به عنوان مثال کد زیر برای همه المنت‌های موجود در صفحه مقدار margin را روی ۰ تنظیم می‌کند.

* {
  margin: 0;
}

این selector برای زمانی که می‌خواهیم تغییرات بزرگی را در کل صفحه خود ایجاد کنیم، مانند تنظیمات مربوط به box-size و یا حذف margin و غیره یه انتخاب بسیار عالی است، اما معمولاً استفاده از آن برای موارد دیگر توصیه نمی‌شود.

Type Selector

ممکن است به ندرت از Type Selector استفاده کنیم زیرا بسیار عمومی بوده و نمی‌تواند خیلی مفید باشد. این selector به ما این امکان را می‌دهد تا تمام المنت‌های یک نوع خاص مانند همه المنت‌های div یا img را انتخاب کنیم. برای استفاده از این selector فقط نام المنتی را که می‌خواهیم انتخاب کنیم مورد استفاده قرار می‌دهیم. مثال زیر تمام المنت‌های div را انتخاب می‌کند.

div {
  background-color: red;
}

بهتر است از این selector استفاده نکنیم زیرا این احتمال وجود دارد المنتی که نمی‌خواهیم هیچ استایلی داشته باشد با این روش به‌طور تصادفی استایل بگیرد. استفاده از آن تنها زمانی می‌تواند مفید باشد که بخواهیم برخی از استایل‌های پیش‌فرض را تنظیم کنیم که برای کل سایت اعمال شود، مانند تنظیم font-sizeبرای تگ‌های عنوان، یا انتخاب تگ bodyبرای حذف marginها.

Class Selector

این selector تا حد زیادی به عنوان رایج‌ترین نوع شناخته می‌شود. کلاس‌ها ویژگی‌هایی هستند که می‌توانیم آن‌ها را به هر المنت HTMLای که اضافه کنیم که هیچ هدفی جز استفاده با CSS یا جاوااسکریپت ندارد. class selectorها در CSS بسیار شگفت‌انگیز هستند زیرا این اجازه را به ما می‌دهند تا مشخص کنیم که کدام المنت در HTML را می‌خواهیم استایل‌دهی کنیم. همچنین می‌توانیم با دادن یک کلاس به آن‌ها، استایل‌ها را بین چندین المنت به اشتراک بگذاریم.

<button class="btn btn-primary">Save</button>
<button class="btn btn-danger">Cancel</button>

همانطور که در مثال بالا می‌بینید ما به هر دو باتن کلاس btnرا اختصاص داده‌ایم تا هر دو بتوانند استایل‌های مرتبط با آن کلاس را در CSS به اشتراک بگذارند. همچنین به هر یک از آن‌ها کلاس btn-primaryیا btn-dangerرا اختصاص دادیم تا استایل‌های مخصوص هر باتن به‌صورت جداگانه به آن‌ها اضافه شود. برای استفاده از class selector در CSS، به سادگی نام کلاسی را که می‌خواهیم انتخاب کنید، بعد از یک .قرار می‌دهیم.

.btn {
  border: 1px solid black;
}

.btn-primary {
  background-color: blue;
}

.btn-danger {
  background-color: red;
}

Id Selector

آخرین selector پایه‌ای، id selectorها می‌باشند. آن‌ها بسیار شبیه به class selectorها هستند زیرا می‌توانیم idها را روی المنت‌های HTML تعریف کنیم و سپس در CSS به آن‌ها ارجاع دهیم، اما چند تفاوت وجود دارد.

اولین تفاوت اصلی این است که id selectorها را نمی‌توانیم بین المنت‌های موجود در یک صفحه به اشتراک بگذاریم زیرا در HTML هر id منحصربه‌فرد است و هیچ دو المنتی نمی‌توانند id یکسانی داشته باشند.

تفاوت نهایی این است که id selectorها به جای .با علامت #شروع می‌شوند.

<nav id="nav-bar">...</nav>
#nav-bar {
  margin-bottom: 1rem;
}

Selectorهای ترکیبی

قدرت واقعی selectorهای CSS در توانایی ما برای ترکیب آن‌ها با یکدیگر می‌باشد. شش selector ترکیبی اصلی وجود دارد که باید با آن‌ها آشنا شویم چرا که این امکان را به ما می‌دهند تا هر بار دقیقاً المنت مورد نظر خود را انتخاب کنیم.

Descendant Selector

اولین نوع از selectorهای ترکیبی، descendant selector است. این selector کمک می‌کند تا هر المنتی که با یک selector خاص مطابقت دارد انتخاب کنیم. در مثال زیر آن را بررسی می‌کنیم.

div span {
  color: red;
}
<div>
  <span>Selected</span>
  <a>
    <span>Selected</span>
  </a>
</div>
<span>Not</span>

سلکتور CSS بالا تمام المنت‌های span را که از childهای المنت div هستند انتخاب می‌کند. طبق این تعریف اولین span انتخاب شده است زیرا child مستقیم div است. span دوم نیز انتخاب شده است زیرا در حالی که child مستقیم div نیست اما از نسل آن است. با این حال، span نهایی انتخاب نشده است، زیرا داخل div قرار ندارد.

برای استفاده از descendant selector تنها کاری که باید انجام دهیم این است که دو selector را با space از هم جدا کنیم. selector اول انتخاب‌کننده parent و selector دوم انتخاب‌کننده childها خواهد بود.

Direct Child Selector

این مورد بسیار شبیه به descendant selector است اما تفاوت اصلی بین آن‌ها این است که direct child selector تنها المنتی را انتخاب می‌کند که child مستقیم اولین سلکتور parent باشد. به عنوان مثال:

div > span {
  color: red;
}
<div>
  <span>Selected</span>
  <a>
    <span>Not</span>
  </a>
</div>
<span>Not</span>

همانطور که در مثال بالا مشخص شده است، span داخل تگ a انتخاب نشده است زیرا child مستقیم div نیست، اما child مستقیم تگ a می‌باشد. با این حال، اولین span انتخاب شده است زیرا child مستقیم div است.

برای استفاده از این selector فقط باید یک علامت >بین selector اول و selector دوم قرار دهیم.

General Sibling Selector

این selector می‌تواند کمی گیج‌کننده به نظر بیاید. مفهوم آن را با مثال زیر به‌طور کامل بررسی می‌کنیم.

div ~ a {
  color: red;
}
<a>Not</a>
<div></div>
<a>Selected</a>
<a>Selected</a>

از آنجایی که این سلکتور، general sibling selector نامیده می‌شود، ممکن است اینطور به نظر بیاید که تمام المنت‌هایی که sibling المنت اول به‌شمار می‌آیند انتخاب می‌شوند، اما اینطور نیست. بلکه این selector فقط siblingهایی که بعد از selector اول قرار می‌گیرند را انتخاب می‌کند. این به این دلیل است که CSS فقط می‌تواند در یک جهت بخواند، بنابراین هیچ راهی برای اصلاح المنت‌هایی که قبل از سایر المنت‌ها قرار می‌گیرند، وجود ندارد.

تنها کاری که برای استفاده از این selector باید انجام دهیم این است که یک ~بین selectorها قرار دهیم. selector اول برای تعیین sibling است که موارد بعد از آن را می‌خواهیم بررسی کنیم و selector دوم برای siblingهای واقعی است که ما در حال بررسی آن‌ها هستیم.

Adjacent Sibling Selector

مشابه general sibling selector است اما تفاوتی که وجود دارد این است که این selector فقط می‌تواند المنتی را انتخاب کند که مستقیماً بعد از المنت اول قرار می‌گیرد.

div + a {
  color: red;
}
<a>Not</a>
<div></div>
<a>Selected</a>
<a>Not</a>

همانطور که در مثال بالا می‌بینیم، تگی که بعد از div قرار گرفته تنها تگی است که انتخاب می‌شود. همچنین مهم است به این نکته توجه داشته باشیم که اگر sibling مستقیماً بعد از div، چیزی غیر از تگ a باشد در این صورت selector ما هیچ کاری انجام نمی‌دهد. زیرا فقط می‌تواند المنتی را انتخاب کند که اولین المنت بعد از div باشد.

برای استفاده از این selector فقط یک +بین selector اول و دوم قرار می‌دهیم.

Or Selector

هنگام استفاده از این selector برای استایل‌دهی، المنتی را انتخاب می‌کند که حداقل با یکی از selectorها مطابقت داشته باشد. مثلا:

div, span {
  color: red;
}
<div>Selected</div>
<a>Not</a>
<div>Selected</div>
<span>Selected</span>

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

برای استفاده از or selector، سلکتورها را با کاما از هم جدا می‌کنیم. اما به طور کلی، اگر تعداد selectorها زیاد باشد و طولانی شود، بهتر است آن‌ها را در خطوط مختلف از هم جدا کنیم تا خوانایی کد بیشتر باشد. به عنوان مثال:

.really-really-long-name,
.another-name {
  color: red;
}

And Selector

این سلکتور آخرین selector ترکیبی و احتمالاً پرکاربردترین آن است و این امکان را به ما می‌دهد تا selectorهای CSSای بنویسیم که المنت‌ها را مجبور می‌کند تا با همه selectorهای مشخص شده مطابقت داشته باشند.

div.red {
  color: red;
}
<div class="red">Selected</div>
<div>Not</div>
<span class="red">Not</span>

همانطور که در مثال بالا می‌بینیم فقط div با کلاس red انتخاب شده است. استفاده از selector ترکیبی And بسیار آسان است چون تنها کاری که باید انجام دهیم این است که همه selectorها را بدون اینکه spaceای بین آن‌ها وجود داشته باشد کنار یکدیگر می‌نویسیم.

تنها نکته مهمی که در مورد این selector باید بدانیم این است که اگر از یک universal selector و یا type selector استفاده می‌کنیم، ابتدا باید آن‌ها را قرار دهید.

div.red {} /* Good */
.reddiv {} /* Bad */

نکات مهم selectorهای ترکیبی

نکته مهمی که باید به آن توجه کنیم این است که می‌توانیم از هر یک از selectorهایی که در مورد آن‌ها صحبت کردیم در ترکیب با یکدیگر و یا حتی selectorهای ترکیبی دیگر نیز استفاده کنیم. به عنوان مثال:

div.container > .large.red {
  font-size: 2rem;
  color: red;
}

در مثال فوق ما چندین سلکتور type و class را با ترکیبات سلکتور direct child و and با هم ترکیب کردیم. این توانایی برای ترکیب شدن selector ها باهم باعث می‌شود تا CSS بسیار انعطاف‌پذیر باشد.

Selectorهای Pseudo Element

در بخش‌های قبلی درمورد رایج‌ترین انواع selector ها در CSS صحبت کردیم. اما چند مورد دیگر وجود دارد که باید آن‌ها مورد بررسی قرار دهیم، اما این موارد کمی تخصصی‌تر هستند.

اولین نوع selectorای که در مورد آن صحبت می‌کنیم selectorهای pseudo element هستند که دارای دو مدل می‌باشند. در ادامه بیشتر با آن‌ها آشنا خواهیم شد.

Before Pseudo Element

before pseudo element المنتی است که می‌توانیم آن را بسازیم و به عنوان اولین child المنتی که برای آن ایجاد می‌کنیم، قرار می‌گیرد.

div::before {
  content: "Child 0";
}
<div>
  <span>Child 1</span>
  <span>Child 2</span>
</div>

در کد بالا ما از before pseudo selector برای انتخاب المنت before برای div استفاده می‌کنیم. این یک المنت جدید در HTML ایجاد می‌کند که متن "Child 0"در داخل آن وجود دارد. همانطور که می‌دانیم در HTML ما هیچ المنتی مطابق با المنت ::beforeوجود ندارد و دلیل آن این است که المنت pseudo به طور کامل در CSS ایجاد شده است و وقتی HTML خود را می‌نویسیم به آن ارجاع نمی‌دهیم.

اکنون برای ایجاد یک المنت pseudo  کافیست آن را پیشوند ::قرار داده و سپس نوع المنت pseudoای را که انتخاب می‌کنیم بنویسیم. در مثال بالا می‌خواهیم یک before pseudo element در داخل هر div در صفحه خود ایجاد کنیم.

After Pseudo Element

after pseudo element دقیقاً مشابه before pseudo element است با این تفاوت که به‌جای المنت اول به عنوان آخرین child المنت اضافه می‌شود.

div::after {
  content: "Child 3";
}
<div>
  <span>Child 1</span>
  <span>Child 2</span>
</div>

نکات مهم selectorهای المنت pseudo

ما باید یک ویژگی content برای المنت‌های pseudo خود قرار دهیم وگرنه در صفحه وجود نخواهند داشت. اگر نمی‌خواهیم محتوایی داشته باشد، می‌توانیم به سادگی یک رشته خالی به آن اختصاص دهیم.

div::after {
  content: "";
}

pseudo elementها را نیز می‌توانیم با استفاده از :تعریف کنیم، اما کار این توصیه نمی‌شود.

div:after {
  content: "Technically it works";
}

همچنین نمی‌توانیم المنت‌های pseudo را به المنت‌هایی اضافه کنیم که محتوای آن‌ها را با چیز دیگری مانند المنت imgجایگزین می‌شوند.

در نهایت، المنت‌های pseudo در ابزارهای توسعه‌دهنده مرورگر ظاهر می‌شوند که این موضوع می‌تواند دیباگ کردن آن‌ها را بسیار آسان‌تر کند.

Pseudo Class Selectors

اکنون اینجا واقعاً جایی است که CSS شروع به تبدیل شدن به دنیای گسترده‌ای از selectorها می‌کند. صدها pseudo class وجود دارد که همگی برای نمایش حالت‌های خاص المنت‌ها استفاده می‌شوند که می‌توانیم از آن‌ها به عنوان selector در CSS استفاده کنیم، اما واقعاً فقط تعداد انگشت شماری وجود دارد که آشنایی و درک آن‌ها می‌تواند برای ما مهم باشد.

برای تعریف یک pseudo class، تقریباً مشابه pseudo elementها رفتار می‌کنیم اما به جای ::از :استفاده می‌کنیم.

Hover Pseudo Class

احتمالاً مفیدترین pseudo class در CSS مربوط به hover است. hover pseudo class این امکان را به ما می‌دهد که حالت hover شدن یک المنت‌ را به گونه‌ای متفاوت طراحی کنیم. برای مثال، می‌توانیم رنگ پس‌زمینه یک باتن را تغییر دهیم تا کاربران متوجه قابل کلیک بودن آن شوند.

button:hover {
  background-color: red;
}

در این صورت هنگامی که روی باتن hover می‌شود رنگ پس‌زمینه به قرمز تغییر پیدا می‌کند.

Focus Pseudo Class

focus pseudo class یکی دیگر از selectorهای بسیار مهم است زیرا این امکان را به ما می‌دهد تا یک المنت را براساس فوکوس داشتن یا نداشتن آن استایل‌دهی کنیم. به عنوان مثال، می‌توانیم رنگ border یک فیلد ورودی را هنگامی که روی آن فوکوس شده است، تغییر دهیم.

input:focus {
  border-color: blue;
}

Checked Pseudo Class

checked pseudo class باعث می‌شود تا یک المنت را براساس check بودن یا نبودن آن استایل دهیم. برای مثال می‌توانیم opacity یک چک‌باکس را وقتی علامت زده می‌شود، تغییر دهیم.

input:checked {
  opacity: .8;
}

Disabled Pseudo Class

disabled pseudo class به ما این امکان را می‌دهد تا یک المنت را براساس غیرفعال بودن یا نبودن آن استایل دهیم. برای مثال می‌توانیم رنگ پس‌زمینه یک فیلد ورودی را هنگامی که غیرفعال است تغییر دهیم.

input:disabled {
  background-color: gray;
}

First Child Pseudo Class

همانطور که از نام آن مشخص است اولین child در داخل parent را انتخاب می‌کند.

a:first-child {
  color: red;
}
<div>
  <a>Selected</a>
  <a>Not</a>
</div>
<div>
  <span>Not</span>
  <a>Not</a>
</div>

نکته مهم در مورد این selector این است که اولین child را انتخاب می‌کند نه اولین المنت childای که با سلکتور CSS مطابقت دارد. به همین دلیل است که تگ a در div دوم انتخاب نشده است.

همچنین می‌توانیم از selectorهای only-child، last-child، nth-childو nth-last-childاستفاده کنیم که تقریباً کارهای مشابهی را انجام می‌دهند، اما برای انتخاب سایر childهای خاص هستند.

First Of Type Pseudo Class

first of type pseudo class اولین child درون یک parent که با نوع المنت مورد نظر مطابقت دارد را انتخاب می‌کند.

a:first-of-type {
  color: red;
}
<div>
  <a>Selected</a>
  <a>Not</a>
</div>
<div>
  <span>Not</span>
  <a>Selected</a>
</div>

نکته مهمی که در مورد این selector باید به آن توجه کنیم این است که اهمیتی ندارد که المنت child اول باشد یا نه. بلکه فقط این موضوع مهم است که اولین المنتی باشد که مدنظر می‌باشد.

همچنین می‌توانیم از selectorهای only-of-type، last-of-type، nth-of-typeو nth-last-of-typeاستفاده کنیم که تقریباً همان کارها را انجام می‌دهند، اما برای انتخاب سایر childهای خاص مورد استفاده قرار می‌گیرند.

Not Pseudo Class

آخرین pseudo classای که می‌خواهیم درمورد آن صحبت کنیم not pseudo class است که این امکان را به ما می‌دهد تا المنت‌هایی را انتخاب کنیم که با یک selectoer خاص مطابقت نداشته باشند.

a:not(.green) {
  color: red;
}
<a>Selected</a>
<a class="large">Selected</a>
<span class="red">Not</span>
<a class="green">Not</a>

not pseudo class با قرار دادن یک selector دیگر داخل پرانتز، در داخل سلکتور :notکار می‌کند. این selector داخل پرانتز، سلکتور not است بنابراین در مثال ما تمام تگ‌هایی که کلاس green ندارند را انتخاب می‌کنیم.

Selectorهای ویژگی

آخرین نوع selectorهایی که می‌خواهیم درموردآن‌ها صحبت کنیم selectorهای ویژگی هستند. این selector به ما کمک می‌کند تا هر المنت را براساس ویژگی‌هایی که دارد انتخاب کنیم.

نکته مهم در مورد selectorهای ویژگی این است که همه آن‌ها در []تعریف می‌شوند.

Has Attribute Selector

ابتدایی‌ترین شکل selector ویژگی، has attribute selector است. این selector فقط بررسی می‌کند که آیا یک المنت دارای ویژگی مشخص شده می‌باشد یا خیر.

[data-active] {
  color: red;
}
<div data-active>Selected</div>
<div data-active="true">Selected</div>
<div data-active="false">Selected</div>
<div>Not</div>

این selector اهمیتی نمی‌دهد که مقدار مشخص شده چیست و یا حتی مقداری برای این ویژگی وجود دارد یا نه. تنها موردی که دارای اهمیت می‌باشد این است که یک ویژگی در المنت HTML وجود داشته باشد که با ویژگی مشخص شده در CSS منطبق باشد.

Exact Attribute Selector

اگر می‌خواهیم مقدار خاصی را بررسی کنیم، باید از exact attribute selector استفاده کنیم.

[data-active="true"] {
  color: red;
}
<div data-active>Not</div>
<div data-active="true">Selected</div>
<div data-active="false">Not</div>
<div>Not</div>

exact attribute selector فقط المنت‌هایی را که دارای ویژگی مشخص شده هستند با مقدار دقیق تعیین شده مطابقت می‌دهد. علامت مساوی بین نام ویژگی و value، چیزی است که این را به عنوان exact attribute selector تعریف می‌کند.

Begins With Attribute Selector

اگر می‌خواهیم ویژگی را بررسی کنیم که با یک مقدار مشخص شروع می‌شود، به begins with attribute selector نیاز داریم.

[data-active^="t"] {
  color: red;
}
<div data-active>Not</div>
<div data-active="true">Selected</div>
<div data-active="test">Selected</div>
<div data-active="false">Not</div>

نماد ^و به دنبال آن علامت مساوی بین نام ویژگی و value، چیزی است که این را به عنوان begins with attribute selector تعریف می‌کند.

Ends With Attribute Selector

این selector بسیار شبیه به selector قبلی می‌باشد که درمورد آن صحبت کردیم. تنها تفاوتی که وجود دارد این است که اینجا کاراکتر انتهایی value مورد بررسی قرار می‌گیرد.

[data-active$="e"] {
  color: red;
}
<div data-active>Not</div>
<div data-active="apple">Selected</div>
<div data-active="true">Selected</div>
<div data-active="test">Not</div>

علامت $و به دنبال آن یک علامت مساوی بین نام ویژگی و value، چیزی است که آن را به عنوان ends with attribute selector تعریف می‌کند.

Substring Attribute Selector

این selector بسیار شبیه به دو selector قبلی است، اما کاری که انجام می‌دهد این است که بررسی می‌کند که آیا رشته‌ای که به آن ارسال شده است در هر قسمتی از value ویژگی وجود دارد یا خیر.

[data-active*="e"] {
  color: red;
}
<div data-active>Not</div>
<div data-active="apple">Selected</div>
<div data-active="test">Selected</div>
<div data-active="gap">Not</div>

علامت *و به دنبال آن یک علامت مساوی بین نام ویژگی و value، چیزی است که آن را به عنوان substring attribute selector تعریف می‌کند.

جمع‌بندی

selectorهای CSS فوق‌العاده قدرتمند بوده و کاربردهای بسیار زیادی دارند، اما برای نوشتن CSS فقط به تعداد انگشت‌شماری از آن‌ها نیاز داریم که سعی کردیم تا حد ممکن همه آن‌ها را در این مقاله بررسی کنیم.