ऊंचाई पर ऐनिमेट करें: स्वचालित; सीएसएस में, (और साइज़ बदलने वाले दूसरे कीवर्ड)

लंबाई से इंट्रिन्सिक साइज़िंग कीवर्ड और फिर से लंबाई पर आसानी से ट्रांज़िशन और ऐनिमेशन करने के लिए, interpolate-size प्रॉपर्टी या calc-size() फ़ंक्शन का इस्तेमाल करें.

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

परिचय

height: auto को ऐनिमेट करने की सुविधा, सीएसएस की वह सुविधा है जिसके लिए अक्सर अनुरोध किया जाता है. उस अनुरोध में थोड़ा बदलाव करके, height के बजाय width प्रॉपर्टी को ट्रांज़िशन किया जा सकता है. इसके अलावा, min-content, max-content, और fit-content जैसे कीवर्ड से दिखाए गए किसी भी अन्य इंटिग्रल साइज़ पर भी ट्रांज़िशन किया जा सकता है.

उदाहरण के लिए, नीचे दिए गए डेमो में, आइकॉन पर कर्सर घुमाने पर लेबल अपनी सामान्य चौड़ाई में आसानी से ऐनिमेट हो जाएं, तो अच्छा होगा.

इस्तेमाल की गई सीएसएस यहां दी गई है:

nav a {
    width: 80px;
    overflow-x: clip;
    transition: width 0.35s ease; /* 👈 Transition the width */

    &:hover,
    &:focus-visible {
        width: max-content; /* 👈 Doesn't work with transitions */
    }
}

width प्रॉपर्टी को ट्रांज़िशन करने के लिए transition का एलान किया गया है और :hover पर width: auto का एलान किया गया है. इसके बावजूद, कोई ट्रांज़िशन नहीं होता. इसके बजाय, बदलाव अचानक होता है.

interpolate-size की मदद से, इनट्रिन्सिक साइज़िंग कीवर्ड पर स्विच करना और उनसे स्विच करना

ब्राउज़र सहायता

  • Chrome: 129.
  • Edge: यह सुविधा काम नहीं करती.
  • Firefox: समर्थित नहीं.
  • Safari: यह सुविधा काम नहीं करती.

सोर्स

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

इसकी डिफ़ॉल्ट वैल्यू numeric-only है, जो इंटरपोलेशन को चालू नहीं करती. प्रॉपर्टी को allow-keywords पर सेट करने पर, लंबाई से सीएसएस के इंट्रिन्सिक साइज़िंग कीवर्ड में इंटरपोलेशन के लिए ऑप्ट-इन किया जाता है. ऐसा तब किया जाता है, जब ब्राउज़र उन कीवर्ड को ऐनिमेट कर सकता है.

हर स्पेसिफ़िकेशन के हिसाब से:

  • numeric-only: <intrinsic-size-keyword> को इंटरपोल नहीं किया जा सकता.
  • allow-keywords: दो वैल्यू को इंटरपोलेट किया जा सकता है, अगर उनमें से एक <intrinsic-size-keyword> और दूसरी <length-percentage> है. […]

interpolate-size प्रॉपर्टी, इनहेरिट की जाने वाली प्रॉपर्टी है. इसलिए, पूरे दस्तावेज़ के लिए, इन्सट्रिंसिक साइज़िंग कीवर्ड पर ट्रांज़िशन करने और उनसे ट्रांज़िशन करने की सुविधा चालू करने के लिए, :root पर इसका एलान किया जा सकता है. हमारा सुझाव है कि आप इस तरीके का इस्तेमाल करें.

/* Opt-in the whole page to interpolate sizes to/from keywords */
:root {
    interpolate-size: allow-keywords; /* 👈 */
}

नीचे दिए गए डेमो में, यह नियम कोड में जोड़ा गया है. इस वजह से, width: auto से और उसमें एनिमेशन ठीक से काम करते हैं. हालांकि, ऐसा सिर्फ़ उन ब्राउज़र में होता है जिनमें यह सुविधा काम करती है:

चुनने वाले टूल की मदद से, ऑप्ट-इन की पहुंच को सीमित करना

अगर आपको allow-keywords ऑप्ट-इन को सिर्फ़ अपने दस्तावेज़ के किसी सबट्री के लिए सीमित करना है, तो :root से सिलेक्टर को सिर्फ़ उस एलिमेंट के लिए एडजस्ट करें जिसे आपको टारगेट करना है. उदाहरण के लिए, अगर आपके पेज का <header> इस तरह के ट्रांज़िशन के साथ काम नहीं करता है, तो नीचे बताए गए तरीके से, ऑप्ट-इन को सिर्फ़ <main> एलिमेंट और उसके डिसेंडेंट तक सीमित किया जा सकता है:

main { /* 👈 Scope the opt-in to only <main> and its descendants */
    interpolate-size: allow-keywords;
}

साइज़ करने वाले कीवर्ड के लिए, ऐनिमेशन की सुविधा को डिफ़ॉल्ट रूप से क्यों नहीं चालू किया जाता?

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

