आसानी से एंट्री करने और बाहर निकलने के ऐनिमेशन के लिए चार नई सीएसएस सुविधाएं

उना क्रावेट्स
उना क्रावेट्स
जॉय अरहर
जॉय अरहर

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

इन अंतरों को भरने के लिए, Chrome 116 और 117 में चार नई वेब प्लैटफ़ॉर्म सुविधाएं शामिल हैं. इनसे अलग-अलग प्रॉपर्टी के लिए, आसान ऐनिमेशन और ट्रांज़िशन मिलते हैं.

ये चार नई सुविधाएं शामिल हैं:

  • display और content-visibility को मुख्य-फ़्रेम टाइमलाइन पर ऐनिमेट करने की सुविधा (Chrome 116 से).
  • display (Chrome 117 से) जैसी अलग-अलग प्रॉपर्टी के ट्रांज़िशन की सुविधा चालू करने के लिए, allow-discrete कीवर्ड के साथ transition-behavior प्रॉपर्टी.
  • display: none और टॉप-लेयर (Chrome 117 से) में एंट्री इफ़ेक्ट को ऐनिमेट करने के लिए @starting-style नियम.
  • किसी ऐनिमेशन के दौरान, सबसे ऊपर वाले लेवल के व्यवहार को कंट्रोल करने के लिए overlay प्रॉपर्टी (Chrome 117 से). ## मुख्य-फ़्रेम में ऐनिमेशन दिखाना

Chrome 116 से, मुख्य-फ़्रेम के नियमों में display और content-visibility का इस्तेमाल किया जा सकता है. फिर मुख्य-फ़्रेम आने के समय ये अपने-आप बदल जाएंगे. इसके लिए, किसी और नई वैल्यू की ज़रूरत नहीं होती है:

.card {
  animation: fade-out 0.5s forwards;
}

@keyframes fade-out {
  100% {
    opacity: 0;
    display: none;
  }
}

पिछला उदाहरण, 0.5 सेकंड की ओपैसिटी को 0 पर ऐनिमेशन के तौर पर 0 पर सेट करता है. इसके बाद, डिसप्ले को 'कोई नहीं' पर सेट करता है. इसके अलावा, forwards कीवर्ड यह पक्का करता है कि ऐनिमेशन अपनी आखिरी स्थिति में बना रहे, ताकि उस एलिमेंट पर लागू किया गया एलिमेंट display: none और opacity: 0 बना रहे.

यह एक आसान उदाहरण है, जिसमें किसी ट्रांज़िशन की नकल करने का तरीका बताया गया है. इसके बारे में ज़्यादा जानने के लिए, ट्रांज़िशन वाले सेक्शन में डेमो देखें. हालांकि, ट्रांज़िशन से ज़्यादा जटिल ऐनिमेशन नहीं बनाए जा सकते, जैसे कि नीचे दिया गया उदाहरण:

.card {
  animation: spin-and-delete 1s ease-in forwards;
}

@keyframes spin-and-delete {
  0% {
    transform: rotateY(0);
    filter: hue-rotate(0);
  }
  80% {
    transform: rotateY(360deg);
    filter: hue-rotate(180deg);
    opacity: 1;
  }
  100% {
    opacity: 0;
    display: none;
  }
}

spin-and-delete ऐनिमेशन, एग्ज़िट ऐनिमेशन है. सबसे पहले, कार्ड y-ऐक्सिस पर घूमेगा, ह्यू-रोटेशन करेगा और फिर 80% पर टाइमलाइन के ज़रिए, अपनी ओपैसिटी को 1 से 0 में बदल देगा. आखिर में, कार्ड display: block से display: none में बदल जाता है.

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

.spin-out {
   animation: spin-and-delete 1s ease-in forwards;
}
document.querySelector('.delete-btn').addEventListener('click', () => {
 document.querySelector('.card').classList.add('spin-out');
})

