नेस्ट किए गए व्यू ट्रांज़िशन ग्रुप का इस्तेमाल करके, व्यू ट्रांज़िशन में क्लिपिंग की समस्याओं (और अन्य समस्याओं) को रोकना

पब्लिश होने की तारीख: 22 सितंबर, 2025

व्यू ट्रांज़िशन शुरू करने पर, ब्राउज़र view-transition-name टैग किए गए एलिमेंट के पहले और बाद के स्नैपशॉट अपने-आप ले लेता है. ये स्नैपशॉट, सूडो-एलिमेंट के ट्री में रेंडर होते हैं. डिफ़ॉल्ट रूप से, जनरेट किया गया ट्री "फ़्लैट" होता है. इसका मतलब है कि DOM में ओरिजनल हैरारकी खत्म हो जाती है. साथ ही, कैप्चर किए गए सभी व्यू ट्रांज़िशन ग्रुप, एक ही ::view-transition स्यूडो-एलिमेंट के तहत सिबलिंग होते हैं.

फ़्लैट ट्री का यह तरीका, इस्तेमाल के कई उदाहरणों के लिए काफ़ी है. हालांकि, स्टाइलिंग के कुछ ऐसे उदाहरण हैं जिन्हें इस तरीके से हासिल नहीं किया जा सकता. यहां ऐसे इफ़ेक्ट के उदाहरण दिए गए हैं जिनसे फ़्लैट ट्री में अनचाहा विज़ुअल इफ़ेक्ट दिख सकता है:

  • क्लिपिंग (overflow, clip-path, border-radius): क्लिपिंग का असर एलिमेंट के चाइल्ड पर पड़ता है. इसका मतलब है कि व्यू ट्रांज़िशन ग्रुप के सिबलिंग एक-दूसरे को क्लिप नहीं कर सकते.
  • opacity, mask-image, और filter: इसी तरह, इन इफ़ेक्ट को किसी ट्री की पूरी तरह से रास्टर की गई इमेज पर काम करने के लिए डिज़ाइन किया गया है. ये इफ़ेक्ट, हर आइटम पर अलग-अलग लागू होने के बजाय, चाइल्ड पर लागू होते हैं.
  • 3D ट्रांसफ़ॉर्म (transform-style, transform, perspective): 3D ट्रांसफ़ॉर्म ऐनिमेशन की पूरी रेंज दिखाने के लिए, कुछ क्रम बनाए रखना ज़रूरी है.

इस उदाहरण में, फ़्लैट स्यूडो-ट्री दिखाया गया है. इसमें ऐसे एलिमेंट हैं जिन्हें डीओएम ट्री में मौजूद पूर्वज ने काटा है. व्यू ट्रांज़िशन के दौरान, इन एलिमेंट की क्लिपिंग हट जाती है. इस वजह से, विज़ुअल इफ़ेक्ट ठीक से नहीं दिखता.

व्यू ट्रांज़िशन के दौरान, क्लिपिंग इफ़ेक्ट के काम न करने की रिकॉर्डिंग. डायलॉग को टेक्स्ट का कुछ हिस्सा छिपाना चाहिए, लेकिन ऐसा नहीं हो रहा है. इफ़ेक्ट को ज़्यादा दिखाने के लिए, ऐनिमेशन की स्पीड कम कर दी गई है.

नेस्ट किए गए व्यू ट्रांज़िशन ग्रुप, व्यू ट्रांज़िशन का एक एक्सटेंशन है. इसकी मदद से, ::view-transition-group स्यूडो-एलिमेंट को एक-दूसरे में नेस्ट किया जा सकता है. जब व्यू ट्रांज़िशन ग्रुप नेस्ट किए जाते हैं, तो ट्रांज़िशन के दौरान क्लिप करने जैसे इफ़ेक्ट को वापस लाया जा सकता है.

Browser Support

  • Chrome: 140.
  • Edge: not supported.
  • Firefox: not supported.
  • Safari: not supported.

फ़्लैट स्यूडो-ट्री से नेस्ट किए गए स्यूडो-ट्री में बदलना

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

लाइव डेमो

डेमो रिकॉर्डिंग

डेमो रिकॉर्डिंग (धीमी की गई)

अगर डेमो को ध्यान से देखा जाए, तो आपको दिखेगा कि ट्रांज़िशन में समस्या है: भले ही, ब्यौरे वाले पैराग्राफ़ डीओएम में <dialog> एलिमेंट के चाइल्ड हों, लेकिन ट्रांज़िशन के दौरान टेक्स्ट को <dialog> के बॉक्स से काटा नहीं जाता:

<dialog id="info_bramus" closedby="any">
  <h2><img alt="…" class="avatar" height="96" width="96" src="avatar_bramus.jpg"> <span>Bramus</span></h2>
  <p>Bramus is …</p>
  <p>…</p>
</dialog>

<dialog> पर overflow: clip लागू करने से भी कोई फ़र्क़ नहीं पड़ता.