इस सुविधा को डेवलप करने के दौरान, इस व्यवहार को चालू करने के विकल्प पर रिसर्च की गई थी. वर्किंग ग्रुप को पता चला है कि इसे डिफ़ॉल्ट रूप से चालू करने पर, यह पुराने वर्शन के साथ काम नहीं करता. इसकी वजह यह है कि कई स्टाइल शीट यह मानती हैं कि साइज़ तय करने वाले इंट्रिन्सिक कीवर्ड (जैसे, auto या min-content) ऐनिमेशन नहीं कर सकते. सीएसएस वर्किंग ग्रुप की समस्या के बारे में इस टिप्पणी में आपको इस बारे में जानकारी मिल सकती है.

इसलिए, प्रॉपर्टी ऑप्ट-इन है. अपनी इनहेरिटेंस विशेषता की वजह से, पूरे दस्तावेज़ के लिए ऑप्ट इन करना, :root के लिए सिर्फ़ interpolate-size: allow-sizes का एलान है. जैसा कि पहले बताया गया है.

calc-size() की मदद से, इनट्रिन्सिक साइज़िंग कीवर्ड पर स्विच करना और उनसे स्विच करना

ब्राउज़र सहायता

  • Chrome: 129.
  • Edge: 129.
  • Firefox: समर्थित नहीं.
  • Safari: समर्थित नहीं.

सोर्स

इंट्रिन्सिक साइज़िंग कीवर्ड में इंटरपोलेशन की सुविधा चालू करने का एक और तरीका है, calc-size() फ़ंक्शन का इस्तेमाल करना. इससे, इंट्रिन्सिक साइज़ पर सुरक्षित और बेहतर तरीके से गणित के हिसाब से काम किया जा सकता है.

फ़ंक्शन में दो आर्ग्युमेंट इस्तेमाल किए जाते हैं:

  • calc-size के आधार पर, जो <intrinsic-size-keyword> हो सकता है, लेकिन नेस्ट किया गया calc-size() भी हो सकता है.
  • calc-size कैलकुलेशन, जिसकी मदद से calc-size के आधार पर कैलकुलेशन किए जा सकते हैं. calc-size के आधार का रेफ़रंस देने के लिए, size कीवर्ड का इस्तेमाल करें.

यहां कुछ उदाहरण दिए गए हैं:

width: calc-size(auto, size);        // = the auto width, unaltered
width: calc-size(min-content, size); // = the min-content width, unaltered

ओरिजनल डेमो में calc-size() जोड़ने पर, कोड कुछ ऐसा दिखता है:

nav a {
    width: 80px;
    overflow-x: clip;
    transition: width 0.35s ease;

    &:hover,
    &:focus-visible {
        width: calc-size(max-content, size); /* 👈 */
    }
}

विज़ुअल तौर पर, नतीजा वैसा ही होता है जैसा interpolate-size का इस्तेमाल करने पर होता है. इसलिए, इस खास मामले में आपको interpolate-size का इस्तेमाल करना चाहिए.

calc-size() की सबसे बड़ी खासियत यह है कि यह कैलकुलेशन कर सकता है. interpolate-size से ऐसा नहीं किया जा सकता:

width: calc-size(auto, size - 10px); // = The auto width minus 10 pixels
width: calc-size(min-content, size + 1rem); // = The min-content width plus 1rem
width: calc-size(max-content, size * .5);   // = Half the max-content width

उदाहरण के लिए, अगर आपको किसी पेज पर मौजूद सभी पैराग्राफ़ का साइज़, 50px के सबसे करीबी मल्टीपल पर सेट करना है, तो इनका इस्तेमाल करें:

p {
    width: calc-size(fit-content, round(up, size, 50px));
    height: calc-size(auto, round(up, size, 50px));
}

calc-size() की मदद से, दो calc-size() के बीच इंटरपोलेशन भी किया जा सकता है. ऐसा तब किया जा सकता है, जब दोनों के कैलकुलेट किए गए साइज़ के बेस एक जैसे हों. यह भी कुछ ऐसा है जिसे interpolate-size से पूरा नहीं किया जा सकता.

#element {
    width: min-content; /* 👈 */
    transition: width 0.35s ease;

    &:hover {
        width: calc-size(min-content, size + 10px); /* 👈 */
    }
}

calc() में <intrinsic-size-keyword> को अनुमति क्यों नहीं देनी चाहिए?

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

इसकी एक वजह यह है कि कैलकुलेशन करते समय, आपको इंट्रिन्सिक साइज़िंग कीवर्ड को आपस में मिलाने और मैच करने की अनुमति नहीं है. उदाहरण के लिए, हो सकता है कि आप calc(max-content - min-content) लिखना चाहें, जो मान्य दिखता है, लेकिन असल में ऐसा नहीं है. calc-size() सही तरीके से काम करता है, क्योंकि यह calc() के उलट, अपने पहले आर्ग्युमेंट के तौर पर सिर्फ़ एक <intrinsic-size-keyword> स्वीकार करता है.

