Kodokon kodokon.com

Cascade layers (@layer) और @scope

दो नए cascade मानदंडों - layers और scope की निकटता - में महारत हासिल करें ताकि specificity की लड़ाइयों के बिना अपनी styles की संरचना बना सकें।

10 मिनट · 3 प्रश्न

इस पाठ को Kodokon में खोलें

Cascade परस्पर विरोधी घोषणाओं को क्रमबद्ध मानदंडों से सुलझाता है: origin और importance, फिर context, फिर style एट्रिब्यूट styles, फिर layers (@layer), फिर specificity, फिर प्रकट होने का क्रम। महत्वपूर्ण बात: layers का मूल्यांकन specificity से पहले होता है। इसलिए किसी उच्च-प्राथमिकता layer में एक .button नियम, किसी निम्न-प्राथमिकता layer के #nav div.menu a.button को हरा देता है - इसकी (1,2,2) की specificity layer क्रम के सामने कोई मायने नहीं रखती। यही बात @layer को डिज़ाइन सिस्टम की संरचना बनाने में इतना शक्तिशाली बनाती है: प्राथमिकता एक बार, संरचनात्मक रूप से घोषित होती है, बजाय इसके कि हर सिलेक्टर के लिए लड़ी जाए।

CSS
@layer reset, base, components, utilities;

@layer components {
  .button { background: rebeccapurple; }
}

@layer base {
  button { background: gray; }
}
पहले से की गई घोषणा क्रम तय कर देती है: फ़ाइल में ब्लॉकों के क्रम की परवाह किए बिना, components base को हराता है।

दो स्पेक बारीकियाँ जो आपको ज़रूर जाननी चाहिए। एक: किसी भी layer के बाहर की styles, layered styles को हरा देती हैं (सामान्य घोषणाओं के लिए) - वे एक अंतर्निहित layer बनाती हैं जो सबसे अंत में रखी जाती है। इसलिए आपके स्थानीय ओवरराइड हमेशा layered लाइब्रेरी को हराते हैं। दो: !important के साथ, क्रम पूरी तरह उलट जाता है। सबसे पहले घोषित layers जीतती हैं, और किसी layer के भीतर का एक !important किसी layer के बाहर के !important को हराता है। आपकी reset layer में एक !important घोषणा लगभग अपराजेय बन जाती है।

CSS
@layer base, theme;

@layer base {
  a { color: black !important; }
}

@layer theme {
  a { color: purple !important; }
}
!important के साथ क्रम उलट जाता है: black जीतता है क्योंकि base पहले घोषित है।

@scope नियमों के एक समूह को एक scoping root और एक वैकल्पिक निचली सीमा के बीच बाँधता है: @scope (.card) to (.card__content) उन एलिमेंट्स को लक्षित करता है जो .card के वंशज हैं पर .card__content के बाहर हैं - यही प्रसिद्ध donut scope है, जो किसी कंपोनेंट के फ़्रेम को स्टाइल करने के लिए आदर्श है बिना उसकी इंजेक्ट की गई सामग्री में रिसाव किए। भीतर, :scope स्वयं root को संदर्भित करता है। और @scope एक बिल्कुल नया cascade मानदंड पेश करता है: निकटता। समान specificity पर, वह नियम जीतता है जिसकी scoping root एलिमेंट के सबसे नज़दीक है - ऐसा कुछ जिसे न BEM और न ही combinators कभी व्यक्त कर सके।

CSS
@scope (.card) to (.card__content) {
  :scope {
    padding: 1rem;
    border: 1px solid oklch(0.85 0.02 260);
  }
  img { border-radius: 8px; }
}
.card के फ़्रेम के img एलिमेंट्स लक्षित होते हैं; जो .card__content में इंजेक्ट किए गए हैं वे scope से बाहर हैं।

ज्ञान जांच

सुनिश्चित करें कि आपको इस पाठ के मुख्य बिंदु याद हैं।

  1. @layer a, b; के साथ और समान specificity की दो सामान्य घोषणाएँ, एक a में और एक b में, कौन-सी लागू होती है?
    • a layer वाली, जो पहले घोषित है
    • b layer वाली, क्योंकि सबसे अंत में घोषित layer जीतती है
    • फ़ाइल में सबसे बाद में प्रकट होने वाली, layers को अनदेखा करते हुए
  2. किसी भी layer के बाहर की एक सामान्य घोषणा, किसी layer में रखी एक सामान्य घोषणा का सामना करती है। परिणाम?
    • layered घोषणा हमेशा जीतती है
    • बिना-layer वाली घोषणा जीतती है
    • सिलेक्टर की specificity तय करती है
    • ब्राउज़र एक संघर्ष की रिपोर्ट करता है
  3. @scope (.card) to (.card__content) में, भीतरी नियम किन एलिमेंट्स को लक्षित कर सकते हैं?
    • .card के सभी वंशज बिना किसी अपवाद के
    • .card के वे वंशज जो .card__content के बाहर स्थित हैं (donut scope)
    • केवल .card__content और उसके बच्चे