समस्या यह है कि व्यू ट्रांज़िशन, अपने छद्म ट्री को कैसे बनाते और रेंडर करते हैं:

  • स्यूडो-ट्री में, डिफ़ॉल्ट रूप से सभी स्नैपशॉट एक-दूसरे के सिबलिंग होते हैं.
  • स्यूडो-ट्री को ::view-transition स्यूडो-एलिमेंट में रेंडर किया जाता है. यह पूरे दस्तावेज़ के सबसे ऊपर रेंडर होता है.

इस डेमो के लिए, DOM ट्री इस तरह दिखता है:

html
  ├─ ::view-transition
  │  ├─ ::view-transition-group(card)
  │  │  └─ ::view-transition-image-pair(card)
  │  │     ├─ ::view-transition-old(card)
  │  │     └─ ::view-transition-new(card)
  │  ├─ ::view-transition-group(name)
  │  │  └─ ::view-transition-image-pair(name)
  │  │     ├─ ::view-transition-old(name)
  │  │     └─ ::view-transition-new(name)
  │  ├─ ::view-transition-group(avatar)
  │  │  └─ ::view-transition-image-pair(avatar)
  │  │     ├─ ::view-transition-old(avatar)
  │  │     └─ ::view-transition-new(avatar)
  │  ├─ ::view-transition-group(paragraph1.text)
  │  │  └─ ::view-transition-image-pair(paragraph1.text)
  │  │     └─ ::view-transition-new(paragraph1.text)
  │  └─ ::view-transition-group(paragraph2.text)
  │     └─ ::view-transition-image-pair(paragraph2.text)
  │        └─ ::view-transition-new(paragraph2.text)
  ├─ head
  └─ body
        └─ …

::view-transition-group(.text) स्यूडो, ::view-transition-group(card) स्यूडो के बाद आते हैं. इसलिए, इन्हें कार्ड के सबसे ऊपर पेंट किया जाता है.

::view-transition-group(card) क्लिप ::view-transition-group(.text) के लिए, ::view-transition-group(.text) स्यूडो को ::view-transition-group(card) का चाइल्ड होना चाहिए. इसके लिए, view-transition-group का इस्तेमाल करें. इससे जनरेट किए गए ::view-transition-group() स्यूडो-एलिमेंट के लिए, "पैरंट ग्रुप" असाइन किया जा सकता है.

आपके पास पैरंट ग्रुप बदलने के दो विकल्प हैं:

  • पैरंट के लिए, view-transition-group को contain पर सेट करें, ताकि इसमें view-transition-name वाले सभी बच्चे शामिल हों.
  • सभी चाइल्ड प्रॉडक्ट के लिए, view-transition-group एट्रिब्यूट की वैल्यू को पैरंट प्रॉडक्ट के view-transition-name एट्रिब्यूट की वैल्यू के तौर पर सेट करें. सबसे नज़दीकी पूर्वज ग्रुप को टारगेट करने के लिए, nearest का भी इस्तेमाल किया जा सकता है.

इसलिए, इस डेमो के लिए नेस्ट किए गए व्यू ट्रांज़िशन ग्रुप का इस्तेमाल करने पर, कोड यह हो जाता है:

button.clicked,
dialog {
  view-transition-group: contain;
}

या

button.clicked,
dialog *,
  view-transition-group: nearest;
}

इस कोड को लागू करने के बाद, ::view-transition-group(.text) स्यूडो एलिमेंट, ::view-transition-group(card) स्यूडो एलिमेंट में नेस्ट हो जाते हैं. ऐसा एक अतिरिक्त ::view-transition-group-children(…) स्यूडो में किया जाता है, जो सभी नेस्ट किए गए स्यूडो को एक साथ रखता है:

html
  ├─ ::view-transition
  │  ├─ ::view-transition-group(card)
  │  │  ├─ ::view-transition-image-pair(card)
  │  │  │  ├─ ::view-transition-old(card)
  │  │  │  └─ ::view-transition-new(card)
  │  │  └─::view-transition-group-children(card)
  │  │    ├─ ::view-transition-group(paragraph1.text)
  │  │    │  └─ ::view-transition-image-pair(paragraph1.text)
  │  │    │     └─ ::view-transition-new(paragraph1.text)
  │  │    └─ ::view-transition-group(paragraph2.text)
  │  │       └─ ::view-transition-image-pair(paragraph2.text)
  │  │          └─ ::view-transition-new(paragraph2.text)
  │  ├─ ::view-transition-group(name)
  │  │  └─ ::view-transition-image-pair(name)
  │  │     ├─ ::view-transition-old(name)
  │  │     └─ ::view-transition-new(name)
  │  └─ ::view-transition-group(avatar)
  │     └─ ::view-transition-image-pair(avatar)
  │        ├─ ::view-transition-old(avatar)
  │        └─ ::view-transition-new(avatar)
  ├─ head
  └─ body
        └─ …

आखिर में, पैराग्राफ़ को ::view-transition-group(card) के तौर पर दिखाने के लिए, ::view-transition-group-children(card) के तौर पर दिखाए गए पैराग्राफ़ पर overflow: clip लागू करें:

