CSS scroll-state()

कंटेनर क्वेरी की तरह ही, लेकिन फ़्लो में रुकी हुई, स्नैप की गई, और ओवरफ़्लो हुई क्वेरी के लिए.

पब्लिश किया गया: 15 जनवरी, 2025

Chrome 133 में, स्क्रोल स्टेटस कंटेनर क्वेरी को शामिल करके, कंटेनर क्वेरी को बेहतर बनाया गया है. स्टिक वाली पोज़िशनिंग, स्क्रोल स्नैप पॉइंट, और स्क्रोल किए जा सकने वाले एलिमेंट के लिए, ब्राउज़र की मैनेज की गई स्थिति की जानकारी अब सीएसएस से ली जा सकती है और उसमें बदलाव किया जा सकता है.

खास जानकारी

स्क्रोल स्टेटस क्वेरी से पहले, आपको यह समझने के लिए JavaScript का इस्तेमाल करना होगा कि कोई एलिमेंट फ़्रीज़ हो गया है, स्नैप हो गया है या स्क्रोल किया जा सकता है. अब इस जानकारी को जानने और उसी के हिसाब से बदलाव करने के लिए, स्टैंडर्ड ट्रैक पर बेहतर परफ़ॉर्म करने वाला तरीका उपलब्ध है. ऐनिमेशन को ट्रिगर करने का एक नया तरीका भी है. इससे सीएसएस से स्क्रोल ट्रिगर किए गए ऐनिमेशन को अनलॉक किया जा सकता है.

Chrome 133 में उपलब्ध स्टेटस क्वेरी के बारे में खास जानकारी यहां दी गई है:

फ़्लैश फ़ाइल फ़ेच करने में लगने वाला समय:
जब कोई एलिमेंट किनारे पर चिपक जाता है, तो स्टाइल में बदलाव ट्रिगर करें.
स्नैप की गई स्थिति:
जब किसी एलिमेंट को किसी अक्ष पर स्नैप किया जाता है, तो स्टाइल में बदलाव ट्रिगर होता है.
स्क्रोल की जा सकने वाली स्थिति:
जब कोई एलिमेंट ओवरफ़्लो होता है, तो ट्रिगर की स्टाइल बदल जाती है.

अच्छी बात यह है कि कंटेनर क्वेरी से आपको जो भी जानकारी मिली है वह स्क्रोल स्टेटस क्वेरी के साथ काम करने में आपकी मदद करेगी.

स्क्रोल ड्रिवन ऐनिमेशन और स्क्रोल स्टेटस कंटेनर क्वेरी के बीच भी एक ऐसा क्षेत्र है जिसकी जानकारी अभी तक नहीं है. हमें समय और संदर्भ के साथ प्रयोग करने की ज़रूरत है, ताकि यह पता लगाया जा सके कि स्क्रोल ड्रिवन ऐनिमेशन या स्क्रोल से ट्रिगर होने वाला स्क्रोल-स्टेटस ऐनिमेशन, दोनों में से कौनसा सबसे अच्छा होगा. नीचे दिए गए वीडियो और डेमो में, इस समस्या के बारे में बताया गया है. इसमें स्क्रोल करने पर चलने वाले ऐनिमेशन की तुलना में, स्टिक ऐनिमेशन को ट्रिगर करने की सुविधा के बारे में बताया गया है.

(बाईं ओर) scroll-state() ट्रिगर किया गया ऐनिमेशन, (दाईं ओर) स्क्रोल से चलने वाला ऐनिमेशन
https://codepen.io/web-dot-dev/pen/emOrBaV

स्क्रोल की स्थिति की पहली क्वेरी

पहला चरण, container-type प्रॉपर्टी के लिए नई वैल्यू का इस्तेमाल करके कंटेनर तय करना है. कंटेनर क्वेरी की तरह ही, आपको जिस एलिमेंट के बारे में क्वेरी करनी है उस पर container-type और ज़रूरत पड़ने पर container-name लगाएं. स्क्रोल स्टेटस क्वेरी की मदद से, उस एलिमेंट को दिया जाता है जो स्नैप हो रहा है, अटक गया है या जिसमें ओवरफ़्लो है container-type: scroll-state.

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;
}

