CSSNestedDeclarations এর সাথে CSS নেস্টিং উন্নত হয়, CSSNestedDeclarations এর সাথে CSS নেস্টিং উন্নত হয়

প্রকাশিত: অক্টোবর 8, 2024

CSS নেস্টিং-এর সাথে কিছু অদ্ভুত বিকৃতি ঠিক করতে, CSS ওয়ার্কিং গ্রুপ CSS নেস্টিং স্পেসিফিকেশনে CSSNestedDeclarations ইন্টারফেস যোগ করার সিদ্ধান্ত নিয়েছে। এই সংযোজনের সাথে, কিছু অন্যান্য উন্নতির মধ্যে শৈলীর নিয়মের পরে আসা ঘোষণাগুলি আর স্থানান্তরিত হয় না।

এই পরিবর্তনগুলি 130 সংস্করণ থেকে Chrome-এ উপলব্ধ এবং Firefox Nightly 132 এবং Safari Technology Preview 204-এ পরীক্ষার জন্য প্রস্তুত৷

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

  • ক্রোম: 130।
  • প্রান্ত: 130।
  • ফায়ারফক্স: 132।
  • সাফারি: সমর্থিত নয়।

CSSNestedDeclarations ছাড়া CSS নেস্টিংয়ের সমস্যা

CSS নেস্টিংয়ের সাথে একটি গোটচা হল যে, প্রাথমিকভাবে, নিম্নলিখিত স্নিপেটটি কাজ করে না যেমন আপনি প্রাথমিকভাবে আশা করতে পারেন:

.foo {
    width: fit-content;

    @media screen {
        background-color: red;
    }
    
    background-color: green;
}

কোডটি দেখে, আপনি অনুমান করবেন যে <div class=foo> উপাদানটির একটি green background-color রয়েছে কারণ background-color: green; ঘোষণা শেষ আসে। কিন্তু 130 সংস্করণের আগে Chrome-এর ক্ষেত্রে এটি ছিল না। যে সংস্করণগুলিতে CSSNestedDeclarations এর জন্য সমর্থন নেই, উপাদানটির background-color red

130টি ব্যবহারের পূর্বে Chrome এর প্রকৃত নিয়ম পার্স করার পর নিম্নরূপ:

.foo {
    width: fit-content;
    background-color: green;

    @media screen {
        & {
            background-color: red;
        }
    }
}

পার্স করার পরে CSS দুটি পরিবর্তন করেছে:

  • background-color: green; অন্য দুটি ঘোষণায় যোগদানের জন্য স্থানান্তরিত হয়েছে।
  • নেস্টেড CSSMediaRule & সিলেক্টর ব্যবহার করে একটি অতিরিক্ত CSSStyleRule এ ঘোষণা মোড়ানোর জন্য পুনরায় লেখা হয়েছে।

আরেকটি সাধারণ পরিবর্তন যা আপনি এখানে দেখতে পাবেন তা হল পার্সার বাতিল করার বৈশিষ্ট্য যা এটি সমর্থন করে না।

আপনি CSSStyleRule থেকে cssText পড়ে নিজের জন্য "পার্সিংয়ের পরে CSS" পরিদর্শন করতে পারেন।

এই ইন্টারেক্টিভ খেলার মাঠে নিজেকে চেষ্টা করে দেখুন:

কেন এই CSS পুনরায় লেখা হয়?

কেন এই অভ্যন্তরীণ পুনর্লিখন হয়েছে তা বোঝার জন্য, আপনাকে বুঝতে হবে কিভাবে এই CSSStyleRule CSS অবজেক্ট মডেলে (CSSOM) উপস্থাপন করা হয়।

130-এর আগে Chrome-এ, আগে ভাগ করা CSS স্নিপেট নিম্নলিখিতগুলিকে সিরিয়ালাইজ করে:

↳ CSSStyleRule
  .type = STYLE_RULE
  .selectorText = ".foo"
  .resolvedSelectorText = ".foo"
  .specificity = "(0,1,0)"
  .style (CSSStyleDeclaration, 2) =
    - width: fit-content
    - background-color: green
  .cssRules (CSSRuleList, 1) =
    ↳ CSSMediaRule
    .type = MEDIA_RULE
    .cssRules (CSSRuleList, 1) =
      ↳ CSSStyleRule
        .type = STYLE_RULE
        .selectorText = "&"
        .resolvedSelectorText = ":is(.foo)"
        .specificity = "(0,1,0)"
        .style (CSSStyleDeclaration, 1) =
          - background-color: red