::view-transition-group-children(card) {
  overflow: clip;
}

नतीजा यह है:

लाइव डेमो

डेमो रिकॉर्डिंग

डेमो रिकॉर्डिंग (धीमी की गई)

::view-transition-group-children pseudo सिर्फ़ तब मौजूद होता है, जब नेस्ट किए गए ग्रुप का इस्तेमाल किया जाता है. इसका साइज़, ओरिजनल एलिमेंट के बॉर्डर-बॉक्स के हिसाब से होता है. साथ ही, इसे पारदर्शी बॉर्डर दिया जाता है. इसका आकार और बॉर्डर की मोटाई, स्यूडो एलिमेंट जनरेट करने वाले एलिमेंट के जैसी होती है. पिछले उदाहरण में, यह card है.

क्लिपिंग और अन्य सुविधाएं

नेस्ट किए गए व्यू ट्रांज़िशन ग्रुप का इस्तेमाल, क्लिपिंग इफ़ेक्ट के अलावा अन्य जगहों पर भी किया जाता है. 3D इफ़ेक्ट भी इसका एक उदाहरण है. नीचे दिए गए डेमो में, ट्रांज़िशन के दौरान कार्ड को 3D में घुमाने का विकल्प है.

html:active-view-transition-type(open) {
    &::view-transition-old(card) {
        animation-name: rotate-out;
    }
    &::view-transition-new(card) {
        animation-name: rotate-in;
    }
}
html:active-view-transition-type(close) {
    &::view-transition-old(card) {
        animation-name: rotate-in;
    }
    &::view-transition-new(card) {
        animation-name: rotate-out;
    }
}

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

लाइव डेमो

डेमो रिकॉर्डिंग

डेमो रिकॉर्डिंग (धीमी की गई)

कार्ड में अवतार और नाम के छद्म एलिमेंट को नेस्ट करके, 3D इफ़ेक्ट को वापस लाया जा सकता है. हालांकि, आपको सिर्फ़ इतना ही नहीं करना है. ::view-transition-old(card) और ::view-transition-new(card) स्यूडो को रोटेट करने के साथ-साथ, आपको ::view-transition-group-children(card) को भी रोटेट करना होगा.

html:active-view-transition-type(open) {
    &::view-transition-group-children(card) {
        animation: rotate-in var(--duration) ease;
        backface-visibility: hidden;
    }
}
html:active-view-transition-type(close) {
    &::view-transition-group-children(card) {
        animation: rotate-out var(--duration) ease;
        backface-visibility: hidden;
    }
}

लाइव डेमो

डेमो रिकॉर्डिंग

डेमो रिकॉर्डिंग (धीमी की गई)

ज़्यादा डेमो

यहां दिए गए उदाहरण में, नेस्टेड व्यू ट्रांज़िशन ग्रुप का इस्तेमाल किया गया है. इससे यह पक्का किया जा सकता है कि कार्ड, अपने पैरंट स्क्रोलर से क्लिप हो जाएं. इसमें शामिल कंट्रोल का इस्तेमाल करके, नेस्ट किए गए व्यू ट्रांज़िशन ग्रुप के इस्तेमाल को टॉगल करके चालू या बंद किया जा सकता है.

लाइव डेमो

डेमो रिकॉर्डिंग

इस डेमो की दिलचस्प बात यह है कि सभी ::view-transition-group(.card) सूडो, पूर्वज ::view-transition-group(cards) सूडो के अंदर नेस्ट किए जाते हैं और उससे क्लिप किए जाते हैं. #targeted-card को शामिल नहीं किया गया है, क्योंकि इसके एंट्री/एक्ज़िट ऐनिमेशन को ::view-transition-group(cards) से काटा नहीं जाना चाहिए.

/* The .cards wrapper contains all children */
.cards {
  view-transition-name: cards;
  view-transition-group: contain;
}

/* Contents that bleed out get clipped */
&::view-transition-group-children(cards) {
  overflow: clip;
}

/* Each card is given a v-t-name and v-t-class */
.card {
  view-transition-name: match-element;
  view-transition-class: card;
}

/* The targeted card is given a unique name (to style the pseudo differently)
   and shouldn't be contained by the ::view-transition-group-children(cards) pseudo */
#targeted-card {
  view-transition-name: targeted-card;
  view-transition-group: none;
}

रीकैप

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

नेस्टिंग से, व्यू ट्रांज़िशन बनाने के मॉडल में बदलाव होता है. इसका इस्तेमाल बेहतर इफ़ेक्ट बनाने के लिए किया जाता है. जैसा कि बताया गया है, तत्व के स्कोप वाली व्यू ट्रांज़िशन भी आसान मॉडल के साथ कुछ इफ़ेक्ट हासिल कर सकती हैं. हमारा सुझाव है कि आप दोनों सुविधाओं को आज़माएं, ताकि आपको यह पता चल सके कि आपकी ज़रूरतों के हिसाब से कौनसी सुविधा सबसे सही है.