सिमैंटिक कॉम्पोनेंट अडैप्टेशन

वेब की सुविधाएं: कंटेनर स्टाइल क्वेरी

कॉन्टेक्स्ट के हिसाब से वैरिएशन ट्रिगर करने के लिए, स्टाइल क्वेरी (@container style()) का इस्तेमाल करें. इसके लिए, आपको हर कॉन्टेक्स्ट को जनरेट करने या उस पर प्रतिक्रिया देने के लिए हार्डकोडिंग करने की ज़रूरत नहीं है. इससे डिज़ाइन सिस्टम कपलिंग कम हो जाती है. साथ ही, एक्सटेंसिबिलिटी और कॉम्पोनेंट एनकैप्सुलेशन बेहतर होता है.

उदाहरण के लिए, section.featured { --surface: featured } नियम किसी कॉन्टेक्स्ट को मार्क कर सकता है. साथ ही, कोई लैंडिंग पेज भी main { --surface: featured } के ज़रिए डिफ़ॉल्ट रूप से उस पर सेट हो सकता है. इसके बाद, कॉम्पोनेंट --surface: featured पर प्रतिक्रिया देने के लिए शामिल होते हैं: कार्ड पर प्रमोशन वाला बैज दिखता है, बटन डिफ़ॉल्ट रूप से अपने भरे हुए वैरिएंट पर सेट हो जाता है वगैरह.

स्टाइल क्वेरी की मदद से, दोनों साइड अलग-अलग रहती हैं: जिन सरफ़ेस पर कॉम्पोनेंट को दिखाया जाता है वे कभी भी उन एलिमेंट का नाम नहीं बताते जो उनके हिसाब से अडैप्ट होते हैं. साथ ही, कॉम्पोनेंट कभी भी यह जांच नहीं करते कि कॉन्टेक्स्ट किस वजह से जनरेट हुआ. दोनों में से किसी भी हिस्से को अलग से बढ़ाया जा सकता है. जैसे, नए कॉम्पोनेंट, नई सुविधाएं वगैरह. इसके लिए, दूसरे हिस्से में कोई बदलाव करने की ज़रूरत नहीं होती. डिसेंडेंट सिलेक्टर (जैसे, .featured .button) इसके उलट काम करते हैं: सिलेक्टर को संबंध के दोनों पक्षों को एन्कोड करना चाहिए. साथ ही, जब भी कोई पक्ष बदलता है, तो सिलेक्टर को भी बदलना चाहिए.

इस गाइड का इस्तेमाल कब करना चाहिए

इस गाइड में, व्यवहार से जुड़े बदलावों के बारे में बताया गया है: कॉम्पोनेंट अपने कॉन्टेक्स्ट के हिसाब से यह तय करता है कि क्या रेंडर करना है, खुद को कैसे व्यवस्थित करना है या कौनसा वैरिएंट दिखाना है. जैसे, बैज को छिपाना या दिखाना, लेआउट की दिशा बदलना या बटन का वैरिएंट बदलना.

अगर आपको टोकन-लेवल पर बदलाव करने हैं, तो डिज़ाइन टोकन रिएक्टिविटी देखें. जैसे, डेंसिटी मोड, थीम या अन्य हाई-ऑर्डर टोकन, जो कई कॉम्पोनेंट में पैडिंग और कलर जैसी वैल्यू को एक जैसा बदलते हैं.

सही टूल चुनना

स्टाइल क्वेरी का इस्तेमाल तब करें, जब कॉन्टेक्स्ट के हिसाब से बने संबंध के दोनों हिस्से अलग-अलग बदल सकते हों. जैसे, नए एलिमेंट कॉन्टेक्स्ट बनाना शुरू कर सकते हैं या नए कॉम्पोनेंट उस पर प्रतिक्रिया देना शुरू कर सकते हैं. इनडायरेक्ट तरीके से स्टाइल लागू करने पर, स्टाइल को आसानी से बढ़ाया जा सकता है और उसे एनकैप्सुलेट किया जा सकता है. साथ ही, स्टाइल क्वेरी, शैडो डीओएम की सीमाओं को पार कर सकती हैं, जबकि डिसेंडेंट सिलेक्टर ऐसा नहीं कर सकते. जब आपको ज़्यादा विकल्पों की ज़रूरत न हो, तो आसान टूल का इस्तेमाल करें:

  • डिसेंडेंट सिलेक्टर (.toolbar .button): यह एक तय और वन-ऑफ़ रिलेशनशिप है, जिसे फिर से इस्तेमाल या बड़ा नहीं किया जा सकता. YAGNI लागू होता है — ऐसा इनडायरेक्शन न जोड़ें जिसका इस्तेमाल नहीं किया जाएगा.
  • साइज़ क्वेरी (@container (min-width: …)): उपलब्ध स्पेस के हिसाब से लेआउट और डेंसिटी में बदलाव होते हैं, न कि सिमैंटिक स्टेट के हिसाब से.
  • स्टाइल क्वेरी (@container style(…)): सिमैंटिक स्टेट — किसी कॉम्पोनेंट को किसी संदर्भ में क्या रेंडर करना चाहिए, व्यवस्थित करना चाहिए या दिखाना चाहिए.

