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

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

Houdini में शामिल हों!

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

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

खास जानकारी

वर्कलेट (spec)

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

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

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

सीएसएस पेंट एपीआई (spec)

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

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

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

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

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

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

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

जैसा कि नाम से ही पता चलता है, कंपोज़िटर वर्कलेट से आपको कंपोज़िटर में हुक करने की सुविधा मिलती है. इससे, एलिमेंट की लेयर, जिसे पहले से पेंट किया जा चुका होता है, को अन्य लेयर के ऊपर रखा जाता है और लेयर्ड किया जाता है.

खास जानकारी पाने के लिए, ब्राउज़र को बताया जा सकता है कि आपको किसी खास DOM नोड के लिए कंपोज़िटिंग प्रोसेस में जोड़ना है. साथ ही, स्क्रोल करने की पोज़िशन, 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 लिखा है, ताकि आप इसे आज़मा सकें.

लेआउट वर्कलेट (spec)

पहले असल स्पेसिफ़िकेशन ड्राफ़्ट का सुझाव दिया गया है. इसे लागू करने में बहुत कम समय लगता है.

फिर से, इसकी खासियत व्यावहारिक रूप से खाली है, लेकिन कॉन्सेप्ट दिलचस्प है: अपना लेआउट खुद लिखें! लेआउट वर्कलेट से आपको 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 (spec)

टाइप किया गया CSSOM (सीएसएस ऑब्जेक्ट मॉडल या कैस्केडिंग स्टाइल शीट ऑब्जेक्ट मॉडल) उस समस्या का समाधान करता है जिसका सामना शायद हम सभी ने किया है और हमने अभी-अभी उसे हल करना सीखा है. मुझे JavaScript की एक पंक्ति से बताने दें:

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

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

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

स्ट्रिंग के बजाय, आप एलिमेंट के 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 फ़ॉन्ट वाली स्ट्रिंग X को साइज़ Z पर रेंडर करता/करती हूं, तब बाउंडिंग बॉक्स (या बाउंडिंग बॉक्स) क्या होता है? रूबी एनोटेशन का इस्तेमाल करने पर क्या होगा? इसकी बहुत बार मांग की गई और हुडीनी को आखिर में अपनी इच्छाओं को पूरा करना चाहिए.

पर और भी हैं!

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

डेमो

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