दूसरा चरण, उस कंटेनर का चाइल्ड चुनना है जो स्टेटस का जवाब देगा. कंटेनर क्वेरी के साथ, यह वही एलिमेंट नहीं हो सकता जिस पर container-type है.

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  > nav {
    @container scroll-state(stuck: top) {
      background: Highlight;
      color: HighlightText;
    }
  }
}

तीसरा चरण, इसे आज़माना है. नीचे दिए गए सीएसएस उदाहरण में, .stuck-top एलिमेंट के 0 पर सबसे ऊपर होने पर, बैकग्राउंड को लाल रंग में दिखाया जाएगा. हमने पहले से ही सीएसएस में कुछ अतिरिक्त लाइनें लिखी हैं. साथ ही, एक अतिरिक्त एलिमेंट भी जोड़ा है, जो ब्राउज़र की स्थिति को प्रॉक्सी करता है. इससे हमारे कॉम्पोनेंट, अपने आस-पास की जानकारी को बेहतर तरीके से समझ पाते हैं.

https://codepen.io/web-dot-dev/pen/ByBxpwR

प्रोग्रेसिव इंहांसमेंट

@supports at-rule और नेस्टिंग की मदद से, कोड की कुछ अतिरिक्त लाइनों में ही प्रगतिशील बेहतर बनाने की सुविधा या शर्त के हिसाब से सुविधा के इस्तेमाल को जोड़ा जा सकता है:

.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  @supports (container-type: scroll-state) {
    > nav {
      @container scroll-state(stuck: top) {
        background: Highlight;
        color: HighlightText;
      }
    }
  }
}

अगर आपको पेज पर स्क्रोल-स्टेटस क्वेरी की मदद से एलिमेंट को ऐनिमेट करना है, तो अपने मोशन के आस-पास @media (prefers-reduced-motion: no-preference) {} का इस्तेमाल करना न भूलें.

उपयोग के उदाहरण

रुका हुआ

शायद इस सेक्शन को "मुश्किल स्थितियां?" कहा जाना चाहिए. यह स्टिक स्टेटस के इस्तेमाल के उदाहरणों का एक छोटा कलेक्शन है. साथ ही, इसमें उन आइडिया का बोनस सेक्शन भी है जिन्हें बनाया जाना चाहिए.

@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}

सभी सिंटैक्स की सूची

फ़ोटो में फ़ोटोग्राफ़र की छाया जोड़ना

फ़्रीज़ हुई क्वेरी के इस्तेमाल के सबसे सामान्य उदाहरणों में से एक, नेविगेशन बार के लिए है. फ़्रीज़ होने पर, नेविगेशन बार में box-shadow जोड़ा जा सकता है, ताकि वे ओवरले किए गए कॉन्टेंट के ऊपर फ़्लोट कर सकें.

https://codepen.io/web-dot-dev/pen/GgKdryj
.stuck-top {
  container-type: scroll-state;
  position: sticky;
  top: 0px;

  > nav {
    transition: box-shadow .3s ease;

    @container scroll-state(stuck: top) {
      box-shadow: var(--shadow-5);
    }
  }
}

फ़िलहाल फ़्रीज़ हो रहे हेडर को चालू करना

यूज़र इंटरफ़ेस (यूआई) के फ़ीडबैक से जुड़ी एक और सामान्य स्थिति यह है कि फ़िलहाल फ़्रीज़ हुए एलिमेंट को हाइलाइट किया जाए. अंग्रेज़ी के वर्णमाला के क्रम में बने बैंड की सूची में, यह सुविधा बहुत मददगार हो सकती है.

https://codepen.io/web-dot-dev/pen/pvzVRaK
.sticky-slide {
  dt {
    container-type: scroll-state;
    position: sticky;
    inset-block-start: 0;
    inset-inline: 0;

    > header {
      transition: 
        background .3s ease,
        box-shadow .5s ease;

      @container scroll-state(stuck: top) {
        background: hsl(265 100% 27%);
        box-shadow: 0 5px 5px #0003;
      }
    }
  }
}

यहां एक और वैरिएंट दिया गया है, जिसमें हेडर, सूची के आइटम के बगल में हैं. बहुत सारी संभावनाएं!

https://codepen.io/web-dot-dev/pen/azoGpGg

आइडिया ओवरफ़्लो

यहां स्टिक डेमो की सूची दी गई है. इनसे आपको डेमो में कुछ नया जोड़ने या स्क्रोल स्टेटस क्वेरी की मदद से, JavaScript को हटाने की प्रेरणा मिल सकती है. हमारा सुझाव है कि आप अपनी पसंद का कोई एक फ़ॉर्मूला बनाएं. इससे सिंटैक्स और आइडिया को याद रखने में मदद मिलेगी 😏.

इस साल क्लिक की गईं फ़ोटो

स्नैप की गई स्थिति की क्वेरी की मदद से, हम JavaScript और स्नैप इवेंट से कुछ ज़िम्मेदारी हटा सकते हैं. साथ ही, इसे हैंडल करने की प्रोसेस को सीएसएस में ले जा सकते हैं.

@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}

सभी सिंटैक्स की सूची

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

a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
    ⤷ a child of the snap target that can query the container for snap state

स्नैप किए गए आइटम को विज़ुअल तौर पर बेहतर बनाना

आम तौर पर, स्क्रीन के बीच में स्नैप किए गए आइटम को हाइलाइट करने या दिखाने के लिए, स्क्रीन के बीच में स्नैप किए गए स्क्रोलर का इस्तेमाल किया जाता है. प्रशंसापत्र के इस उदाहरण में, not कीवर्ड का इस्तेमाल किया गया है, ताकि अनस्नैप किए गए सभी प्रशंसापत्र कम ओपैसिटी वाले हों. वहीं, स्नैप किए गए प्रशंसापत्र अपनी सामान्य स्थिति में बने रहें.

https://codepen.io/web-dot-dev/pen/NPKMdBX
.demo {
  overflow: auto hidden;
  scroll-snap-type: x mandatory;

  > article {
    container-type: scroll-state;
    scroll-snap-align: center;

    @supports (container-type: scroll-state) {
      > * {
        transition: opacity .5s ease;

        @container not scroll-state(snapped: x) {
          opacity: .25;
        }
      }
    }
  }
}

स्नैप किए गए आइटम का कैप्शन दिखाना

यह एक अच्छा उदाहरण है कि स्क्रोल स्टेटस क्वेरी, स्क्रोल से ट्रिगर होने वाले ऐनिमेशन को कैसे चालू करती हैं. यह इस बात का भी एक अच्छा उदाहरण है कि सीएसएस में, कम मोशन का इस्तेमाल कब करना चाहिए.

https://codepen.io/web-dot-dev/pen/XJrqpBG
.demo {
  overflow-x: auto;
  scroll-behavior-x: contain;
  scroll-snap-type: x mandatory;

  > .card {
    container-type: scroll-state;
    scroll-snap-align: center;

    @supports (container-type: scroll-state) {
      @media (prefers-reduced-motion: no-preference) {
        figcaption {
          transform: translateY(100%);

          @container scroll-state(snapped: x) {
            transform: translateY(0);
          }
        }
      }
    }
  }
}

स्लाइड के एलिमेंट में ऐनिमेशन जोड़ना

आम तौर पर, किसी बातचीत के दौरान स्लाइड शो या प्रज़ेंटेशन के एलिमेंट को ऐनिमेट किया जाता है. इसके लिए इंटरसेक्शन ऑब्ज़र्वर लिखना बहुत परेशान करने वाला काम था. यह सिर्फ़ स्लाइड पर एक क्लास सेट करता था. अब हमें किसी JavaScript की ज़रूरत नहीं है.

https://codepen.io/web-dot-dev/pen/dPbeNqY
html {
  scroll-snap-type: y mandatory;
}

section {
  container-type: scroll-state;
  scroll-snap-align: start;
  scroll-snap-stop: always;

  @supports (container-type: scroll-state) {
    @media (prefers-reduced-motion: no-preference) {
      > h1 {
        transition: opacity .5s ease, transform .5s var(--ease-spring-3);
        transition-delay: .5s;
        opacity: 0;
        transform: scale(1.25);

        @container scroll-state(snapped: block) {
          opacity: 1;
          transform: scale(1);
        }
      }
    }
  }
}

आपको यह दिख सकता है कि स्नैप की गई सीएसएस स्टेटस की सभी क्वेरी, scrollsnapchange के बजाय scrollsnapchanging की तरह काम करती हैं. इससे आपको स्नैप किए गए एलिमेंट का विज़ुअल फ़ीडबैक देने के लिए, जल्द से जल्द हुक मिलता है. अगर यह बहुत जल्दी ट्रिगर होता है, तो JavaScript इवेंट का इस्तेमाल करें.

