अपने डीओएम के सीमित सबट्री में एलिमेंट चुनने के लिए, @scope का इस्तेमाल करने का तरीका जानें.
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
सीएसएस सिलेक्टर को लिखने की बारीक कला
सिलेक्टर को लिखते समय, हो सकता है कि आपको दो अलग-अलग चीज़ों के बीच फंसा हुआ महसूस हो. आपको यह भी बताना होगा कि आपने कौनसे एलिमेंट चुने हैं. दूसरी ओर, आपको सिलेक्टर को ऐसे रखना चाहिए कि उन्हें आसानी से बदला जा सके और उनके साथ डीओएम स्ट्रक्चर के साथ कोई तालमेल न बनाया जा सके.
उदाहरण के लिए, जब आपको “कार्ड कॉम्पोनेंट के कॉन्टेंट एरिया में हीरो इमेज” चुनना हो, तो हो सकता है कि आप .card > .content > img.hero
जैसा सिलेक्टर न लिखना चाहें.
- इस सिलेक्टर में
(0,3,1)
की खूबी बहुत ज़्यादा है. इसकी वजह से आपका कोड बढ़ने के साथ-साथ इसे बदलना मुश्किल हो जाता है. - डायरेक्ट चाइल्ड कॉम्बिनेटर पर निर्भर होने की वजह से, यह डीओएम स्ट्रक्चर से मज़बूती से जुड़ जाता है. अगर मार्कअप में कभी कोई बदलाव होता है, तो आपको अपना सीएसएस भी बदलना होगा.
हालांकि, आपको उस एलिमेंट के लिए सिलेक्टर के तौर पर सिर्फ़ img
नहीं लिखना है, क्योंकि इससे आपके पेज पर मौजूद सभी इमेज एलिमेंट चुन लिए जाएंगे.
इस स्थिति में सही संतुलन बनाना काफ़ी चुनौती भरा होता है. पिछले कुछ सालों में, कुछ डेवलपर ने इस तरह की स्थितियों में आपकी मदद करने के लिए, समाधान और समाधान तैयार किए हैं. उदाहरण के लिए:
- बीईएम जैसे तरीकों से यह पता चलता है कि एलिमेंट को
card__img card__img--hero
की क्लास दी जाती है, ताकि उसकी खासियत को कम रखा जा सके. साथ ही, चुने गए विकल्प के बारे में साफ़ तौर पर बताया जा सके. - दायरे वाले सीएसएस या स्टाइल वाले कॉम्पोनेंट जैसे JavaScript पर आधारित समाधान, अपने सिलेक्टर में रैंडम तरीके से जनरेट की गई स्ट्रिंग, जैसे कि
sc-596d7e0e-4
–को जोड़कर, आपके सभी सिलेक्टर को फिर से लिखते हैं. इससे वे आपके पेज के दूसरी ओर मौजूद एलिमेंट को टारगेट नहीं कर पाते. - कुछ लाइब्रेरी में सिलेक्टर ही पूरी तरह से इस्तेमाल नहीं किए जाते और आपको स्टाइलिंग ट्रिगर को सीधे मार्कअप में रखने की ज़रूरत होती है.
लेकिन अगर आपको उनमें से किसी की ज़रूरत न हो, तो क्या करना होगा? क्या होगा अगर सीएसएस आपको आपके चुने गए एलिमेंट के बारे में सटीक तौर पर बताने का विकल्प दे, और इसके लिए आपको ज़्यादा खासियत वाले सिलेक्टर या आपके डीओएम से मज़बूती से जुड़े हुए सिलेक्टर को लिखने की ज़रूरत न पड़े? यहां से @scope
का इस्तेमाल किया जा सकता है. इसमें आपको अपने डीओएम के सब-ट्री में एलिमेंट चुनने की सुविधा मिलती है.
पेश है @scope
@scope
की मदद से, चुनने वालों की पहुंच सीमित की जा सकती है. ऐसा करने के लिए स्कोपिंग रूट सेट करें, जो उस सबट्री की ऊपरी सीमा को तय करता है जिसे आपको टारगेट करना है. स्कोपिंग रूट सेट के साथ, स्कोपिंग स्टाइल के नियम नाम वाले शामिल स्टाइल नियम – डीओएम के सिर्फ़ उस सीमित सबट्री में से ही चुने जा सकते हैं.
उदाहरण के लिए, .card
कॉम्पोनेंट में सिर्फ़ <img>
एलिमेंट को टारगेट करने के लिए, .card
को @scope
ऐट-नियम के स्कोपिंग रूट के तौर पर सेट करें.
@scope (.card) {
img {
border-color: green;
}
}
स्कोप वाली स्टाइल का नियम img { … }
, असरदार तरीके से सिर्फ़ उन <img>
एलिमेंट को चुन सकता है जो मेल खाने वाले .card
एलिमेंट के स्कोप में आते हैं.
कार्ड के कॉन्टेंट एरिया (.card__content
) में मौजूद <img>
एलिमेंट को चुने जाने से रोकने के लिए, img
सिलेक्टर को और सटीक बनाया जा सकता है. ऐसा करने का दूसरा तरीका यह है कि इस नियम का इस्तेमाल करें कि @scope
के नियम में स्कोपिंग की सीमा भी स्वीकार की गई हो. इससे निचली सीमा तय होती है.
@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
से पहले, इसके बारे में साफ़ तौर पर बताया जा सकता है. इसके अलावा, सीएसएस नेस्टिंग में जाकर, &
सिलेक्टर को पहले जोड़ा जा सकता है.
@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
pseudo-class का इस्तेमाल कर सकती है, ताकि स्कोपिंग रूट से किसी खास संबंध की ज़रूरत हो:
/* .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)
नाम वाली सामान्य pseudo-class की खासियत है.
@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()
का इस्तेमाल करके &
की वैल्यू तय की जाती है. इसलिए, &
की खासियत, :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>
एलिमेंट का पैरंट एलिमेंट है.
कैस्केड में @Scope
CSS Cascade के अंदर, @scope
एक नई शर्त भी जोड़ता है: स्कोपिंग निकटता. यह चरण विशेषता के बाद आता है, लेकिन उसके दिखने के क्रम से पहले आता है.
हर स्पेसिफ़िकेशन के हिसाब से:
स्टाइल के नियमों में दिखने वाले एलानों की तुलना, अलग-अलग स्कोप वाले रूट से की जाती है. इसके बाद, सबसे कम जनरेशन या सिबलिंग एलिमेंट वाला एलान, स्कोपिंग रूट और स्कोप वाली स्टाइल के नियम के विषय के बीच हो जाता है.
किसी कॉम्पोनेंट के कई वैरिएशन को नेस्ट करते समय, यह नया चरण काम आता है. इस उदाहरण को लें, जो अभी तक @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
होगा. हालांकि, यह उस div
का चाइल्ड लिंक है जिस पर .light
क्लास लागू है. ऐसा, 'दिखने का तरीका' मानदंड के क्रम की वजह से होता है, जिसका इस्तेमाल कैस्केड यहां विजेता तय करने के लिए करता है. ऐसा लगता है कि .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
से वैल्यू इनहेरिट करते हैं.
(Unस्प्लैश पर रस्टम बुरखानोव की कवर फ़ोटो)