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

लंबाई से इंट्रिन्सिक साइज़िंग कीवर्ड और फिर से लंबाई पर आसानी से ट्रांज़िशन और ऐनिमेशन करने के लिए, 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) ऐनिमेशन नहीं कर सकते. सीएसएस वर्किंग ग्रुप की समस्या के बारे में इस टिप्पणी में आपको इस बारे में जानकारी मिल सकती है.

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

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 को मिलाकर, आपको दोनों दिशाओं में ऐनिमेशन मिल सकता है: