بررسی مفهوم Specificity در زبان CSS

09 خرداد 1398
درسنامه درس 31 از سری صفر تا صد CSS
CSS-Specificity

Specificity چیست؟

specificity به معنای مشخص بودن و دقیق بودن است. همانطور که قبلا گفته ایم در زبان CSS می توانیم برای یک عنصر واحد چندین قانون CSS بنویسیم که شاید حتی در تضاد هم باشند! اگر چنین اتفاقی رخ دهد مرورگر مجبور است که تعیین کند کدام دستور CSS باید روی عنصر اجرا شود. به این مفهوم specificity می گوییم. برای ساده تر شدن موضوع می توانیم از specificity به عنوان یک هرم یا رتبه بندی سلسله مراتبی یاد کنیم که در آن دستورات مختلف CSS جایگاه های مختلف و اولویت های مختلفی دارند و بر اساس همین اولویت ها روی عناصر اعمال می شوند. به طور مثال سلکتور سراسری (*) specificity بسیار کمی دارد در حالی که سلکتور های id اولویت specificity بالایی دارند. یکی از رایج ترین مشکلات در هنگام کدنویسی CSS نیز همین موضوع است.

در واقع specificity دارای چهار سطح مجزا است و هر کدام از این سطوح دارای اولویت خاص خودشان هستند (رابطه ی سلسله مراتبی):

  • استایل های inline: همانطور که میدانید این نوع استایل ها مستقیما به عنصر هدفشان متصل هستند مانند <";=h1 style="color: #ffffff>
  • id ها: ID ها وظیفه ی شناسایی عناصر مختلف را بر عهده دارند و نباید تکراری باشند (منحصر به عنصر خاصی هستند) مانند navbar#
  • کلاس ها، attribute ها و شبه کلاس ها: کلاس ها را که می شناسید، attribute ها را هم حتما می شناسید، شبه کلاس ها را هم در قسمت های قبل به طور کامل توضیح دادیم (مثال های hover: و focus: و ...).
  • عناصر و شبه عناصر: این دسته شامل عناصر (مانند h1 و p و ...) و شبه عناصر (مانند before: و after: و ...) می شود.

specificity را محاسبه کنید

برای جلوگیری از بروز مشکلات در کدهایتان بهتر است روشی را ابداع کنید تا بتوانید ترتیب اولویت ها (specificity) را به ذهن بسپارید. یکی از راه های پیشنهادی این است: از عدد 0 شروع کنید. 1000 واحد برای attribute های استایل دهی در نظر بگیرید، سپس برای هر id دقیقا 100 واحد اضافه کنید، برای هر attribute، کلاس یا شبه کلاس 10 واحد دیگر و برای هر عنصر یا شبه عنصر 1 واحد اضافه کنید. به مثال زیر نگاه کنید:

A: h1
B: #content h1
C: <div id="content"><h1 style="color: #ffffff">Heading</h1></div>

specificity مربوط به A عدد 1 است (چرا که یک عنصر است)، specificity مربوط به B عدد 101 است (چرا که یک id و یک عنصر است) و specificity مربوط به C عدد 1000 است (چرا که استایل inline است). از آنجایی که 1 کوچکتر از 101 و خود 101 کوچکتر از 1000 است بنابراین دستور سوم (یعنی C) مقدار specificity بیشتری دارد و دستوری است که در نهایت روی عنصر اعمال می شود.

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

قوانین دیگر specificity

1- اگر مقدار specificity برای دو دستور یکسان بود، آخرین دستور در سورس کد اعمال خواهد شد: اگر دو دستور مختلف CSS را برای یک عنصر نوشته باشیم، دستوری که در متن سورس کد از همه پایین تر باشد اولویت بیشتری خواهد داشت. مثال:

<!DOCTYPE html>
<html>
<head>
<style>
h1 {background-color: yellow;}
h1 {background-color: red;}
</style>
</head>
<body>

<h1>This is heading 1</h1>

</body>
</html>

مشاهده ی خروجی در JSBin

همانطور که میبینید خروجی رنگ قرمز است به دلیل اینکه پایین تر از زرد (yellow) قرار دارد.

2- سلکتور های id اولویت بیشتری نسبت به سلکتور های attribute دارند: به کد ساده ی زیر نگاه کنید.