ऊपर दिए गए उदाहरण में, अब खत्म होने की स्थिति display:none है. ऐसे कई मामले हैं जहां आपको ऐनिमेशन को पहले पूरा करने के लिए, टाइम आउट के साथ DOM नोड को हटाना होगा.

अलग-अलग ऐनिमेशन का ट्रांज़िशन करना

अलग-अलग प्रॉपर्टी को मुख्य-फ़्रेम से ऐनिमेट करते समय अलग, अलग-अलग प्रॉपर्टी पर ट्रांज़िशन के लिए, आपको allow-discrete ट्रांज़िशन बिहेवियर मोड का इस्तेमाल करना होगा.

transition-behavior प्रॉपर्टी

allow-discrete मोड की मदद से, अलग-अलग ट्रांज़िशन हो सकते हैं और यह transition-behavior प्रॉपर्टी की वैल्यू है. transition-behavior दो वैल्यू स्वीकार करता है: normal और allow-discrete.

.card {
  transition: opacity 0.25s, display 0.25s;
  transition-behavior: allow-discrete; /* Note: be sure to write this after the shorthand */
}

.card.fade-out {
  opacity: 0;
  display: none;
}
ध्यान दें: यह ट्रांज़िशन डेमो, पहले ऐनिमेशन डेमो से अलग तकनीक दिखाता है. हालांकि, यह दिखने में एक जैसा ही लगता है.

transition शॉर्टहैंड भी इस वैल्यू को सेट करता है, ताकि आप प्रॉपर्टी को छोड़ दें और इसके बजाय हर ट्रांज़िशन के लिए, transition शॉर्टहैंड के आखिर में allow-discrete कीवर्ड का इस्तेमाल करें.

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

अगर आप कई अलग-अलग प्रॉपर्टी को ऐनिमेट कर रहे हैं, तो आपको हर उस प्रॉपर्टी के बाद allow-discrete को शामिल करना होगा, जिसे आप ऐनिमेट करना चाहते हैं. उदाहरण के लिए:

.card {
  transition: opacity 0.5s, display 0.5s allow-discrete, overlay 0.5s allow-discrete;
}

.card.fade-out {
  opacity: 0;
  display: none;
}

एंट्री में इस्तेमाल होने वाले ऐनिमेशन के लिए @starting-style नियम

अब तक, इस लेख में कवर किए गए एग्ज़िट ऐनिमेशन दिए गए हैं. एंट्री ऐनिमेशन बनाने के लिए, आपको @starting-style नियम का इस्तेमाल करना होगा.

ऐसी स्टाइल लागू करने के लिए @starting-style का इस्तेमाल करें जिसे ब्राउज़र, पेज पर एलिमेंट के खुलने से पहले देख सके. यह “खुले होने से पहले” की स्थिति है (जहां से आपकी शुरुआत होती है).

/*  0. BEFORE-OPEN STATE   */
/*  Starting point for the transition */
@starting-style {
  .item {
    opacity: 0;
    height: 0;
  }
}

/*  1. IS-OPEN STATE   */
/*  The state at which the element is open + transition logic */
.item {
  height: 3rem;
  display: grid;
  overflow: hidden;
  transition: opacity 0.5s, transform 0.5s, height 0.5s, display 0.5s allow-discrete;
}

/*  2. EXITING STATE   */
/*  While it is deleting, before DOM removal in JS, apply this
    transformation for height, opacity, and a transform which
    skews the element and moves it to the left before setting
    it to display: none */
.is-deleting {
  opacity: 0;
  height: 0;
  display: none;
  transform: skewX(50deg) translateX(-25vw);
}

अब आपके पास इन TODO सूची आइटम के लिए एंट्री और एग्ज़िट स्थिति, दोनों हैं:

टॉप-लेयर में और उसके अंदर के एलिमेंट को ऐनिमेट करना

