اختصاصی

پادکست CSS - 003: ویژگی

فرض کنید که با HTML و CSS زیر کار می‌کنید:

<button class="branding">Hello, Specificity!</button>
.branding {
  color: blue;
}

button {
  color: red;
}

در اینجا دو قانون وجود دارد که یک عنصر را هدف قرار می‌دهند. هر قانون شامل یک تعریف است که می‌خواهد رنگ دکمه را تنظیم کند: یکی سعی می‌کند دکمه را به رنگ قرمز و دیگری سعی می‌کند آن را به رنگ آبی دربیاورد. کدام تعریف روی عنصر اعمال می‌شود؟

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

ویژگی یکی از مراحل متمایز آبشار است که در ماژول قبلی، در مورد آبشار ، به آن پرداخته شد.

امتیازدهی اختصاصی

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

در مورد میزان دقت در یک پروژه واقعی، عمل متعادل‌سازی این است که مطمئن شوید قوانین CSS مورد انتظار شما واقعاً اعمال می‌شوند، در حالی که عموماً امتیازها را پایین نگه می‌دارید تا از پیچیدگی جلوگیری شود. دقت فقط باید تا جایی که لازم است بالا باشد، نه اینکه بخواهیم بالاترین دقت ممکن را داشته باشیم. در آینده، ممکن است CSSهای واقعاً مهم‌تری لازم باشد اعمال شوند. اگر به دنبال بالاترین دقت باشید، این کار را سخت خواهید کرد.

این ویژگی یک عدد اعشاری نیست، بلکه یک سه‌گانه است که از سه جزء A ، B و C تشکیل شده است.

  • A ) ویژگی شبیه به شناسه
  • B : ویژگی شبه کلاس
  • C : ویژگی شبه عنصری

اغلب با استفاده از نمادگذاری (A,B,C) نمایش داده می‌شود. برای مثال: (1,0,2) . نمادگذاری جایگزین ABC نیز معمولاً استفاده می‌شود.

نموداری که سه مؤلفه‌ی ویژگی (A، B، C) را نشان می‌دهد. برای هر مؤلفه، نمودار نشان می‌دهد که چه چیزی را نشان می‌دهد و چند نمونه از انتخابگرهایی که بر آن تأثیر می‌گذارند را نیز نشان می‌دهد.
نموداری که نشان می‌دهد انتخابگرهای مختلف بر کدام مؤلفه از ویژگی (specificity) تأثیر می‌گذارند.

نحوه مقایسه ویژگی‌های خاص

ویژگی‌ها با مقایسه سه مؤلفه به ترتیب مقایسه می‌شوند: ویژگی‌ای که مقدار A بزرگ‌تری دارد، ویژگی بیشتری دارد؛ اگر دو مقدار A با هم برابر باشند، ویژگی‌ای که مقدار B بزرگ‌تری دارد، ویژگی بیشتری دارد؛ اگر دو مقدار B نیز با هم برابر باشند، ویژگی‌ای که مقدار C بزرگ‌تری دارد، ویژگی بیشتری دارد؛ اگر همه مقادیر با هم برابر باشند، دو ویژگی با هم برابرند.

برای مثال، (1,0,0) نسبت به (0,4,3) ویژگی بالاتری در نظر گرفته می‌شود، زیرا مقدار A در (1,0,0) (که برابر با 1 است) بزرگتر از مقدار A در (0,4,3) (که برابر با 0 است) است.

انتخابگرها بر ویژگی تأثیر می‌گذارند

هر بخش در مثلث اولویت با مقدار 0 شروع می‌شود، بنابراین اولویت پیش‌فرض (0,0,0) است. هر بخش از یک انتخابگر، اولویت را افزایش می‌دهد که بسته به نوع انتخابگر، مقدار A ، B یا C را افزایش می‌دهد.

انتخابگر جهانی

یک انتخابگر جهانی ( * ) هیچ ویژگی خاصی اضافه نمی‌کند و مقدار آن را در سطح ویژگی اولیه (0,0,0) باقی می‌گذارد.

* {
  color: red;
}

انتخابگر عنصر یا شبه عنصر

یک انتخابگر عنصر (نوع) یا شبه عنصر، ویژگی شبه عنصری را اضافه می‌کند که مولفه C را 1 افزایش می‌دهد.

مثال‌های زیر دارای ویژگی کلی (0,0,1) هستند.

انتخابگر نوع

div {
  color: red;
}

انتخابگر شبه عنصر

::selection {
  color: red;
}

انتخابگر کلاس، شبه کلاس یا ویژگی