<!DOCTYPE html>
<html>
<head>
<style>
div#a {background-color: green;}
#a {background-color: yellow;}
div[id=a] {background-color: blue;}
</style>
</head>
<body>

<div id="a">This is a div</div>

</body>
</html>

مشاهده ی خروجی در JSBin

خروجی رنگ سبز است؛ به دلیل اینکه specific تر است (در لغت یعنی «مشخص» تر و واضح تر است یا جزئیات بیشتری را شامل می شود).

3- سلکتور های نزدیک تر به عنصر اولویت بیشتری دارند: بر این اساس می توان گفت بین استایل های external (در یک فایل جداگانه CSS) و استایل های internal (در خود سند HTML)، استایل های internal برنده هستند:

From external CSS file:
#content h1 {background-color: red;}

In HTML file:
<style>
#content h1 {
  background-color: yellow;
}
</style>

در مثال بالا خروجی ما رنگ yellow (زرد) خواهد بود چرا که در سند HTML است و به عنصر نزدیک تر است اما دستور مربوط به رنگ قرمز در یک فایل جداگانه قرار دارد.

4- سلکتور های کلاس اولویت بیشتری نسبت به سلکتور های نام عنصر دارند: اگر از یک طرف سلکتور کلاسی مانند intro. و از طرفی سلکتور نام عنصر مانند div یا p داشته باشیم، اولویت با سلکتور کلاس خواهد بود. به مثال زیر توجه کنید:

<!DOCTYPE html>
<html>
<head>
<style>
.intro {background-color: yellow;}
h1 {background-color: red;}
</style>
</head>
<body>

<h1 class="intro">This is a heading</h1>

</body>
</html>

مشاهده ی خروجی در JSBin

5- سلکتور سراسری و سلکتور ها یا مقادیری که به ارث رسیده اند، اولویت 0 دارند: این مورد به نظر من واضح است؛ اگر سلکتوری مانند * یا * body داشته باشید تنها در صورتی اعمال خواهد شد که هیچ استایل دیگری برای آن عنصر تعیین نشده باشد. همین مورد برای استایل هایی که از عناصر پدر یا موارد پیش فرض مرورگر می آیند نیز صدق می کند.

جمع بندی

برای تمرین و جمع بندی این نکات به جدول زیر نگاه کنید و سعی کنید مقدار specificity را خودتان حدس بزنید:

مثال از یک سلکتور مقدار specificity (اجزاء مختلف سلکتور)
* { } 0
li { } 1 (تنها یک عنصر است)
li:first-line { } 2 (یک عنصر و یک شبه عنصر)
ul li { } 2 (دو عنصر)
ul ol+li { } 3 (سه عنصر)
h1 + *[rel=up] { } 11 (یک attribute و یک عنصر)
ul ol li.red { } 13 (یک کلاس، سه عنصر)
li.red.level { } 21 (دو کلاس و یک عنصر)
style=“” 1000 (یک استایل inline)
p { } 1 (یک سلکتور نام تگ)
div p { } 2 (دو سلکتور نام تگ)
.sith 10 (یک سلکتور کلاس)
#sith 100 (یک سلکتور id)
body #darkside .sith p { } 112 (سلکتور نام تگ، سلکتور id، سلکتور کلاس، سلکتور نام تگ.) بنابراین:

1+100+10+1

به شما تبریک می گویم که تا این قسمت با ما همراه بوده اید. این قسمت آخرین قسمت از دوره ی پایه ی CSS بود. دوره ی بعدی CSS، دوره ی «CSS پیشرفته» خواهد بود. امیدوارم از این قسمت لذت برده باشید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری صفر تا صد CSS توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (3 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

علی
08 دی 1399
سلام و وقت بخیر با تشکر از مقالات سایت تون که موضوعات مختلف رو گام به گام توضیح دادین . خیلی علاقه مندم که سایت شما دوره ای برای فلاتر یا سلسله مقالاتی برای اموزش فلاتر داشته باشد . ممنون

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

EYRES
24 مرداد 1399
آموزش های سایت بسیار برای افراد مبتدی مفید است و برای شروع ، این سایت جزو بهترین هاست . ممنون از عوامل سایت .

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

amir abedin
24 مرداد 1399
داداش مرسی از این همه زحمتی که کشیدی همه چیز کامل و عالی ممنون از وقتی که گذاشتی و این آموزش هارو تهیه کردی دمت گرم

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.