একটি CSSStyleRule এর সমস্ত বৈশিষ্ট্যগুলির মধ্যে নিম্নলিখিত দুটি এই ক্ষেত্রে প্রাসঙ্গিক:

  • style সম্পত্তি যা একটি CSSStyleDeclaration উদাহরণ যা ঘোষণার প্রতিনিধিত্ব করে।
  • cssRules বৈশিষ্ট্য যা একটি CSSRuleList যা সমস্ত নেস্টেড CSSRule অবজেক্ট ধারণ করে।

যেহেতু CSS স্নিপেট থেকে সমস্ত ঘোষণা CSStyleRule এর style সম্পত্তিতে শেষ হয়, তাই তথ্যের ক্ষতি হয়। style সম্পত্তির দিকে তাকালে এটি স্পষ্ট নয় যে background-color: green নেস্টেড CSSMediaRule পরে ঘোষণা করা হয়েছিল।

↳ CSSStyleRule
  .type = STYLE_RULE
  .selectorText = ".foo"
  .style (CSSStyleDeclaration, 2) =
    - width: fit-content
    - background-color: green
  .cssRules (CSSRuleList, 1) =
    ↳ …

এটি সমস্যাযুক্ত, কারণ একটি সিএসএস ইঞ্জিন সঠিকভাবে কাজ করার জন্য এটি অবশ্যই একটি স্টাইল নিয়মের বিষয়বস্তুর শুরুতে প্রদর্শিত বৈশিষ্ট্যগুলিকে আলাদা করতে সক্ষম হতে হবে যা অন্যান্য নিয়মগুলির সাথে ছেদযুক্ত প্রদর্শিত হয়৷

CSSMediaRule অভ্যন্তরে ঘোষণাগুলি হঠাৎ করে একটি CSSStyleRule এ মোড়ানো: এর কারণ হল CSSMediaRule ঘোষণা ধারণ করার জন্য ডিজাইন করা হয়নি।

কারণ CSSMediaRule নেস্টেড নিয়ম ধারণ করতে পারে-এর cssRules প্রপার্টির মাধ্যমে অ্যাক্সেসযোগ্য-ঘোষণাগুলি স্বয়ংক্রিয়ভাবে একটি CSSStyleRule এ মোড়ানো হয়।

↳ CSSMediaRule
  .type = MEDIA_RULE
  .cssRules (CSSRuleList, 1) =
    ↳ CSSStyleRule
      .type = STYLE_RULE
      .selectorText = "&"
      .resolvedSelectorText = ":is(.foo)"
      .specificity = "(0,1,0)"
      .style (CSSStyleDeclaration, 1) =
        - background-color: red

কিভাবে এই সমাধান?

CSS ওয়ার্কিং গ্রুপ এই সমস্যা সমাধানের জন্য বিভিন্ন বিকল্পের দিকে নজর দিয়েছে।

প্রস্তাবিত সমাধানগুলির মধ্যে একটি হল নেস্টিং নির্বাচক ( & ) দিয়ে নেস্টেড CSSStyleRule এ সমস্ত বেয়ার ঘোষণাগুলি মোড়ানো। এই ধারণাটি বিভিন্ন কারণে বাতিল করা হয়েছিল, যার মধ্যে নিম্নলিখিত অবাঞ্ছিত পার্শ্ব-প্রতিক্রিয়া & ডিসুগারিং :is(…) :

  • এটি নির্দিষ্টতার উপর প্রভাব ফেলে। এর কারণ :is() তার সবচেয়ে নির্দিষ্ট আর্গুমেন্টের নির্দিষ্টতা দখল করে।
  • এটি মূল বাইরের নির্বাচকের ছদ্ম-উপাদানগুলির সাথে ভাল কাজ করে না। কারণ :is() তার নির্বাচক তালিকা আর্গুমেন্টে ছদ্ম-উপাদান গ্রহণ করে না।

নিম্নলিখিত উদাহরণ নিন:

#foo, .foo, .foo::before {
  width: fit-content;
  background-color: red;

  @media screen {
    background-color: green;
  }
}

স্নিপেট পার্স করার পরে 130 এর আগে Chrome এ এটি হয়ে যায়:

#foo,
.foo,
.foo::before {
  width: fit-content;
  background-color: red;

  @media screen {
    & {
      background-color: green;
    }
  }
}

এটি একটি সমস্যা কারণ & নির্বাচক সহ নেস্টেড CSSRule :

  • নিচের দিকে সমতল করে :is(#foo, .foo) , পথ ধরে নির্বাচক তালিকা থেকে .foo::before ছুঁড়ে ফেলে।
  • (1,0,0) এর একটি নির্দিষ্টতা রয়েছে যা পরবর্তীতে ওভাররাইট করা কঠিন করে তোলে।

আপনি নিয়মটি কী সিরিয়ালাইজ করে তা পরিদর্শন করে এটি পরীক্ষা করতে পারেন:

↳ CSSStyleRule
  .type = STYLE_RULE
  .selectorText = "#foo, .foo, .foo::before"
  .resolvedSelectorText = "#foo, .foo, .foo::before"
  .specificity = (1,0,0),(0,1,0),(0,1,1)
  .style (CSSStyleDeclaration, 2) =
    - width: fit-content
    - background-color: red
  .cssRules (CSSRuleList, 1) =
    ↳ CSSMediaRule
      .type = MEDIA_RULE
      .cssRules (CSSRuleList, 1) =
        ↳ CSSStyleRule
          .type = STYLE_RULE
          .selectorText = "&"
          .resolvedSelectorText = ":is(#foo, .foo, .foo::before)"
          .specificity = (1,0,0)
          .style (CSSStyleDeclaration, 1) =
            - background-color: green

দৃশ্যত এর মানে হল .foo::before এর background-color green বদলে red

CSS ওয়ার্কিং গ্রুপ আরেকটি পদ্ধতির দিকে তাকিয়েছিল যেটি হল আপনি সমস্ত নেস্টেড ঘোষণাকে একটি @nest নিয়মে মোড়ানো। রিগ্রেসড ডেভেলপার অভিজ্ঞতার কারণে এটি বাতিল করা হয়েছে।

CSSNestedDeclarations ইন্টারফেস প্রবর্তন করা হচ্ছে

সিএসএস ওয়ার্কিং গ্রুপের সমাধান হল নেস্টেড ঘোষণার নিয়মের প্রবর্তন।

এই নেস্টেড ঘোষণার নিয়ম Chrome 130 থেকে শুরু করে Chrome-এ প্রয়োগ করা হয়।

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

  • ক্রোম: 130।
  • প্রান্ত: 130।
  • ফায়ারফক্স: 132।
  • সাফারি: সমর্থিত নয়।

নেস্টেড ঘোষণার নিয়মের প্রবর্তন CSS পার্সারকে স্বয়ংক্রিয়ভাবে একটি CSSNestedDeclarations উদাহরণে পরপর সরাসরি-নেস্টেড ঘোষণাগুলিকে মোড়ানোর জন্য পরিবর্তন করে। সিরিয়ালাইজ করা হলে, এই CSSNestedDeclarations উদাহরণটি CSSStyleRule এর cssRules প্রপার্টিতে শেষ হয়।

নিম্নলিখিত CSSStyleRule আবার একটি উদাহরণ হিসাবে গ্রহণ করা:

.foo {
  width: fit-content;

  @media screen {
    background-color: red;
  }
    
  background-color: green;
}

যখন ক্রোম 130 বা তার নতুন সংস্করণে সিরিয়ালাইজ করা হয়, তখন এটি এইরকম দেখায়:

↳ CSSStyleRule
  .type = STYLE_RULE
  .selectorText = ".foo"
  .resolvedSelectorText = ".foo"
  .specificity = (0,1,0)
  .style (CSSStyleDeclaration, 1) =
    - width: fit-content
  .cssRules (CSSRuleList, 2) =
    ↳ CSSMediaRule
      .type = MEDIA_RULE
      .cssRules (CSSRuleList, 1) =
        ↳ CSSNestedDeclarations
          .style (CSSStyleDeclaration, 1) =
            - background-color: red
    ↳ CSSNestedDeclarations
      .style (CSSStyleDeclaration, 1) =
        - background-color: green

যেহেতু CSSNestedDeclarations নিয়মটি CSSRuleList এ শেষ হয়, পার্সার background-color: green ঘোষণা: background-color: red পরে : লাল ঘোষণা (যা CSSMediaRule এর অংশ)।

উপরন্তু, একটি CSSNestedDeclarations দৃষ্টান্ত থাকা অন্য কোন খারাপ পার্শ্ব-প্রতিক্রিয়ার পরিচয় দেয় না, যা এখন বাতিল করা হয়েছে, সম্ভাব্য সমাধান সৃষ্ট: নেস্টেড ঘোষণার নিয়মটি একই নির্দিষ্টতার সাথে এর মূল শৈলীর নিয়ম হিসাবে একই উপাদান এবং ছদ্ম-উপাদানের সাথে মেলে। আচরণ

এর প্রমাণ হল CSSStyleRule এর cssText পড়া। নেস্টেড ঘোষণার নিয়মের জন্য ধন্যবাদ এটি ইনপুট সিএসএসের মতোই:

.foo {
  width: fit-content;

  @media screen {
    background-color: red;
  }
    
  background-color: green;
}

এই আপনার জন্য মানে কি

এর মানে হল যে CSS নেস্টিং ক্রোম 130 এর হিসাবে অনেক ভাল হয়েছে। তবে, এর মানে হল যে আপনি যদি নেস্টেড নিয়মগুলির সাথে খালি ঘোষণাগুলি ইন্টারলিভ করে থাকেন তবে আপনাকে আপনার কিছু কোড অতিক্রম করতে হতে পারে।

নিম্নলিখিত উদাহরণ নিন যা চমৎকার @starting-style ব্যবহার করে

/* This does not work in Chrome 130 */
#mypopover:popover-open {
  @starting-style {
    opacity: 0;
    scale: 0.5;
  }

  opacity: 1;
  scale: 1;
}