स्क्रोल किया जा सकता है

स्क्रोल किए जा सकने वाले एरिया को स्क्रोल करने के लिए, विज़ुअल अवफ़र्डेंस दिखाने में स्क्रोल किए जा सकने की स्थिति की क्वेरी काफ़ी मददगार होगी. स्क्रोल स्टेटस क्वेरी से पहले, यह जानकारी हासिल करना मुश्किल था.

@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}

सभी सिंटैक्स की सूची

शैडो की मदद से स्क्रोल करने की जानकारी देना

लीआ वेरू की एक मशहूर सीएसएस ट्रिक है, जिसमें background-attachment: local का इस्तेमाल करके इस तरह का इफ़ेक्ट बनाया जाता है. साथ ही, स्क्रोल ड्रिवन ऐनिमेशन की मदद से भी ऐसा किया जा सकता है. हर तकनीक के कुछ फ़ायदे और कुछ नुकसान होते हैं. यह पता लगाना हमारा काम है कि इनमें से कौनसी तकनीक कब और कहां सबसे सही रहेगी.

इस उदाहरण में, स्क्रोलपोर्ट में फैले हुए एक स्टिक ऐलिमेंट का इस्तेमाल किया गया है. सबसे ऊपर और सबसे नीचे मौजूद ग्रेडिएंट की ओपैसिटी, @property के साथ ऐनिमेशन की जाती है. ऐसा तब होता है, जब स्क्रोल स्टेटस से जुड़ी संदर्भ क्वेरी लागू होती है: @container scroll-state(scrollable: top).

यह भी ध्यान दें कि यह पहला कंटेनर है, जो size और scroll-state, दोनों तरह का कंटेनर है.

https://codepen.io/web-dot-dev/pen/OPLZWBj
.scroll-container {
  container-type: scroll-state size;
  overflow: auto;

  &::after {
    content: " ";

    background: var(--_shadow-top), var(--_shadow-bottom);
    transition: 
      --_scroll-shadow-color-1-opacity .5s ease,
      --_scroll-shadow-color-2-opacity .5s ease;

    @container scroll-state(scrollable: top) {
      --_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
    }

    @container scroll-state(scrollable: bottom) {
      --_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
    }
  }
}

ऐरो प्रॉम्प्ट

कभी-कभी ऐरो दिखाने से, उपयोगकर्ताओं को यह पता चल सकता है कि किसी हिस्से को स्क्रोल किया जा सकता है. ये उस दिशा में इशारा करते हैं जहां स्क्रोल किया जा सकता है. साथ ही, ज़रूरत न होने पर ये गायब हो जाते हैं. ऐसा करने के लिए, यहां दिया गया कोड इस्तेमाल करें.

https://codepen.io/web-dot-dev/pen/OPLZWBj
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
  translate: 0 calc(100% + 10px);
}

@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
  translate: 0 calc(100% + 10px);
  rotate: .5turn;
}

वापस ऊपर जाएं

स्क्रोल स्टेटस के साथ इंटरैक्ट करने का एक और लोकप्रिय तरीका, "सबसे ऊपर स्क्रोल करें" सुविधा बटन है. नीचे दिए गए कोड की मदद से, स्क्रोल करके सबसे ऊपर जाने का बटन तब दिखता है, जब स्क्रोल करने के लिए कोई जगह न हो.

यह तरीका थोड़ा अलग है, लेकिन इससे सीएसएस का साइज़ कम किया जा सकता है. बटन को स्क्रीन पर दिखना चाहिए. इसलिए, जब ऊपर स्क्रोल करने के लिए कोई जगह न बचे, तब आपको उसे छिपाने के लिए कहना होगा.

https://codepen.io/web-dot-dev/pen/OPLZWBj
@container not scroll-state(scrollable: top) {
  translate: 0 calc(100% + 10px);
}

स्टडी जारी रखना

अगर आपको इस बारे में ज़्यादा जानकारी चाहिए, तो यहां कुछ संसाधन दिए गए हैं. इनमें स्पेसिफ़िकेशन की जानकारी के साथ-साथ, इस विषय से जुड़े अन्य बेहतरीन लेख भी शामिल हैं: