<picture>
एलिमेंट अपने-आप कुछ भी रेंडर नहीं करता. इसके बजाय, यह अंदरूनी <img>
एलिमेंट के लिए डिसिज़न इंजन के तौर पर काम करता है. इससे यह पता चलता है कि क्या रेंडर करना है. <picture>
, <audio>
और <video>
एलिमेंट से पहले से सेट किए गए उदाहरण को फ़ॉलो करता है: एक रैपर एलिमेंट, जिसमें अलग-अलग <source>
एलिमेंट होते हैं.
<picture>
<source …>
<source …>
<img …>
</picture …>
यह अंदरूनी <img>
आपको पुराने ब्राउज़र के लिए भरोसेमंद फ़ॉलबैक पैटर्न भी देता है, लेकिन रिस्पॉन्सिव इमेज के साथ काम नहीं करता:
अगर उपयोगकर्ता का ब्राउज़र <picture>
एलिमेंट की पहचान नहीं करता, तो उसे अनदेखा कर दिया जाता है. इसके बाद, <source>
एलिमेंट भी खारिज कर दिए जाते हैं,
क्योंकि ब्राउज़र उन्हें पहचान नहीं पाएगा या <video>
या <audio>
पैरंट के बिना, उसके लिए काम का संदर्भ नहीं देगा.
हालांकि, कोई भी ब्राउज़र इन <img>
एलिमेंट की पहचान कर लेता है और src
में बताए गए सोर्स को उम्मीद के मुताबिक रेंडर किया जाएगा.
<picture>
के साथ "कला के निर्देशन में बनी" इमेज
पेज पर मौजूद इमेज के साइज़ के हिसाब से इमेज के कॉन्टेंट या आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) में बदलाव करने को, आम तौर पर "आर्ट के लिए भेजी गई" रिस्पॉन्सिव इमेज कहा जाता है. srcset
और sizes
को इस तरह से डिज़ाइन किया गया है कि ये उपयोगकर्ता के ब्राउज़र के निर्देशों के मुताबिक, बिना किसी रुकावट के सोर्स को बदल देते हैं.
हालांकि, कई बार कॉन्टेंट को बेहतर तरीके से हाइलाइट करने के लिए, ब्रेकपॉइंट के सभी सोर्स में बदलाव करना होता है. ठीक उसी तरह, जिस तरह पेज लेआउट में बदलाव किया जाता है.
उदाहरण के लिए: छोटे से मुख्य फ़ोकस वाली पूरी चौड़ाई वाली हेडर इमेज, बड़े व्यूपोर्ट पर अच्छी तरह से काम कर सकती है:
हालांकि, छोटे व्यूपोर्ट के हिसाब से छोटा करने पर, इमेज का मुख्य फ़ोकस हट सकता है:
इन इमेज सोर्स का विषय एक जैसा ही होता है. हालांकि, सब्जेक्ट पर बेहतर तरीके से फ़ोकस करने के लिए, आपको ब्रेकपॉइंट के हिसाब से इमेज सोर्स के अनुपातों को बदलना होगा. उदाहरण के लिए, इमेज के बीच में ज़्यादा बेहतर तरीके से ज़ूम करना और काट-छांटे गए किनारों पर मौजूद बारीकियां:
इस तरह की "काट-छांट" करने के लिए सीएसएस का इस्तेमाल किया जा सकता है. हालांकि, इससे उपयोगकर्ता को उस इमेज के पूरे डेटा के लिए अनुरोध करना पड़ सकता है, भले ही वे उसे कभी न देखें.
हर source
एलिमेंट में ऐसे एट्रिब्यूट होते हैं जो source
को चुनने के लिए शर्तें तय करते हैं: media
, जो मीडिया क्वेरी स्वीकार करता है और type
, जो मीडिया टाइप (जिसे पहले "MIME टाइप" कहा जाता था) को स्वीकार करता है. सोर्स ऑर्डर में, पहले <source>
को चुना जाता है, ताकि उपयोगकर्ता के मौजूदा ब्राउज़िंग कॉन्टेक्स्ट से मैच किया जा सके. साथ ही, उस source
पर मौजूद srcset
एट्रिब्यूट के कॉन्टेंट का इस्तेमाल किया जाएगा, ताकि उस कॉन्टेक्स्ट के लिए सही कैंडिडेट तय किए जा सकें. इस उदाहरण में, उपयोगकर्ता के व्यूपोर्ट साइज़ से मेल खाने वाले media
एट्रिब्यूट वाले पहले source
को चुना गया होगा:
<picture>
<source media="(min-width: 1200px)" srcset="wide-crop.jpg">
<img src="close-crop.jpg" alt="…">
</picture>
आपको हमेशा अंदरूनी img
के आखिरी को क्रम में बताना चाहिए—अगर कोई भी source
एलिमेंट अपने media
या type
मापदंड से मेल नहीं खाता, तो इमेज "डिफ़ॉल्ट" सोर्स के तौर पर काम करेगी. अगर min-width
मीडिया क्वेरी का इस्तेमाल किया जा रहा है, तो जैसा कि पिछले कोड में दिखाया गया है, आपको सबसे बड़े सोर्स पहले रखने चाहिए. max-width
मीडिया क्वेरी का इस्तेमाल करते समय, आपको सबसे छोटे सोर्स को पहले रखना चाहिए.
<picture>
<source media="(max-width: 400px)" srcset="mid-bp.jpg">
<source media="(max-width: 800px)" srcset="high-bp.jpg">
<img src="highest-bp.jpg" alt="…">
</picture>
जब आपकी ओर से तय की गई शर्तों के आधार पर कोई सोर्स चुना जाता है, तो source
पर मौजूद srcset
एट्रिब्यूट को <img>
पर इस तरह से पास किया जाता है कि उसे <img>
पर ही सबमिट किया गया है. इसका मतलब है कि आप आर्ट से जुड़े इमेज सोर्स को भी ऑप्टिमाइज़ करने के लिए sizes
का इस्तेमाल कर सकते हैं.
<picture>
<source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
<source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
<img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>
बेशक, चुने गए <source>
एलिमेंट के हिसाब से अलग-अलग अनुपात वाली इमेज की परफ़ॉर्मेंस से जुड़ी समस्या हो सकती है:
<img>
सिर्फ़ एक width
और height
एट्रिब्यूट के साथ काम करता है, लेकिन उन एट्रिब्यूट को हटाने से उपयोगकर्ता को बहुत खराब अनुभव मिल सकता है.
इसे समझने के लिए, हाल ही के लेकिन काम करने वाले—एचटीएमएल एट्रिब्यूट में जोड़ने से, <source>
एलिमेंट में height
और width
एट्रिब्यूट का इस्तेमाल किया जा सकता है. ये, लेआउट शिफ़्ट को ठीक वैसे ही कम करते हैं जैसे <img>
पर करते हैं. साथ ही, आपके लेआउट में, <source>
एलिमेंट को चुनने के लिए ज़रूरी जगह होती है.
<picture>
<source
media="(min-width: 800px)"
srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
width="1600"
height="800">
<img src="fallback.jpg"
srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
sizes="calc(100vw - 2em)"
width="1200"
height="750"
alt="…">
</picture>
इस बात पर ध्यान देना ज़रूरी है कि व्यूपोर्ट के साइज़ के आधार पर फ़ैसला लेने के साथ-साथ कई और फ़ैसले लेने के लिए भी आर्ट डायरेक्शन का इस्तेमाल किया जा सकता है. हालांकि, ऐसा करना इसलिए ज़रूरी है, क्योंकि ऐसे ज़्यादातर मामलों में srcset
/sizes
की मदद से ज़्यादा बेहतर तरीके से हैंडल किया जा सकता है. उदाहरण के लिए, उपयोगकर्ता की पसंद के हिसाब से तय की गई कलर स्कीम के हिसाब से इमेज के बेहतर स्रोत को चुनना:
<picture>
<source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
<img srcset="hero-light.jpg">
</picture>
type
एट्रिब्यूट
type
एट्रिब्यूट की मदद से, <picture>
एलिमेंट के एक अनुरोध वाले डिसिज़न इंजन का इस्तेमाल किया जा सकता है. इससे, आपको सिर्फ़ उन ब्राउज़र पर इमेज का फ़ॉर्मैट दिखेगा जिन पर यह सुविधा काम करती है.
जैसा कि आपने इमेज फ़ॉर्मैट और कंप्रेस करने में सीखा है, लेकिन ब्राउज़र जिस एन्कोडिंग को पार्स नहीं कर सकता उसे इमेज डेटा के तौर पर भी नहीं पहचाना जा सकता.
<picture>
एलिमेंट के लॉन्च होने से पहले, नए इमेज फ़ॉर्मैट को दिखाने के सबसे अच्छे फ़्रंट-एंड सलूशन के लिए ब्राउज़र को किसी इमेज फ़ाइल का अनुरोध करना और उसे पार्स करने की कोशिश करनी पड़ती थी. इसके बाद ही, यह तय किया जाता था कि किसी इमेज को हटाना है या नहीं और उसे लोड करना है या नहीं. इसका एक सामान्य उदाहरण
इन पंक्तियों के साथ एक स्क्रिप्ट थी:
<img src="image.webp"
data-fallback="image.jpg"
onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
alt="...">
इस पैटर्न के साथ, अब भी हर ब्राउज़र में image.webp
के लिए अनुरोध किया जाता है—इसका मतलब है कि WebP का इस्तेमाल किए बिना, ब्राउज़र को ट्रांसफ़र करने का फ़ायदा नहीं मिलेगा. इसके बाद, जो ब्राउज़र WebP एन्कोडिंग को पार्स नहीं कर पाते वे onerror
इवेंट को थ्रो करेंगे और data-fallback
वैल्यू को src
में बदल देंगे. इससे बर्बाद हुआ हल नहीं मिला, लेकिन फिर से, फ़्रंट-एंड पर इस तरह का ही तरीका
उपलब्ध था. याद रखें कि किसी भी कस्टम स्क्रिप्टिंग के चलाए जाने—या पार्स किए जाने का मौका मिलने से पहले, ब्राउज़र इमेज के लिए अनुरोध करना शुरू कर देता है—इसलिए हम इस प्रक्रिया को पहले से नहीं रोक सकते.
<picture>
एलिमेंट को खास तौर पर, उन ग़ैर-ज़रूरी अनुरोधों से बचने के लिए डिज़ाइन किया गया है. ब्राउज़र के लिए अनुरोध किए बिना उस फ़ॉर्मैट की पहचान नहीं की जा सकती जो काम नहीं करता. इसके बावजूद, type
एट्रिब्यूट, ब्राउज़र को चेतावनी देता है कि सोर्स को पहले कोड में बदला जाता है. इससे, ब्राउज़र यह तय कर पाता है कि अनुरोध करने का अनुरोध किया जाए या नहीं.
type
एट्रिब्यूट में, हर <source>
के srcset
एट्रिब्यूट में बताए गए इमेज स्रोत का मीडिया का टाइप (पहले MIME टाइप था) दिया जाता है. यह ब्राउज़र को वह सारी जानकारी दे देता है जिसकी ज़रूरत उसे तुरंत यह तय करने के लिए होती है कि source
से मिले इमेज कैंडिडेट को बिना बाहरी अनुरोध किए, डिकोड किया जा सकता है या नहीं—अगर मीडिया टाइप की पहचान नहीं हो पाती है, <source>
और उसके सभी उम्मीदवारों को अनदेखा कर दिया जाता है, और ब्राउज़र आगे बढ़ जाता है.
<picture>
<source type="image/webp" srcset="pic.webp">
<img src="pic.jpg" alt="...">
</picture>
यहां, WebP एन्कोडिंग की सुविधा वाला कोई भी ब्राउज़र, <source>
एलिमेंट के type
एट्रिब्यूट में दिए गए image/webp
मीडिया टाइप की पहचान करेगा. इसलिए, उस <source>
को चुनें. srcset
में सिर्फ़ एक विकल्प दिया गया है, जो <img>
को अनुरोध, ट्रांसफ़र, और रेंडर करने के लिए pic.webp
का निर्देश देगा. अगर कोई ब्राउज़र WebP के लिए बिना काम करता है, तो वह source
को अनदेखा कर देगा. अगर इसके उलट कोई निर्देश नहीं दिया जाता है, तो <img>
, src
के कॉन्टेंट को उसी तरह रेंडर करेगा जैसा कि 1992 से किया जा रहा है.
यहां आपको type="image/jpeg"
के साथ दूसरे <source>
एलिमेंट के बारे में बताने की ज़रूरत नहीं है. इसे सभी के लिए उपलब्ध कराया जा सकता है.
उपयोगकर्ता चाहे जो भी ब्राउज़ कर रहा हो, ये सारे काम एक ही फ़ाइल में ट्रांसफ़र से किए जाते हैं. साथ ही, इमेज के उन सोर्स पर बैंडविड्थ बर्बाद नहीं होती जिन्हें रेंडर नहीं किया जा सकता. साथ ही, यह आने वाले समय पर निर्भर करता है: नए और ज़्यादा असरदार फ़ाइल फ़ॉर्मैट, अपने खुद के मीडिया टाइप के साथ आएंगे. साथ ही, picture
की वजह से हम उनका फ़ायदा उठा पाएंगे. इसमें JavaScript, सर्वरसाइड की डिपेंडेंसी, और <img>
की तेज़ स्पीड शामिल नहीं होगी.
रिस्पॉन्सिव इमेज का भविष्य
यहां बताए गए सभी मार्कअप पैटर्न ने स्टैंडर्ड तय करने के मामले में काफ़ी बड़ा बदलाव किया है: किसी चीज़ के काम करने के तरीके को
<img>
के तौर पर सेट करना और उसका मुख्य प्लैटफ़ॉर्म होना कोई आसान काम नहीं था. जिन समस्याओं को हल करने के लिए किए गए बदलाव उनकी
चीज़ों में थे उनके काम को सिर्फ़ इतना ही नहीं कहा गया. अगर आपको लगता है कि इन मार्कअप पैटर्न की मदद से काफ़ी सुधार किया जा सकता है, तो आप बिलकुल सही हैं. शुरू से ही इन स्टैंडर्ड का मकसद, आने वाली टेक्नोलॉजी को एक बुनियाद उपलब्ध कराना था, ताकि आने वाली टेक्नोलॉजी को और बेहतर बनाया जा सके.
ये सभी समाधान, मार्कअप पर निर्भर करते हैं. इसलिए, इन्हें सर्वर के शुरुआती पेलोड में शामिल किया जाता है और इमेज सोर्स के लिए अनुरोध करने के लिए, ब्राउज़र समय पर पहुंचता है. इस सीमा की वजह से, sizes
एट्रिब्यूट की वैल्यू मुश्किल होती है.
हालांकि, इन सुविधाओं को वेब प्लैटफ़ॉर्म पर शुरू किया गया था. इसलिए, इमेज के अनुरोधों को रोकने का एक नेटिव तरीका पेश किया गया.
जब तक पेज का लेआउट पता नहीं चलता, तब तक loading="lazy"
एट्रिब्यूट वाले <img>
एलिमेंट के लिए अनुरोध नहीं किया जाता. ऐसा इसलिए किया जाता है, ताकि पेज को रेंडर करने की प्रोसेस पूरी होने तक, उपयोगकर्ता के शुरुआती व्यूपोर्ट के बाहर की इमेज के लिए किए जाने वाले अनुरोधों को रोका जा सके. इससे हो सकता है कि वे ग़ैर-ज़रूरी अनुरोधों से बचें. ये अनुरोध करते समय, ब्राउज़र पेज के लेआउट को पूरी तरह से समझता है. इसलिए, इस तरह के मामलों में मैन्युअल तरीके से लिखे गए sizes
एट्रिब्यूट के काम से बचने के लिए, एचटीएमएल एट्रिब्यूट के साथ sizes="auto"
एट्रिब्यूट का सुझाव दिया गया है.
इसके अलावा, कुछ ऐसे <picture>
एलिमेंट भी जोड़े गए हैं जिन्हें जल्द ही तैयार किया गया है. इससे, पेज लेआउट को बेहतर बनाने में कुछ दिलचस्प बदलाव देखने को मिलते हैं. हालांकि व्यूपोर्ट की जानकारी हाई-लेवल लेआउट से जुड़े फ़ैसले लेने के लिए सही आधार है, लेकिन यह हमें डेवलपमेंट के लिए पूरी तरह से कॉम्पोनेंट-लेवल का तरीका अपनाने से रोकती है. इसका मतलब है कि एक ऐसा कॉम्पोनेंट जिसे पेज लेआउट के किसी भी हिस्से में छोड़ा जा सकता है और जो उस कॉम्पोनेंट के स्पेस के हिसाब से सही स्टाइल में काम करता है. इस समस्या की वजह से कंटेनर क्वेरी बनाई गईं: आइटम को स्टाइल करने का तरीका, जो सिर्फ़ व्यूपोर्ट के बजाय उनके पैरंट कंटेनर के साइज़ के आधार पर बनाया जाता है.
कंटेनर क्वेरी सिंटैक्स सिर्फ़ स्थिर ही है—और लिखने के समय ब्राउज़र की सुविधा बहुत सीमित है—इसके लिए चालू की गई ब्राउज़र टेक्नोलॉजी, <picture>
एलिमेंट को इसी काम के तरीके उपलब्ध कराती हैं: एक संभावित container
एट्रिब्यूट जो व्यूपोर्ट के साइज़ के बजाय, <picture>
एलिमेंट के <img>
की जगह के आधार पर <source>
को चुनने की ज़रूरी शर्तों को पूरा करता है.
अगर आपको समझ नहीं आ रहा, तो इसकी एक अच्छी वजह है: वेब मानकों पर की जा रही बातचीत अभी चल रही है, लेकिन अभी यह तय नहीं हो पाया है. इसलिए, फ़िलहाल इनका इस्तेमाल नहीं किया जा सकता.
रिस्पॉन्सिव इमेज मार्कअप यह वादा करता है कि समय के साथ काम करना ज़्यादा आसान हो जाएगा, जैसे किसी वेब टेक्नोलॉजी की तरह. हालांकि, इस मार्कअप को हाथ से लिखने के बोझ को आसान बनाने के लिए कई सेवाएं, टेक्नोलॉजी, और फ़्रेमवर्क मौजूद हैं. अगले मॉड्यूल में, हम देखेंगे कि मॉडर्न डेवलपमेंट वर्कफ़्लो में इमेज फ़ॉर्मैट, कंप्रेशन, और रिस्पॉन्सिव इमेज के बारे में सेव की गई सारी जानकारी को कैसे इंटिग्रेट किया जाए.