ग्राफ़िक को SVG <symbol> में एक बार परिभाषित करें, फिर हर दिखाई देने वाले SVG के भीतर <use> से उसकी ID का संदर्भ दें। हर इंस्टेंस को उसका अपना आकार दें और आसपास के पेज को CSS से व्यवस्थित करें। SVG दस्तावेज़ की संरचना।

यह ट्यूटोरियल उन लोगों के लिए है जो Mac पर HTML पेज संपादित करते हैं और कई टेक्स्ट लेबल के पास एक ही छोटा ग्राफ़िक दिखाना चाहते हैं। पूरे उदाहरण में सिंथेटिक टाइलें, सामान्य HTML और CSS का उपयोग किया गया है। इसमें किसी फ़्रेमवर्क, JavaScript, डाउनलोड की गई कलाकृति या बिल्ड चरण की ज़रूरत नहीं है।

एक सिंबल से कई दिखाई देने वाले ग्राफ़िक्स कैसे बनते हैं?

<symbol> एक ग्राफ़िकल टेम्पलेट है। यह अपने आप दिखाई नहीं देता; <use> संदर्भ एक दिखाई देने वाला इंस्टेंस बनाता है। परिभाषा को दस्तावेज़ में एक बार रखें, फिर जहाँ ग्राफ़िक चाहिए वहाँ एक छोटा SVG रैपर जोड़ें। MDN के अनुसार, दोनों एलिमेंट व्यापक रूप से उपलब्ध हैं। MDN: symbol।

यहाँ अहम अंतर यह है कि लेखक द्वारा बार-बार पाथ लिखने से बचना और ब्राउज़र के रेंडरिंग कार्य से बचना अलग बातें हैं। आपके HTML में पाथ की एक परिभाषा होती है, लेकिन ब्राउज़र हर <use> के लिए एक रेंडर किया गया इंस्टेंस फिर भी बनाता है। MDN इसे ऐसे क्लोन के रूप में बताता है जो DOM में उजागर नहीं होता। पुनः उपयोग से स्रोत को बनाए रखना आसान होता है; इसका अर्थ यह नहीं कि कई दिखाई देने वाले ग्राफ़िक्स एक ही रेंडर की गई वस्तु बन जाते हैं। MDN: use।

लेबल और आइकन वाले पेज में, लेबल HTML में रखें और हर आइकन को उसका अपना SVG रैपर दें। WHATWG SVG को HTML में एम्बेडेड, phrasing और flow content मानता है, जिससे इन रैपर को सामान्य पेज सामग्री के बीच रखना संभव होता है। HTML Standard: SVG।

एक परिभाषा और तीन इंस्टेंस वाला पूरा पेज बनाएँ

अपने Mac पर किसी साधारण टेक्स्ट एडिटर में svg-reuse.html नाम की फ़ाइल बनाएँ। नीचे दिया पूरा दस्तावेज़ पेस्ट करें, उसे सेव करें और अपने डेस्कटॉप ब्राउज़र में खोलें। .html एक्सटेंशन रखें और फ़ाइल को रिच-टेक्स्ट दस्तावेज़ के बजाय सादा टेक्स्ट के रूप में सेव करें।

इस उदाहरण में एक ही <path> से दो तिरछी टाइलें परिभाषित की गई हैं। तीन संदर्भ उसी ज्यामिति को अलग-अलग आकारों और रंगों में दिखाते हैं। हर संदर्भ href="#demo-tiles" का उपयोग करता है; वर्तमान रूप href है, जबकि xlink:href अप्रचलित है। MDN: use attributes।

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Reusable tile symbol</title>
  <style>
    body {
      margin: 2rem;
      font-family: system-ui, sans-serif;
      color: #263445;
    }
    .symbol-bank {
      position: absolute;
      width: 0;
      height: 0;
      overflow: hidden;
    }
    .samples {
      display: flex;
      flex-wrap: wrap;
      gap: 1.5rem;
    }
    .sample {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      padding: 1rem;
      border: 1px solid #cbd5df;
    }
    .icon {
      display: block;
      width: 24px;
      height: 24px;
      flex: none;
    }
    .icon-large { width: 48px; height: 48px; }
    .icon-medium { width: 32px; height: 32px; }
    .blue { color: #2457a7; }
    .purple { color: #7140a0; }
  </style>
</head>
<body>
  <svg class="symbol-bank" width="0" height="0" aria-hidden="true">
    <symbol id="demo-tiles" viewBox="0 0 24 24"
            preserveAspectRatio="xMidYMid meet">
      <path fill="currentColor"
            d="M4 4H10V10H4Z M14 14H20V20H14Z"></path>
    </symbol>
  </svg>

  <main>
    <h1>Tile samples</h1>
    <div class="samples">
      <div class="sample">
        <svg class="icon" width="24" height="24"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Small tiles</span>
      </div>

      <div class="sample blue">
        <svg class="icon icon-large" width="48" height="48"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Large tiles</span>
      </div>

      <div class="sample purple">
        <svg class="icon icon-medium" width="32" height="32"
             viewBox="0 0 24 24" aria-hidden="true">
          <use href="#demo-tiles" width="24" height="24"></use>
        </svg>
        <span>Medium tiles</span>
      </div>
    </div>
  </main>
</body>
</html>

अपेक्षित परिणाम तीन बॉर्डर वाले नमूने हैं, जिनमें एक जैसी तिरछी टाइलें होंगी। पहले नमूने में बॉडी टेक्स्ट का रंग, दूसरे में नीला और तीसरे में बैंगनी रंग होगा। उनके SVG बॉक्स क्रमशः 24, 48 और 32 CSS पिक्सेल वर्ग के हैं। नमूने कैसे पंक्तियों में लिपटते हैं, यह देखने के लिए ब्राउज़र विंडो को संकरा करें।

यहाँ दिखाई देने वाली आकृतियाँ सजावटी हैं, क्योंकि पास के लेबल सामग्री देते हैं। इसलिए SVG रैपर aria-hidden="true" का उपयोग करते हैं। इससे वे दृष्टिगत रूप से छिपे बिना एक्सेसिबिलिटी ट्री से हट जाते हैं। सजावटी ग्राफ़िक्स के लिए यह तरीका रखें; ऐसी छवि पर इसका उपयोग न करें जिसमें ऐसी जानकारी हो जो टेक्स्ट में मौजूद न हो। MDN: aria-hidden।

कौन-सी सेटिंग पेज लेआउट और SVG लेआउट नियंत्रित करती हैं?

यहाँ तीन अलग-अलग काम हैं: HTML घटकों को व्यवस्थित करना, हर SVG बॉक्स का आकार तय करना और चित्र को उस बॉक्स में फिट करना। किसी एक काम की सेटिंग बदलने से बाकी दो पर असर ज़रूरी नहीं कि पड़े।

काम उदाहरण में सेटिंग क्या बदलें
पेज पर नमूनों को व्यवस्थित करना .samples में flexbox और wrapping का उपयोग है यहाँ अंतराल या wrapping बदलें
हर ग्राफ़िक को उसके लेबल के साथ संरेखित करना .sample में flexbox और align-items: center का उपयोग है यहाँ घटक का संरेखण बदलें
दिखाई देने वाले SVG बॉक्स का आकार तय करना .icon और उसकी size classes यहाँ CSS की width और height बदलें
चित्र के निर्देशांक तय करना viewBox="0 0 24 24" कलाकृति की निर्देशांक सीमाएँ बदलने पर इसे बदलें
संदर्भित सिंबल का अंदरूनी आकार तय करना <use> की width और height 24 हैं इन्हें इस उदाहरण के अंदरूनी निर्देशांक क्षेत्र के अनुरूप रखें
चित्र को अनुपात बनाए रखते हुए फिट करना preserveAspectRatio="xMidYMid meet" इसे तभी बदलें जब फिट करने का अलग व्यवहार चाहिए

Flexbox किसी flex कंटेनर के सीधे बच्चों को व्यवस्थित करता है। इसलिए बाहरी कंटेनर नमूनों को व्यवस्थित करता है, और हर अंदरूनी कंटेनर SVG को लेबल के पास रखता है। Flexbox एक समय में एक ही आयाम में काम करता है; लिपटी हुई पंक्तियाँ अपना स्थान स्वतंत्र रूप से बाँटती हैं। अगर डिज़ाइन में पंक्तियों और स्तंभों का समन्वित लेआउट चाहिए, तो CSS Grid पेज लेआउट का उपयुक्त विकल्प है। MDN: Basic concepts of flexbox।

SVG के भीतर <use> का लेआउट मॉडल अलग है। इसके x और y मान SVG निर्देशांक प्रणाली में ग्राफ़िक्स को खिसकाते हैं। ये HTML घटकों के बीच का अंतराल तय नहीं करते। इसकी width और height संदर्भित सिंबल का viewport आकार दे सकती हैं; सीधे संदर्भित पाथ या समूह को सामान्य रूप से स्केल करने का नियंत्रण ये नहीं देतीं। W3C: Layout of re-used graphics।

बड़े इंस्टेंस में भी अंदरूनी आयाम 24 क्यों हैं?

बाहरी SVG का viewBox 24-बाई-24 निर्देशांक क्षेत्र बताता है। इसका CSS बॉक्स 48-बाई-48 पिक्सेल का हो सकता है, जबकि इसके अंदरूनी निर्देशांक वही रहते हैं। <use> उस अंदरूनी 24-बाई-24 क्षेत्र को भरता है और बाहरी SVG उसे बड़े दिखाई देने वाले बॉक्स में मैप करता है। MDN viewBox को चार संख्याओं के रूप में परिभाषित करता है: न्यूनतम x, न्यूनतम y, चौड़ाई और ऊँचाई। MDN: viewBox।

इसी कलाकृति का उपयोग करके एक उदाहरणात्मक गणना में, 48 पिक्सेल का बॉक्स 24 निर्देशांक इकाइयों को 48 / 24 = 2 के स्केल पर मैप करता है। टाइल की ज्यामिति निर्देशांक 4 से 20 तक फैली है, इसलिए उसका कुल रंगा हुआ क्षेत्र (20 - 4) × 2 = 32 पिक्सेल का होगा। बाकी जगह चित्र के भीतर जानबूझकर छोड़े गए मार्जिन के कारण है।

इससे समझ आता है कि किसी आइकन की CSS width बढ़ाने से उसकी रंगी हुई आकृति ज़रूरी नहीं कि पूरी चौड़ाई भर दे। इसकी भरपाई के लिए पेज मार्जिन बदलने से पहले viewBox के भीतर ज्यामिति की सीमाएँ देखें।

आयताकार SVG बॉक्स में क्या होता है?

xMidYMid meet के साथ चित्र एक समान अनुपात में स्केल होता है, बीच में रहता है और उपलब्ध viewport में पूरा viewBox समा जाता है। इसलिए चौड़े आयत में वर्गाकार चित्र के दोनों ओर खाली जगह रहती है। none विकृति की अनुमति देता है; slice अनुपात बनाए रखता है, लेकिन viewBox के कुछ हिस्से viewport से बाहर जाने देता है। जब पूरा ग्राफ़िक दिखाई देना चाहिए, तब meet का उपयोग करें। MDN: preserveAspectRatio।

हर इंस्टेंस का रंग अलग कैसे रखें?

पाथ fill="currentColor" का उपयोग करता है। यह कीवर्ड एलिमेंट का color मान लेता है, जिससे एक ही चित्र आसपास के टेक्स्ट के रंग के अनुसार दिख सकता है। उदाहरण में .blue या .purple नियम बदलने से लेबल और उसकी टाइलों, दोनों का रंग बदलता है। MDN: currentColor keyword।

यह हर इंस्टेंस में इनहेरिटेंस के ज़रिए काम करता है। SVG का पुनः उपयोग मॉडल जनरेट की गई सामग्री को <use> होस्ट से इनहेरिट की गई शैलियाँ देता है। स्रोत पाथ पर सीधे घोषित स्थिर रंग, पैरेंट से मिले इनहेरिटेड fill पर प्राथमिकता पाएगा। हर इंस्टेंस का रंग अलग रखना हो तो साझा ज्यामिति में स्थिर रंग न रखें। W3C: Style Scoping and Inheritance।

दिखाई देने वाले रैपर के ज़रिए जनरेट किए गए पाथ तक पहुँचने के लिए .blue path जैसे selector पर निर्भर न रहें। जनरेट की गई सामग्री पुनः उपयोग की शैडो ट्री में होती है, इसलिए उसके पूर्वजों के संबंध सामान्य नेस्टेड HTML से अलग होते हैं। रैपर या उसके कंटेनर पर color सेट करें और स्रोत ज्यामिति में currentColor बनाए रखें। W3C: Style Scoping and Inheritance।

पुनः उपयोग किया गया सिंबल गलत दिखे तो क्या जाँचें?

संदर्भ से शुरू करके बाहर की ओर जाँचें। इस क्रम से गायब ग्राफ़िक और गलत आकार या जगह पर मौजूद ग्राफ़िक में अंतर पता चलता है, ताकि हर बदलाव किसी खास तंत्र को ठीक करे।

  1. लक्ष्य जाँचें। पुष्टि करें कि href="#demo-tiles" परिभाषा के id="demo-tiles" से मेल खाता है। दस्तावेज़ ट्री में यह ID अद्वितीय रखें। W3C: The id attribute।
  2. दिखाई देने वाले रैपर के आयाम जाँचें। शून्य आकार वाली .symbol-bank क्लास केवल परिभाषा वाले कंटेनर पर रखें। हर दिखाई देने वाले इंस्टेंस का बॉक्स गैर-शून्य होना चाहिए, जैसा .icon में दिखाया गया है।
  3. निर्देशांक सीमाएँ जाँचें। पुष्टि करें कि कलाकृति घोषित viewBox के भीतर आती है। अनपेक्षित खाली जगह अप्रयुक्त चित्र निर्देशांकों के कारण हो सकती है। MDN: viewBox।
  4. संदर्भित एलिमेंट का प्रकार जाँचें। अगर आपने सिंबल की जगह सीधे पाथ का संदर्भ दिया है, तो <use> की width और height उसे उसी तरह स्केल नहीं करेंगी। इस पैटर्न के लिए सिंबल और उसका viewBox वापस रखें। MDN: use।
  5. रंग की घोषणाएँ जाँचें। हर इंस्टेंस के लिए और selector जोड़ने से पहले स्रोत में स्थिर रंग देखें।
  6. पेज कंटेनर जाँचें। अगर ग्राफ़िक सही रेंडर हो रहा है, लेकिन लेबल से बहुत दूर है, तो घटक का CSS gap या संरेखण बदलें। MDN: Basic concepts of flexbox।

उदाहरण को किसी मौजूदा पेज में जोड़ते समय, सिंबल बैंक एक बार डालें, CSS को मिलाएँ और अतिरिक्त घटकों में केवल दिखाई देने वाला SVG रैपर कॉपी करें। इस छोटे दस्तावेज़ की संरचनात्मक जाँच में संतुलित एलिमेंट, अद्वितीय ID और एक ही पाथ पर पहुँचने वाले तीन संदर्भ शामिल थे; इन जाँचों से ब्राउज़र में रेंडरिंग की पुष्टि नहीं होती। जिन Mac ब्राउज़र का समर्थन करना चाहते हैं, उनमें पेज खोलें और आकार, अंतराल तथा रंग देखें।

साझा चित्र बदलने के लिए उसकी एकमात्र पाथ परिभाषा संपादित करें। किसी एक इंस्टेंस को बदलने के लिए उसके रैपर का आकार या इनहेरिटेड रंग बदलें। इन ज़िम्मेदारियों को अलग रखने से आपको पुनः उपयोग योग्य कलाकृति और हर इंस्टेंस की जगह पर भरोसेमंद नियंत्रण मिलता है।

स्रोत