বিশেষত্ব

সিএসএস পডকাস্ট - ০০৩: সুনির্দিষ্টতা

ধরা যাক, আপনি নিম্নলিখিত 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) দেখানো একটি ডায়াগ্রাম। প্রতিটি উপাদানের জন্য, ডায়াগ্রামটিতে দেখানো হয়েছে সেটি কী নির্দেশ করে এবং সেটিকে প্রভাবিত করে এমন কিছু উদাহরণমূলক সিলেক্টর।
একটি চিত্র যা প্রদর্শন করে যে নির্দিষ্টতার কোন কোন উপাদানকে বিভিন্ন নির্বাচক প্রভাবিত করে।

নির্দিষ্টতাগুলির তুলনা কীভাবে করবেন

নির্দিষ্টতা তুলনা করার জন্য তিনটি উপাদানকে ক্রমানুসারে তুলনা করা হয়: যে নির্দিষ্টতার A মান বেশি, সেটি অধিক সুনির্দিষ্ট; যদি দুটি A মান সমান হয়, তবে যে নির্দিষ্টতার B মান বেশি, সেটি অধিক সুনির্দিষ্ট; যদি দুটি B মানও সমান হয়, তবে যে নির্দিষ্টতার C মান বেশি, সেটি অধিক সুনির্দিষ্ট; যদি সব মান সমান হয়, তবে দুটি নির্দিষ্টতা সমান।

উদাহরণস্বরূপ, (1,0,0) কে (0,4,3) এর চেয়ে উচ্চতর স্পেসিফিসিটি হিসেবে বিবেচনা করা হয় কারণ (1,0,0) এর A মান (যা 1 ) (0,4,3) এর A মানের (যা 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)

যে বিষয়গুলো নির্দিষ্টতাকে প্রভাবিত করে না

নির্দিষ্টতাকে প্রভাবিত করে এমন নিম্নলিখিত বিষয়গুলো সম্পর্কে কিছু সাধারণ ভুল ধারণা রয়েছে।

ইনলাইন স্টাইল অ্যাট্রিবিউট

কোনো এলিমেন্টের style অ্যাট্রিবিউটে সরাসরি প্রয়োগ করা CSS, স্পেসিফিসিটিকে প্রভাবিত করে না, কারণ এটি ক্যাসকেডের একটি ভিন্ন ধাপ যা স্পেসিফিসিটির আগে মূল্যায়ন করা হয়।

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

একটি স্টাইল শীটের ভেতর থেকে এই ডিক্লারেশনটিকে ওভাররাইড করার জন্য, আপনাকে ক্যাসকেডের আগের কোনো ধাপে ডিক্লারেশনটিকে কার্যকর করতে হবে।

উদাহরণস্বরূপ, আপনি এতে !important যোগ করতে পারেন, যাতে এটি Authored !important origin- এর অংশ হয়ে যায়।

!important ঘোষণা

একটি CSS ডিক্লারেশনের শেষে !important করলে তা স্পেসিফিসিটিকে প্রভাবিত করে না, কিন্তু ডিক্লারেশনটিকে একটি ভিন্ন অরিজিনে , অর্থাৎ Authored !important , স্থাপন করে।

নিম্নলিখিত উদাহরণে, !important ডিক্লারেশনটি কার্যকর হওয়ার জন্য .my-class এর স্পেসিফিসিটি প্রাসঙ্গিক নয়।

.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` কম্পোনেন্ট) যোগ করে। ২টি ক্লাস এবং ১টি এলিমেন্ট থাকায়, এই সিলেক্টরটির স্পেসিফিসিটি হয় (0,2,1)
article:hover a[href]
এলিমেন্টগুলো এলিমেন্টের মতো স্পেসিফিসিটি (`C` কম্পোনেন্ট) যোগ করে, সিউডো-ক্লাস এবং অ্যাট্রিবিউটগুলো ক্লাসের মতো স্পেসিফিসিটি (`B` কম্পোনেন্ট) যোগ করে। এখানে ২টি এলিমেন্ট সিলেক্টর (২ × (0,0,1) ), একটি অ্যাট্রিবিউট সিলেক্টর (যার মান (0,1,0) ), এবং একটি ক্লাস সিলেক্টর (যার মান (0,1,0) ) রয়েছে। এর ফলে এই সিলেক্টরটির মোট স্পেসিফিসিটি হয় (0,2,2)

বাস্তবিকভাবে নির্দিষ্টতা বৃদ্ধি করা

ধরুন আপনার কিছু CSS কোড আছে যা দেখতে এইরকম:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

এইচটিএমএলটি দেখতে এইরকম:

<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;
}

এর কারণ হলো, উভয় সিলেক্টরের স্পেসিফিসিটি একই। এক্ষেত্রে, ক্যাসকেডটি উপস্থিতির ক্রম ধাপটিতে ফিরে যায়।

সম্পদ