یک انتخابگر کلاس ، شبه کلاس یا ویژگی ، ویژگی شبه کلاس را اضافه می‌کند که مولفه B را 1 افزایش می‌دهد.

مثال‌های زیر دارای ویژگی (0,1,0) هستند.

انتخابگر کلاس

.my-class {
  color: red;
}

انتخابگر شبه کلاس

:hover {
  color: red;
}

انتخابگر ویژگی

[href='#'] {
  color: red;
}

انتخابگر شناسه

یک انتخابگر شناسه ، ویژگی شبیه به شناسه را اضافه می‌کند که کامپوننت A را ۱ واحد افزایش می‌دهد، البته تا زمانی که از انتخابگر شناسه ( #myID ) استفاده کنید و نه از انتخابگر ویژگی ( [id="myID"] ).

در مثال زیر، میزان اختصاصیت (1,0,0) است.

#myID {
  color: red;
}

انتخابگرهای دیگر

CSS انتخابگرهای زیادی دارد. همه آنها ویژگی اختصاصی بودن را اضافه نمی‌کنند. برای مثال، خود کلاس کاذب :not() چیزی به محاسبه ویژگی اضافه نمی‌کند.

ویژگی شبه کلاس :not() با ویژگی خاص‌ترین انتخابگر در آرگومان انتخابگرهای جدا شده با کاما جایگزین می‌شود؛ و همان ویژگی را ارائه می‌دهد که گویی به صورت :not(:is(argument)) نوشته شده است.

div:not(.my-class) {
  color: red;
}

شبه کلاس :is() نیز خودش به محاسبه‌ی ویژگی اضافه نمی‌کند. مانند :not() ، این کلاس نیز ویژگی خاص‌ترین آرگومان خود را دریافت می‌کند.

:is(h1, h2, h3) {
  color: blue;
}

این نمونه دارای ویژگی (0,0,1) است زیرا فقط یک نوع انتخابگر ( type ) دارد.

با اضافه شدن یک id ، میزان اختصاصی بودن به (1,0,0) افزایش می‌یابد.

:is(h1, h2, h3, #my-heading) {
  color: blue;
}

شبه کلاس :where() متفاوت است. صرف نظر از میزان اختصاصی بودن هر یک از آرگومان‌هایش، همیشه میزان اختصاصی بودن آن (0,0,0) است.

:where(h1, h2, h3, #my-heading) {
  color: blue;
}

استایل‌های با سطح اختصاصیت پایین که با استفاده از :where() اعمال می‌شوند، به شما این امکان را می‌دهند که بعداً در فایل استایل خود، این استایل‌ها را با انتخابگرهای پایه بازنویسی کنید:

:where(#my-content) {
   color: red;
}

p {
   color: blue;
}

اگرچه :where() یک id در لیست آرگومان‌های خود دارد، اما همچنان فقط دارای ویژگی (0, 0, 0) است، بنابراین انتخابگر p پایه آن را لغو می‌کند و متن blue خواهد بود.

درک خود را بررسی کنید

دانش خود را در مورد امتیازدهی اختصاصی بیازمایید

ویژگی a[href="#"] چیست؟

(0,0,1)
ارزش a (0,0,1) است، اما [href="#"] ارزش (0,1,0) را دارد.
(0,1,0)
دوباره امتحان کنید! ارزش a (0,0,1) است، اما [href="#"] ارزش (0,1,0) را دارد.
(0,1,1)
مقدار a برابر با (0,0,1) و مقدار [href="#"] برابر با (0,1,0) است که در مجموع، خصوصیت (0,1,1) را ایجاد می‌کند.

عواملی که بر اختصاصی بودن تأثیر نمی‌گذارند

برخی تصورات غلط رایج در مورد عوامل مؤثر بر اختصاصی بودن وجود دارد که در ادامه به آنها اشاره می‌کنیم.

ویژگی‌های سبک درون‌خطی

CSS که مستقیماً روی ویژگی style یک عنصر اعمال می‌شود، بر میزان اختصاصی بودن آن تأثیری ندارد، زیرا این مرحله در آبشاری که قبل از اختصاصی بودن ارزیابی می‌شود، متفاوت است.

<div style="color: red"></div>

برای لغو این تعریف از درون یک فایل استایل، باید به مرحله‌ی قبل‌تر cascade برای دریافت تعریف win متوسل شوید.

برای مثال، می‌توانید !important به آن اضافه کنید، تا بخشی از مبدا Authored !important شود.

!important

یک !important در انتهای یک تعریف CSS بر خصوصیت (specificity) تأثیر نمی‌گذارد، اما تعریف را در یک مبدأ متفاوت، یعنی Authored !important قرار می‌دهد.

در مثال زیر، خصوصیت .my-class ‎ برای برنده شدن اعلان !important ‎ اهمیتی ندارد.

.my-class {
  color: red !important;
  color: white;
}

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

.branding {
  color: blue !important;
}

button {
  color: red !important;
}

ویژگی در متن

وقتی از یک انتخابگر پیچیده یا مرکب استفاده می‌شود، هر بخش از آن انتخابگر به میزان اختصاصی بودن آن می‌افزاید. به این مثال HTML توجه کنید:

<a class="my-class another-class" href="#">A link</a>

این لینک دو کلاس دارد. قانون CSS زیر دارای ویژگی (0,0,1) است:

a {
  color: red;
}

اگر به یکی از کلاس‌های موجود در انتخابگر ارجاع دهید، اکنون دارای ویژگی (0,1,1) است:

a.my-class {
  color: green;
}

کلاس دیگر را به انتخابگر اضافه کنید، اکنون دارای ویژگی (0,2,1) است:

a.my-class.another-class {
  color: rebeccapurple;
}

ویژگی href را به انتخابگر اضافه کنید، اکنون دارای ویژگی (0,3,1) است:

a.my-class.another-class[href] {
  color: goldenrod;
}

در نهایت، یک شبه کلاس :hover به همه اینها اضافه کنید، انتخابگر با ویژگی (0,4,1) به پایان می‌رسد:

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

درک خود را بررسی کنید

دانش خود را در مورد امتیازدهی اختصاصی بیازمایید

کدام یک از انتخابگرهای زیر دارای ویژگی (0,2,1) است؟

article > section
عناصر، ویژگی خاص عنصر مانند (مولفه `C`) را اضافه می‌کنند. دو عنصر در انتخابگر وجود دارد که باعث می‌شود ویژگی خاص (0,0,2) داشته باشد.
article.card.dark
عناصر، ویژگی خاص عنصر مانند (مولفه `C`) و کلاس‌ها ویژگی خاص کلاس مانند (مولفه `B`) را اضافه می‌کنند. با 2 کلاس و 1 عنصر، این باعث می‌شود که این انتخابگر ویژگی خاص (0,2,1) داشته باشد.
article:hover a[href]
عناصر، ویژگی خاص (specificity) شبیه به عنصر (مولفه `C`) را اضافه می‌کنند، شبه کلاس‌ها و ویژگی‌ها، ویژگی خاص شبیه به کلاس (مولفه `B`) را اضافه می‌کنند. دو انتخابگر عنصر (2 × (0,0,1) )، یک انتخابگر ویژگی (value (0,1,0) ) و یک انتخابگر کلاس (value (0,1,0) ) وجود دارد. این باعث می‌شود که این انتخابگر، ویژگی خاص (0,2,2) را داشته باشد.

افزایش عملی اختصاصی بودن

فرض کنید CSS ای دارید که به این شکل است:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

با HTML که به این شکل است:

<button class="my-button" onclick="alert('hello')">Click me</button>

دکمه دارای پس‌زمینه خاکستری است، زیرا انتخابگر دوم دارای ویژگی (0,1,1) است. این به این دلیل است که یک انتخابگر نوع ( button ) دارد که (0,0,1) است و یک انتخابگر ویژگی ( [onclick] ) دارد که (0,1,0) است.

قانون قبلی .my-button - برابر با (0,1,0) است زیرا یک انتخابگر کلاس دارد که سطح خصوصیت پایین‌تری نسبت به (0,1,1) دارد.

اگر می‌خواهید این قانون را تقویت کنید، می‌توانید انتخابگر کلاس را به این صورت تکرار کنید:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

اکنون، دکمه دارای پس‌زمینه آبی خواهد بود، زیرا انتخابگر جدید دارای ویژگی (0,2,0) است.

تساوی در ویژگی به مرحله بعدی در آبشار برمی‌گردد.

فعلاً با مثال دکمه ادامه می‌دهیم، CSS را به این تغییر می‌دهیم:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

دکمه دارای پس‌زمینه خاکستری است، زیرا هر دو انتخابگر دارای ویژگی یکسان (0,1,0) هستند.

اگر قوانین را به ترتیب منبع تغییر دهید، دکمه آبی خواهد شد.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

دلیل این امر این است که هر دو انتخابگر دارای ویژگی یکسانی هستند. در این حالت، آبشار به مرحله ترتیب ظاهر شدن برمی‌گردد.

منابع