लागू करने के लिए निर्देश

  1. किसी कंटेनर पर सीएसएस कस्टम प्रॉपर्टी का इस्तेमाल करके, सिमैंटिक कॉन्टेक्स्ट फ़्लैग तय करें.
  2. स्टाइल क्वेरी के लिए, container-type सेट न करें. ये क्वेरी, सबसे नज़दीकी पैरंट एलिमेंट पर इनहेरिट की गई कस्टम प्रॉपर्टी को क्वेरी करती हैं. साथ ही, इन्हें साफ़ तौर पर कंटेनमेंट कॉन्टेक्स्ट की ज़रूरत नहीं होती.
  3. ज़रूरी: डिसेंडेंट एलिमेंट पर कंडिशनल स्टाइल लागू करने के लिए, @container style(--property: value) का इस्तेमाल करें. स्टाइल क्वेरी, उस एलिमेंट से मैच नहीं हो सकतीं जिस पर प्रॉपर्टी सेट की गई है. ये सिर्फ़ उसके डिसेंडेंट से मैच हो सकती हैं.
  4. जब रिलेशनशिप को एक्सटेंसिबल या क्रॉस कॉम्पोनेंट/शैडो डीओएम बाउंड्री रखना ज़रूरी हो, तो डिसेंडेंट सिलेक्टर के बजाय स्टाइल क्वेरी को प्राथमिकता दें. इसके बारे में ऊपर सही टूल चुनना सेक्शन में बताया गया है. हालांकि, डिसेंडेंट सिलेक्टर को तय और एक बार के रिलेशनशिप के लिए रखें, जहां इनडायरेक्शन से कुछ नहीं मिलता.

लागू करने का उदाहरण

/* 1. Set the context on a layout container */
.featured {
  --surface: featured; /* Semantic context flag for children */
}

/* 2. Component reacts to inherited flag */
.button {
  /* Default: Outlined informational style */
  background: transparent;
  border: 1px solid currentColor;
}

.badge {
  /* Default: Hidden — only revealed in featured surfaces */
  display: none;
}

@container style(--surface: featured) {
  .button {
    /* Automatic switch to Filled promotional style */
    background: var(--brand-accent);
    color: white;
    border: none;
  }

  .badge {
    /* Reveal decorative elements only in featured context */
    display: block;
  }
}

फ़ॉलबैक रणनीतियां

जब तक कंटेनर स्टाइल क्वेरी बड़े पैमाने पर उपलब्ध नहीं हो जातीं, तब तक उन्हें परतदार वृद्धि के तौर पर लेयर करें: सिलेक्टर पर आधारित एक डिफ़ॉल्ट स्टाइल शिप करें, जो हर जगह काम करे. साथ ही, स्टाइल क्वेरी को ज़रूरत पड़ने पर उसे बदलने की अनुमति दें. कॉन्टेक्स्ट सिलेक्टर पर :where() का इस्तेमाल करें, ताकि स्टाइल क्वेरी (एक जैसी खासियत, सोर्स ऑर्डर में बाद में) अपने-आप लागू हो जाए.

/* Default styles — work everywhere */
.button {
  background: transparent;
  border: 1px solid currentColor;
}

.badge {
  display: none;
}

/* Selector-based contextual styles — broad browser support */
:where(.featured) .button {
  background: var(--brand-accent);
  color: white;
  border: none;
}

:where(.featured) .badge {
  display: block;
}

/* Progressive enhancement: style queries override when supported */
@container style(--surface: featured) {
  .button {
    background: var(--brand-accent);
    color: white;
    border: none;
  }

  .badge {
    display: block;
  }
}

सिलेक्टर फ़ॉलबैक, कॉन्टेक्स्ट के हिसाब से स्टाइलिंग को क्लास के नाम से जोड़ता है. इससे कॉम्पोनेंट, अपने डीओएम प्लेसमेंट से जुड़ जाता है. स्टाइल क्वेरी के लिए ज़्यादा ब्राउज़र पर सहायता उपलब्ध होने के बाद, :where() नियम को हटाया जा सकता है.