Chrome 130 এর আগে এই ঘোষণাগুলি উত্তোলন করা হবে। আপনি opacity: 1; এবং scale: 1; ঘোষণাগুলি CSSStyleRule.style এ যাচ্ছে, তারপর CSSStyleRule.cssRules এ একটি CSSStartingStyleRule ( @starting-style নিয়মের প্রতিনিধিত্ব করে)।

Chrome 130 এর পর থেকে ঘোষণাগুলি আর উত্তোলন করা হবে না এবং আপনি CSSStyleRule.cssRules এ দুটি নেস্টেড CSSRule অবজেক্টের সাথে শেষ করবেন। ক্রমানুসারে: একটি CSSStartingStyleRule ( @starting-style নিয়মের প্রতিনিধিত্ব করে) এবং একটি CSSNestedDeclarations যাতে opacity: 1; scale: 1; ঘোষণা

এই পরিবর্তিত আচরণের কারণে, @starting-style ঘোষণাগুলি CSSNestedDeclarations দৃষ্টান্তে থাকা বিষয়গুলি দ্বারা ওভাররাইট করা হয়, যার ফলে এন্ট্রি অ্যানিমেশনটি সরিয়ে দেওয়া হয়।

কোডটি ঠিক করতে, নিশ্চিত করুন যে @starting-style ব্লকটি নিয়মিত ঘোষণার পরে আসে। যেমন:

/* This works in Chrome 130 */
#mypopover:popover-open {
  opacity: 1;
  scale: 1;

  @starting-style {
    opacity: 0;
    scale: 0.5;
  }
}

আপনি যদি CSS নেস্টিং ব্যবহার করার সময় নেস্টেড নিয়মগুলির উপরে আপনার নেস্টেড ঘোষণাগুলি রাখেন আপনার কোডটি CSS নেস্টিং সমর্থন করে এমন সমস্ত ব্রাউজারগুলির সমস্ত সংস্করণের সাথে বেশিরভাগই ভাল কাজ করে।

অবশেষে, আপনি যদি CSSNestedDeclarations এর উপলব্ধ বৈশিষ্ট্য সনাক্ত করতে চান তবে আপনি নিম্নলিখিত জাভাস্ক্রিপ্ট স্নিপেট ব্যবহার করতে পারেন:

if (!("CSSNestedDeclarations" in self && "style" in CSSNestedDeclarations.prototype)) {
  // CSSNestedDeclarations is not available
}