हुडीनी - सीएसएस की जानकारी देना

क्या आपने कभी सोचा है कि सीएसएस कितने काम करती है? किसी एक एट्रिब्यूट में बदलाव करने पर, आपकी पूरी वेबसाइट अचानक किसी दूसरे लेआउट में दिखने लगती है. यह एक तरह का जादू है. अब तक, हम वेब डेवलपर कम्यूनिटी के तौर पर, सिर्फ़ इस जादू को देख पा रहे थे. अगर हमें अपनी ज़रूरत के हिसाब से कोई इफ़ेक्ट बनाना हो, तो क्या करें? अगर हमें जादूगर बनना है, तो क्या करना होगा?

Houdini!

Houdini टास्क फ़ोर्स में Mozilla, Apple, Opera, Microsoft, HP, Intel, और Google के इंजीनियर शामिल हैं. वे वेब डेवलपर को सीएसएस इंजन के कुछ हिस्सों के बारे में बताने के लिए मिलकर काम कर रहे हैं. टास्क फ़ोर्स, ड्राफ़्ट के कलेक्शन पर काम कर रही है. इसका मकसद, उन्हें W3C से स्वीकार करवाना है, ताकि वे वेब के असल स्टैंडर्ड बन सकें. उन्होंने अपने लिए कुछ हाई-लेवल लक्ष्य तय किए और उन्हें स्पेसिफ़िकेशन ड्राफ़्ट में बदल दिया. इससे, स्पेसिफ़िकेशन के कम लेवल वाले ड्राफ़्ट का एक सेट तैयार हुआ.

जब कोई व्यक्ति "Houdini" के बारे में बात करता है, तो आम तौर पर इन ड्राफ़्ट के कलेक्शन का ही मतलब होता है. इस लेख को लिखने के समय, ड्राफ़्ट की सूची अधूरी है और कुछ ड्राफ़्ट सिर्फ़ प्लेसहोल्डर हैं.

खास जानकारी

वर्कलेट (स्पेसिफ़िकेशन)

वर्कलेट अपने-आप काम के नहीं होते. यह एक ऐसा कॉन्सेप्ट है जिसे बाद में कई ड्राफ़्ट बनाने के लिए शुरू किया गया था. अगर "वर्कलेट" पढ़ते समय आपको वेब वर्कर्स की याद आई है, तो आपका अनुमान सही है. इनमें बहुत सारे कॉन्सेप्ट ओवरलैप होते हैं. तो जब हमारे पास पहले से ही कर्मचारी हैं, तो हमें नई चीज़ क्यों चाहिए?

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

इसका मतलब है कि वेब वर्कर्स, Houdini के प्लान के मुताबिक काम नहीं कर सकते. इसलिए, वर्कलेट का आविष्कार किया गया. वर्कलेट, मेथड के कलेक्शन को तय करने के लिए, ES2015 क्लास का इस्तेमाल करते हैं. इन मेथड के सिग्नेचर, वर्कलेट के टाइप के हिसाब से पहले से तय होते हैं. ये हल्के और कम समय तक चलने वाले होते हैं.

CSS Paint API (स्पेसिफ़िकेशन)

Chrome 65 में, Paint API डिफ़ॉल्ट रूप से चालू होता है. ज़्यादा जानकारी देने वाला पेज पढ़ें.

कंपोज़िटर वर्कलेट

यहां बताए गए एपीआई का इस्तेमाल नहीं किया जा सकता. कंपोजिटर वर्कलेट को फिर से डिज़ाइन किया गया है. अब इसे "ऐनिमेशन वर्कलेट" के तौर पर दिखाया जाएगा. एपीआई के मौजूदा वर्शन के बारे में ज़्यादा जानें.

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

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

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

कंपोज़िटर वर्कलेट.

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

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

यहां पैरलॅक्स स्क्रोलिंग के लिए, कंपोजिटर वर्कलेट का इस्तेमाल करके, पूरी जानकारी दी गई है.

// main.js
window.compositorWorklet.import('worklet.js')
    .then(function() {
    var animator = new CompositorAnimator('parallax');
    animator.postMessage([
        new CompositorProxy($('.scroller'), ['scrollTop']),
        new CompositorProxy($('.parallax'), ['transform']),
    ]);
    });

// worklet.js
registerCompositorAnimator('parallax', class {
    tick(timestamp) {
    var t = self.parallax.transform;
    t.m42 = -0.1 * self.scroller.scrollTop;
    self.parallax.transform = t;
    }

    onmessage(e) {
    self.scroller = e.data[0];
    self.parallax = e.data[1];
    };
});

रॉबर्ट फ़्लैक ने कंपोजिटर वर्कलेट के लिए एक polyfill लिखा है, ताकि आप इसे आज़मा सकें. हालांकि, इससे परफ़ॉर्मेंस पर काफ़ी ज़्यादा असर पड़ेगा.

लेआउट वर्कलेट (स्पेसिफ़िकेशन)

स्पेसिफ़िकेशन का पहला ड्राफ़्ट तैयार हो गया है. लागू करने में थोड़ा समय लगता है.

फिर से, इसके लिए स्पेसिफ़िकेशन में कुछ नहीं है, लेकिन कॉन्सेप्ट दिलचस्प है: अपना लेआउट लिखें! लेआउट वर्कलेट की मदद से, display: layout('myLayout') किया जा सकता है. साथ ही, नोड के बॉक्स में नोड के चाइल्ड को व्यवस्थित करने के लिए, JavaScript को चलाया जा सकता है.

बेशक, सीएसएस के flex-box लेआउट को पूरी तरह से JavaScript में लागू करने की प्रोसेस, नेटिव तरीके से लागू करने की प्रोसेस के मुकाबले धीमी होती है. हालांकि, ऐसे कई उदाहरण हैं जहां कम समय में ज़्यादा काम करने के लिए, परफ़ॉर्मेंस में फ़ायदा मिल सकता है. कल्पना कीजिए कि ऐसी वेबसाइट जिसमें टाइल के अलावा कुछ नहीं है, जैसे कि Windows 10 या मेसनरी-स्टाइल लेआउट. ऐब्सलूट और फ़िक्स्ड पोज़िशनिंग का इस्तेमाल नहीं किया जाता और न ही z-index होता है. साथ ही, एलिमेंट में कभी ओवरलैप नहीं किया जाता, न ही किसी तरह का बॉर्डर या ओवरफ़्लो होता है. री-लेआउट पर इन सभी जांचों को स्किप करने से, परफ़ॉर्मेंस में बढ़ोतरी हो सकती है.

registerLayout('random-layout', class {
    static get inputProperties() {
        return [];
    }
    static get childrenInputProperties() {
        return [];
    }
    layout(children, constraintSpace, styleMap) {
        const width = constraintSpace.width;
        const height = constraintSpace.height;
        for (let child of children) {
            const x = Math.random()*width;
            const y = Math.random()*height;
            const constraintSubSpace = new ConstraintSpace();
            constraintSubSpace.width = width-x;
            constraintSubSpace.height = height-y;
            const childFragment = child.doLayout(constraintSubSpace);
            childFragment.x = x;
            childFragment.y = y;
        }

        return {
            minContent: 0,
            maxContent: 0,
            width: width,
            height: height,
            fragments: [],
            unPositionedChildren: [],
            breakToken: null
        };
    }
});

टाइप किया गया CSSOM (स्पेसिफ़िकेशन)

टाइप किया गया CSSOM (सीएसएस ऑब्जेक्ट मॉडल या कैस्केडिंग स्टाइल शीट ऑब्जेक्ट मॉडल), एक ऐसी समस्या को हल करता है जिसका सामना शायद हम सभी ने किया हो और जिसे हमने सहन करना सीख लिया हो. मैं आपको JavaScript की एक लाइन के साथ इसका उदाहरण दूंगा:

    $('#someDiv').style.height = getRandomInt() + 'px';

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

यह ड्राफ़्ट ज़्यादा परिपक्व में से एक है और पॉलिफ़िल पर पहले से काम किया जा रहा है. (डिसक्लेमर: पॉलीफ़िल का इस्तेमाल करने से, कंप्यूटेशनल ओवरहेड और भी बढ़ जाएगा. इसका मकसद यह दिखाना है कि एपीआई का इस्तेमाल करना कितना आसान है.)

आपको स्ट्रिंग के बजाय, एलिमेंट के StylePropertyMap पर काम करना होगा. यहां हर सीएसएस एट्रिब्यूट की अपनी कुंजी और उससे जुड़ी वैल्यू टाइप होती है. width जैसे एट्रिब्यूट की वैल्यू टाइप में LengthValue होता है. LengthValue, em, rem, px, percent वगैरह जैसी सभी सीएसएस यूनिट की डिक्शनरी होती है. height: calc(5px + 5%) को सेट करने पर LengthValue{px: 5, percent: 5} मिलेगी. box-sizing जैसी कुछ प्रॉपर्टी सिर्फ़ कुछ कीवर्ड को स्वीकार करती हैं. इसलिए, उनमें KeywordValue वैल्यू टाइप होती है. इसके बाद, रनटाइम के दौरान उन एट्रिब्यूट की वैधता की जांच की जा सकती है.

<div style="width: 200px;" id="div1"></div>
<div style="width: 300px;" id="div2"></div>
<div id="div3"></div>
<div style="margin-left: calc(5em + 50%);" id="div4"></div>
var w1 = $('#div1').styleMap.get('width');
var w2 = $('#div2').styleMap.get('width');
$('#div3').styleMap.set('background-size',
    [new SimpleLength(200, 'px'), w1.add(w2)])
$('#div4')).styleMap.get('margin-left')
    // => {em: 5, percent: 50}

प्रॉपर्टी और वैल्यू

(spec)

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

["--scale-x", "--scale-y"].forEach(function(name) {
document.registerProperty({
    name: name,
    syntax: "<number>",
    inherits: false,
    initialValue: "1"
    });
});

फ़ॉन्ट मेट्रिक

फ़ॉन्ट मेट्रिक ठीक वैसी ही होती हैं जैसी वे दिखती हैं. जब मैं स्ट्रिंग X को फ़ॉन्ट Y के साथ साइज़ Z में रेंडर करता/करती हूं, तो बॉउंडिंग बॉक्स (या बॉउंडिंग बॉक्स) क्या होता है? अगर Ruby एनोटेशन का इस्तेमाल किया जाता है, तो क्या होगा? इस सुविधा के लिए काफ़ी अनुरोध किए गए हैं. इसलिए, Houdini को यह सुविधा उपलब्ध कराना चाहिए.

लेकिन रुकें, यहां और भी हैं!

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

डेमो

मैंने डेमो के लिए कोड को ओपन सोर्स किया है (पॉलीफ़िल का इस्तेमाल करके लाइव डेमो).