टॉप-लेयर में और उससे एलिमेंट को ऐनिमेट करने के लिए, “ओपन” स्थिति में @starting-style के बारे में बताएं. इससे ब्राउज़र को यह पता चलेगा कि कहां से ऐनिमेट करना है. किसी डायलॉग बॉक्स में, [open] एट्रिब्यूट की मदद से 'ओपन स्टेट' का इस्तेमाल किया जाता है. पॉपओवर के लिए, :popover-open सूडो क्लास का इस्तेमाल करें.

डायलॉग का एक आसान उदाहरण ऐसा दिख सकता है:

/*   0. BEFORE-OPEN STATE   */
@starting-style {
  dialog[open] {
    translate: 0 100vh;
  }
}

/*   1. IS-OPEN STATE   */
dialog[open] {
  translate: 0 0;
}

/*   2. EXIT STATE   */
dialog {
  transition: translate 0.7s ease-out, overlay 0.7s ease-out allow-discrete, display 0.7s ease-out allow-discrete;
  translate: 0 100vh;
}

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

पॉपओवर को ऐनिमेट करते समय, पहले इस्तेमाल किए गए open एट्रिब्यूट के बजाय :popover-open सूडो क्लास का इस्तेमाल करें.

.settings-popover {
  &:popover-open {
    /*  0. BEFORE-OPEN STATE  */
    /*  Initial state for what we're animating *in* from, 
        in this case: goes from lower (y + 20px) to center  */
    @starting-style {
      transform: translateY(20px);
      opacity: 0;
    }
    
    /*  1. IS-OPEN STATE  */
    /*  state when popover is open, BOTH:
        what we're transitioning *in* to 
        and transitioning *out* from */
    transform: translateY(0);
    opacity: 1;
  }
  
  /*  2. EXIT STATE  */
  /*  Initial state for what we're animating *out* to , 
      in this case: goes from center to (y - 50px) higher */
  transform: translateY(-50px);
  opacity: 0;
  
  /*  Enumerate transitioning properties, 
      including display and allow-discrete mode */
  transition: transform 0.5s, opacity 0.5s, display 0.5s allow-discrete;
}

overlay प्रॉपर्टी

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

[open] {
  transition: opacity 1s, display 1s allow-discrete;
}

इसके बजाय, overlay को बाकी सुविधाओं के साथ ऐनिमेट करने या ऐनिमेट करने के लिए, overlay को ट्रांज़िशन या ऐनिमेशन में शामिल करें. साथ ही, पक्का करें कि ऐनिमेट करते समय यह सबसे ऊपर लेयर में बना रहे. यह बहुत आसान दिखेगा.

[open] {
  transition: opacity 1s, display 1s allow-discrete, overlay 1s allow-discrete;
}

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

व्यू ट्रांज़िशन के बारे में जानकारी

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

इस पहले डेमो में, @starting-style और अन्य सीएसएस ट्रांसफ़ॉर्म को सेट अप करने के बजाय, व्यू ट्रांज़िशन, ट्रांज़िशन को हैंडल करेंगे. व्यू ट्रांज़िशन को इस तरह सेट अप किया जाता है:

सबसे पहले, सीएसएस में हर कार्ड को एक अलग view-transition-name दें.

.card-1 {
  view-transition-name: card-1;
}

.card-2 {
  view-transition-name: card-2;
}

/* etc. */

इसके बाद, JavaScript में व्यू ट्रांज़िशन में, डीओएम म्यूटेशन (इस मामले में, कार्ड हटाकर) को रैप करें.

deleteBtn.addEventListener('click', () => {
  // Check for browser support
  if (document.startViewTransition) {
    document.startViewTransition(() => {
      // DOM mutation
      card.remove();
    });
  } 
  // Alternative if no browser support
  else {
    card.remove();
  }
})

अब ब्राउज़र, हर कार्ड के फ़ेड आउट और मॉर्फ़ को नई जगह पर ले जा सकता है.

इसका एक अन्य उदाहरण सूची आइटम जोड़ें/हटाएं का डेमो है. ऐसे में, आपको बनाए गए हर कार्ड के लिए, एक खास view-transition-name जोड़ना होगा.

नतीजा

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