इसकी दूसरी वजह कॉन्टेक्स्ट अवेयरनेस है. कुछ लेआउट एल्गोरिदम, खास साइज़ वाले कीवर्ड के लिए खास तरीके से काम करते हैं. calc-size() को साफ़ तौर पर, <length> के बजाय किसी खास साइज़ को दिखाने के लिए तय किया गया है. इसकी मदद से, वे एल्गोरिदम calc-size(<intrinsic-size-keyword>, …) को <intrinsic-size-keyword> के तौर पर इस्तेमाल कर सकते हैं. इससे उस कीवर्ड के लिए, उसके खास व्यवहार को बनाए रखा जा सकता है.

किस तरीके का इस्तेमाल करना है?

ज़्यादातर मामलों में, :root पर interpolate-size: allow-keywords का एलान करें. यह वास्तविक आकार वाले कीवर्ड में और उनसे एनिमेशन सक्षम करने का सबसे आसान तरीका है, क्योंकि यह एक लाइन का बेहद ज़रूरी उदाहरण है.

/* Opt-in the whole page to animating to/from intrinsic sizing keywords */
:root {
    interpolate-size: allow-keywords; /* 👈 */
}

यह कोड, प्रगतिशील बेहतर बनाने का एक अच्छा तरीका है. जिन ब्राउज़र में यह काम नहीं करता उनमें ट्रांज़िशन का इस्तेमाल नहीं किया जाएगा.

अगर आपको कैलकुलेशन करने जैसी चीज़ों पर पूरा कंट्रोल चाहिए या ऐसा व्यवहार इस्तेमाल करना है जिसे सिर्फ़ calc-size() कर सकता है, तो calc-size() का इस्तेमाल किया जा सकता है.

#specific-element {
    width: 50px;

    &:hover {
        width: calc-size(fit-content, size + 1em); /* 👈 Only calc-size() can do this */
    }
}

हालांकि, अपने कोड में calc-size() का इस्तेमाल करने के लिए, आपको उन ब्राउज़र के लिए फ़ॉलबैक शामिल करने होंगे जो calc-size() के साथ काम नहीं करते. उदाहरण के लिए, साइज़ की अतिरिक्त जानकारी जोड़ना या @supports का इस्तेमाल करके, सुविधा का पता लगाने की सुविधा का इस्तेमाल करना.

width: fit-content;
width: calc-size(fit-content, size + 1em);
       /* 👆 Browsers with no calc-size() support will ignore this second declaration,
             and therefore fall back to the one on the line before it. */

ज़्यादा डेमो

यहां कुछ और डेमो दिए गए हैं जो interpolate-size: allow-keywords का इस्तेमाल करके अपना फ़ायदा उठाते हैं.

सूचनाएं

नीचे दिया गया डेमो, @starting-style के इस डेमो का हिस्सा है. अलग-अलग ऊंचाई वाले आइटम जोड़ने के लिए, कोड में बदलाव किया गया.

ऐसा करने के लिए, पूरा पेज साइज़ कीवर्ड इंटरपोलेशन के लिए ऑप्ट इन करता है. साथ ही, हर .item एलिमेंट पर height को auto पर सेट किया जाता है. अगर ऐसा नहीं है, तो कोड ठीक वैसा ही है जैसा फ़ोर्क करने से पहले लिया गया था.

:root {
    interpolate-size: allow-keywords; /* 👈 */
}

.item {
    height: auto; /* 👈 */

    @starting-style {
        height: 0px;
    }
}

<details> एलिमेंट को ऐनिमेट करना

इस तरह के इंटरपोलेशन का इस्तेमाल तब किया जा सकता है, जब आपको जानकारी ज़ाहिर करने वाले विजेट या खास अकॉर्डियन को खुलते समय ऐनिमेट करना हो. एचटीएमएल में, इसके लिए <details> एलिमेंट का इस्तेमाल किया जाता है.

interpolate-size: allow-keywords की मदद से, ये काम किए जा सकते हैं:

@supports (interpolate-size: allow-keywords) {
    :root {
        interpolate-size: allow-keywords;
    }
    
    details {
        transition: height 0.5s ease;
        height: 2.5rem;
        
        &[open] {
            height: auto;
            overflow: clip; /* Clip off contents while animating */
        }
    }
}

हालांकि, जैसा कि आपको दिख रहा है, ऐनिमेशन सिर्फ़ तब चलता है, जब जानकारी देने वाला विजेट खुला हो. इस समस्या को हल करने के लिए, Chrome ::details-content स्यूडो कोड पर काम कर रहा है. यह इस साल के आखिर में Chrome में उपलब्ध होगा. इस बारे में हम आने वाले समय में एक पोस्ट में बताएंगे. interpolate-size: allow-keywords और ::details-content को मिलाकर, दोनों दिशाओं में ऐनिमेशन बनाया जा सकता है: