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

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

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

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

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-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-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)
  ├─ head
  └─ body
        └─ …

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

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

इससे ये नतीजे मिलते हैं:

लाइव डेमो

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

डेमो रिकॉर्डिंग (धीमी स्पीड वाला वर्शन)

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

रीकैप

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

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