CSS @scope at-rule দিয়ে আপনার নির্বাচকদের নাগাল সীমিত করুন, CSS @scope at-রুল দিয়ে আপনার নির্বাচকদের নাগাল সীমিত করুন

শুধুমাত্র আপনার DOM-এর একটি সীমিত সাবট্রির মধ্যে উপাদান নির্বাচন করতে @scope কীভাবে ব্যবহার করবেন তা শিখুন।

ব্রাউজার সমর্থন

  • ক্রোম: 118।
  • প্রান্ত: 118।
  • ফায়ারফক্স: একটি পতাকার পিছনে।
  • সাফারি: 17.4.

উৎস

সিএসএস নির্বাচকদের লেখার সূক্ষ্ম শিল্প

নির্বাচকদের লেখার সময় আপনি নিজেকে দুটি জগতের মধ্যে বিচ্ছিন্ন দেখতে পাবেন। একদিকে আপনি কোন উপাদানগুলি নির্বাচন করবেন সে সম্পর্কে আপনি সুনির্দিষ্ট হতে চান। অন্যদিকে, আপনি চান আপনার নির্বাচকরা যাতে সহজে ওভাররাইড করতে পারে এবং DOM কাঠামোর সাথে শক্তভাবে সংযুক্ত না হয়।

উদাহরণস্বরূপ, আপনি যখন "কার্ড উপাদানের বিষয়বস্তু এলাকায় হিরো ইমেজ" নির্বাচন করতে চান - যা একটি বরং নির্দিষ্ট উপাদান নির্বাচন - আপনি সম্ভবত .card > .content > img.hero

  • এই নির্বাচকের (0,3,1) এর বেশ উচ্চ নির্দিষ্টতা রয়েছে যা আপনার কোড বাড়ার সাথে সাথে ওভাররাইড করা কঠিন করে তোলে।
  • সরাসরি চাইল্ড কম্বিনেটরের উপর নির্ভর করে এটি শক্তভাবে DOM কাঠামোর সাথে মিলিত হয়। মার্কআপ কখনও পরিবর্তন করা উচিত, আপনাকে আপনার CSSও পরিবর্তন করতে হবে।

কিন্তু, আপনি সেই উপাদানটির নির্বাচক হিসাবে শুধু img লিখতে চান না, কারণ এটি আপনার পৃষ্ঠা জুড়ে সমস্ত চিত্র উপাদান নির্বাচন করবে।

এর মধ্যে সঠিক ভারসাম্য খুঁজে পাওয়া প্রায়ই বেশ চ্যালেঞ্জ। বছরের পর বছর ধরে, কিছু বিকাশকারী এই ধরনের পরিস্থিতিতে আপনাকে সাহায্য করার জন্য সমাধান এবং সমাধান নিয়ে এসেছে। যেমন:

  • BEM-এর মতো পদ্ধতিগুলি নির্দেশ করে যে আপনি সেই উপাদানটিকে একটি শ্রেণী দেন card__img card__img--hero নির্দিষ্টতা কম রাখতে যখন আপনি যা নির্বাচন করেন তাতে আপনাকে নির্দিষ্ট হতে দেয়।
  • জাভাস্ক্রিপ্ট-ভিত্তিক সমাধান যেমন স্কোপড সিএসএস বা স্টাইলড কম্পোনেন্টস আপনার পৃষ্ঠার অন্য পাশের উপাদানগুলিকে লক্ষ্যবস্তু করা থেকে বিরত রাখতে আপনার নির্বাচকদের সাথে এলোমেলোভাবে জেনারেট করা স্ট্রিংগুলি-যেমন sc-596d7e0e-4 যোগ করে আপনার সমস্ত নির্বাচককে পুনর্লিখন করে।
  • কিছু লাইব্রেরি এমনকি নির্বাচকদের সম্পূর্ণভাবে বাতিল করে দেয় এবং আপনাকে স্টাইলিং ট্রিগারগুলিকে সরাসরি মার্কআপে রাখতে হয়।

কিন্তু আপনি যদি তাদের কোনো প্রয়োজন না হয়? সিএসএস যদি আপনাকে উচ্চ নির্দিষ্টতার নির্বাচক বা আপনার DOM-এর সাথে শক্তভাবে সংযুক্ত করা হয় এমন নির্বাচকদের লেখার প্রয়োজন না করে আপনি কোন উপাদানগুলি নির্বাচন করেন সে সম্পর্কে উভয়ই সুনির্দিষ্ট হওয়ার একটি উপায় দেয়? ঠিক আছে, এখানেই @scope কার্যকর হয়, যা আপনাকে শুধুমাত্র আপনার DOM-এর একটি সাবট্রির মধ্যে উপাদান নির্বাচন করার উপায় প্রদান করে।

@স্কোপ পেশ করা হচ্ছে

@scope সাহায্যে আপনি আপনার নির্বাচকদের নাগাল সীমিত করতে পারেন। আপনি স্কোপিং রুট সেট করে এটি করেন যা আপনি লক্ষ্য করতে চান এমন সাবট্রির উপরের সীমানা নির্ধারণ করে। একটি স্কোপিং রুট সেটের সাথে, ধারণকৃত শৈলী নিয়ম - নাম স্কোপড শৈলী নিয়ম - শুধুমাত্র DOM-এর সেই সীমিত সাবট্রি থেকে নির্বাচন করতে পারে।

উদাহরণস্বরূপ, .card কম্পোনেন্টে শুধুমাত্র <img> উপাদানগুলিকে লক্ষ্য করতে, আপনি @scope at-rule-এর স্কোপিং রুট হিসাবে .card সেট করেছেন।

@scope (.card) {
    img {
        border-color: green;
    }
}

স্কোপড স্টাইল নিয়ম img { … } কার্যকরভাবে শুধুমাত্র <img> উপাদানগুলিকে নির্বাচন করতে পারে যা মিলিত .card উপাদানের সুযোগে রয়েছে।

কার্ডের বিষয়বস্তু এলাকার ভিতরের <img> উপাদানগুলিকে ( .card__content ) নির্বাচন করা থেকে আটকাতে আপনি img নির্বাচককে আরও নির্দিষ্ট করতে পারেন। এটি করার আরেকটি উপায় হল এই সত্যটি ব্যবহার করা যে @scope at-rule এছাড়াও একটি স্কোপিং সীমা গ্রহণ করে যা নিম্ন সীমানা নির্ধারণ করে।

@scope (.card) to (.card__content) {
    img {
        border-color: green;
    }
}

এই স্কোপড শৈলী নিয়মটি শুধুমাত্র <img> উপাদানগুলিকে লক্ষ্য করে যা পূর্বপুরুষ ট্রিতে .card এবং .card__content উপাদানগুলির মধ্যে স্থাপন করা হয়। এই ধরনের স্কোপিং - একটি উপরের এবং নিম্ন সীমানা সহ - প্রায়ই একটি ডোনাট স্কোপ হিসাবে উল্লেখ করা হয়

:scope নির্বাচক

ডিফল্টরূপে, সমস্ত স্কোপযুক্ত শৈলী নিয়মগুলি স্কোপিং রুটের সাথে সম্পর্কিত। স্কোপিং রুট উপাদান নিজেই লক্ষ্য করা সম্ভব। এর জন্য :scope নির্বাচক ব্যবহার করুন।

@scope (.card) {
    :scope {
        /* Selects the matched .card itself */
    }
    img {
       /* Selects img elements that are a child of .card */
    }
}

স্কোপড শৈলী নিয়মের মধ্যে নির্বাচকরা অন্তর্নিহিতভাবে পাবেন :scope প্রিপেন্ডেড। আপনি যদি চান, আপনি নিজেকে প্রিপেন্ড করে :scope মাধ্যমে এটি সম্পর্কে স্পষ্ট হতে পারেন। বিকল্পভাবে আপনি CSS নেস্টিং থেকে & নির্বাচককে প্রিপেন্ড করতে পারেন।

@scope (.card) {
    img {
       /* Selects img elements that are a child of .card */
    }
    :scope img {
        /* Also selects img elements that are a child of .card */
    }
    & img {
        /* Also selects img elements that are a child of .card */
    }
}

একটি স্কোপিং সীমা :scope সিউডো-ক্লাস ব্যবহার করতে পারে স্কোপিং রুটের সাথে একটি নির্দিষ্ট সম্পর্ক প্রয়োজন:

/* .content is only a limit when it is a direct child of the :scope */
@scope (.media-object) to (:scope > .content) { ... }

একটি স্কোপিং সীমা :scope ব্যবহার করে তাদের স্কোপিং রুটের বাইরের উপাদানগুলিকে উল্লেখ করতে পারে। যেমন:

/* .content is only a limit when the :scope is inside .sidebar */
@scope (.media-object) to (.sidebar :scope .content) { ... }

নোট করুন যে স্কোপড শৈলী নিয়মগুলি নিজেই সাবট্রি থেকে এড়াতে পারে না। :scope + p এর মতো নির্বাচনগুলি অবৈধ কারণ এটি সুযোগের মধ্যে নেই এমন উপাদানগুলি নির্বাচন করার চেষ্টা করে।

@scope এবং নির্দিষ্টতা

আপনি @scope এর প্রস্তাবনায় যে নির্বাচকগুলি ব্যবহার করেন তা অন্তর্ভুক্ত নির্বাচকদের নির্দিষ্টতাকে প্রভাবিত করে না। নীচের উদাহরণে, img নির্বাচকের নির্দিষ্টতা এখনও (0,0,1)

@scope (#sidebar) {
    img { /* Specificity = (0,0,1) */
        …
    }
}

:scope নির্দিষ্টতা হল একটি নিয়মিত ছদ্ম-শ্রেণীর, যথা (0,1,0)

@scope (#sidebar) {
    :scope img { /* Specificity = (0,1,0) + (0,0,1) = (0,1,1) */
        …
    }
}

নিম্নলিখিত উদাহরণে, অভ্যন্তরীণভাবে, & সিলেক্টরে পুনরায় লেখা হয় যা স্কোপিং রুটের জন্য ব্যবহৃত হয়, একটি :is() নির্বাচকের ভিতরে মোড়ানো। শেষ পর্যন্ত, ব্রাউজারটি ম্যাচিং করার জন্য নির্বাচক হিসেবে :is(#sidebar, .card) img ব্যবহার করবে। এই প্রক্রিয়াটি ডিসুগারিং নামে পরিচিত।

@scope (#sidebar, .card) {
    & img { /* desugars to `:is(#sidebar, .card) img` */
        …
    }
}

কারণ & :is() ব্যবহার করে desugared হয়, & এর নির্দিষ্টতা গণনা করা হয় :is() নির্দিষ্টতা নিয়ম অনুসরণ করে: & এর নির্দিষ্টতা হল এটির সবচেয়ে নির্দিষ্ট যুক্তি।

এই উদাহরণে প্রযোজ্য, :is(#sidebar, .card) এর নির্দিষ্টতা হল এটির সবচেয়ে নির্দিষ্ট আর্গুমেন্ট, যথা #sidebar , এবং তাই হয়ে যায় (1,0,0) । এটিকে img এর নির্দিষ্টতার সাথে একত্রিত করুন -যা (0,0,1) -এবং আপনি সম্পূর্ণ জটিল নির্বাচকের নির্দিষ্টতা হিসাবে (1,0,1) দিয়ে শেষ করবেন।

@scope (#sidebar, .card) {
    & img { /* Specificity = (1,0,0) + (0,0,1) = (1,0,1) */
        …
    }
}

:scope & ভিতরে @scope মধ্যে পার্থক্য

কীভাবে নির্দিষ্টতা গণনা করা হয় তার পার্থক্য ছাড়াও, :scope এবং & এর মধ্যে আরেকটি পার্থক্য হল :scope মিলিত স্কোপিং রুটকে প্রতিনিধিত্ব করে, যেখানে & স্কোপিং রুটের সাথে মেলে নির্বাচককে প্রতিনিধিত্ব করে।

এই কারণে, এটি একাধিকবার ব্যবহার করা সম্ভব & এটি :scope এর বিপরীতে যা আপনি শুধুমাত্র একবার ব্যবহার করতে পারেন, কারণ আপনি একটি স্কোপিং রুটের ভিতরে একটি স্কোপিং রুট মেলে না।

@scope (.card) {
  & & { /* Selects a `.card` in the matched root .card */
  }
  :scope :scope { /* ❌ Does not work */
    …
  }
}

প্রিলুড-কম সুযোগ

<style> উপাদান দিয়ে ইনলাইন শৈলী লেখার সময়, আপনি কোনো স্কোপিং রুট উল্লেখ না করে <style> উপাদানের এনক্লোসিং প্যারেন্ট এলিমেন্টে শৈলীর নিয়মগুলিকে স্কোপ করতে পারেন। আপনি @scope এর প্রস্তাবনা বাদ দিয়ে এটি করেন।

<div class="card">
  <div class="card__header">
    <style>
      @scope {
        img {
          border-color: green;
        }
      }
    </style>
    <h1>Card Title</h1>
    <img src="…" height="32" class="hero">
  </div>
  <div class="card__content">
    <p><img src="…" height="32"></p>
  </div>
</div>

উপরের উদাহরণে, স্কোপ করা নিয়মগুলি শুধুমাত্র div ভিতরের উপাদানগুলিকে ক্লাস নাম card__header দিয়ে লক্ষ্য করে, কারণ সেই div হল <style> উপাদানের মূল উপাদান।

ক্যাসকেডে @স্কোপ

CSS ক্যাসকেডের ভিতরে, @scope একটি নতুন মানদণ্ড যোগ করে: স্কোপিং প্রক্সিমিটি । পদক্ষেপটি নির্দিষ্টতার পরে আসে তবে উপস্থিতির আদেশের আগে।

CSS ক্যাসকেডের ভিজ্যুয়ালাইজেশন।

স্পেসিফিকেশন অনুযায়ী :

বিভিন্ন স্কোপিং রুটের সাথে শৈলীর নিয়মে প্রদর্শিত ঘোষণার তুলনা করার সময়, স্কোপিং রুট এবং স্কোপিং শৈলী নিয়ম বিষয়ের মধ্যে সবচেয়ে কম প্রজন্মের বা সহোদর-উপাদান সহ ঘোষণাটি জয়ী হয়।

এই নতুন পদক্ষেপটি কাজে আসে যখন একটি উপাদানের বিভিন্ন বৈচিত্র বাসা বাঁধে। এই উদাহরণটি নিন, এটি এখনও @scope ব্যবহার করে না:

<style>
    .light { background: #ccc; }
    .dark  { background: #333; }
    .light a { color: black; }
    .dark a { color: white; }
</style>
<div class="light">
    <p><a href="#">What color am I?</a></p>
    <div class="dark">
        <p><a href="#">What about me?</a></p>
        <div class="light">
            <p><a href="#">Am I the same as the first?</a></p>
        </div>
    </div>
</div>

সেই সামান্য মার্কআপটি দেখার সময়, তৃতীয় লিঙ্কটি black পরিবর্তে white হবে, যদিও এটি ক্লাস .light এর সাথে একটি div সন্তান। এটি উপস্থিতির মানদণ্ডের ক্রম অনুসারে যা ক্যাসকেড এখানে বিজয়ী নির্ধারণ করতে ব্যবহার করে। এটা দেখে যে .dark a সর্বশেষ ঘোষণা করা হয়েছে, তাই এটি .light a নিয়ম থেকে জিতবে

স্কোপিং প্রক্সিমিটি মানদণ্ডের সাথে এটি এখন সমাধান করা হয়েছে:

@scope (.light) {
    :scope { background: #ccc; }
    a { color: black;}
}

@scope (.dark) {
    :scope { background: #333; }
    a { color: white; }
}

যেহেতু উভয় স্কোপড a একই নির্দিষ্টতা রয়েছে, তাই স্কোপিং প্রক্সিমিটি মাপকাঠি কাজ শুরু করে। এটি উভয় নির্বাচককে তাদের স্কোপিং রুটের নিকটবর্তী করে ওজন করে। যে তৃতীয় a উপাদানের জন্য, এটি .light স্কোপিং মূলের জন্য শুধুমাত্র একটি হপ কিন্তু .dark জন্য দুটি। তাই .light a নির্বাচক জিতবেন।

সমাপ্তি নোট: নির্বাচক বিচ্ছিন্নতা, শৈলী বিচ্ছিন্নতা নয়

একটি গুরুত্বপূর্ণ নোট তৈরি করা হল যে @scope নির্বাচকদের নাগালের সীমাবদ্ধ করে, এটি শৈলী বিচ্ছিন্নতা অফার করে না। সন্তানদের কাছে উত্তরাধিকারসূত্রে পাওয়া বৈশিষ্ট্যগুলি @scope নিম্ন সীমার বাইরেও উত্তরাধিকারী হবে। যেমন একটি সম্পত্তি color এক. ডোনাট স্কোপের ভিতরের একটিকে ঘোষণা করার সময়, color এখনও ডোনাটের গর্তের ভিতরে শিশুদের কাছে উত্তরাধিকারসূত্রে পাওয়া যাবে।

@scope (.card) to (.card__content) {
  :scope {
    color: hotpink;
  }
}

উপরের উদাহরণে, .card__content উপাদান এবং এর বাচ্চাদের একটি hotpink রঙ রয়েছে কারণ তারা .card থেকে মানটি উত্তরাধিকার সূত্রে পেয়েছে।

( আনস্প্ল্যাশে রুস্তম বুরখানভের কভার ফটো)