सीएसएस में इनलाइन एसवीजी


284

क्या सीएसएस में इनलाइन एसवीजी परिभाषा का उपयोग करना संभव है?

मेरा मतलब कुछ इस तरह है:

.my-class {
  background-image: <svg>...</svg>;
}

1
आप क्या करने की कोशिश कर रहे हैं, छवि "स्रोत" को स्टाइल शीट में जोड़ें?
ज़ूलुल

1
प्रस्तावित समाधान सीएसएस छवियों, एचटीएमएल <img>टैग और अन्य मामलों के लिए काम नहीं करेंगे यदि एसवीजी कई छवियों का मिश्रण है (जब तक कि एम्बेडेड नहीं है), पृष्ठभूमि छवि देखें एसवीजी मुखौटा के साथ बाहरी छवि का उपयोग नहीं करते हैं , और विशेष रूप से एसवीजी पर प्रतिबंध के रूप में उपयोग किया जाता है। एक छवि
स्किप्पी ले ग्रांड गौरौ

जवाबों:


376

हाँ यह संभव है। इसे इस्तेमाल करे:

body { background-image: 
        url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='%23F00'/><stop offset='90%' stop-color='%23fcc'/> </linearGradient><rect fill='url(%23gradient)' x='0' y='0' width='100%' height='100%'/></svg>");
      }

(ध्यान दें कि इस कार्य के लिए SVG सामग्री को url-escaped होना चाहिए, उदाहरण के लिए इसे #बदल दिया जाता है %23।)

यह IE 9 (जो SVG को सपोर्ट करता है) में काम करता है । डेटा-यूआरएल IE के पुराने संस्करणों में भी काम करते हैं (सीमाओं के साथ), लेकिन वे एसवीजी का मूल समर्थन नहीं करते हैं।


8
एकमात्र ब्राउज़र जिसमें यह अच्छी तरह से काम करता है वह है सफारी (5.1.4)। ओपेरा 11.62 में ढाल काला है, IE 9 और फ़ायरफ़ॉक्स 12 में यह सफेद है। Chrome 19 में, यह काम करता है आप% इकाइयों में SVG की चौड़ाई / ऊँचाई निर्दिष्ट करते हैं। मैं कहूंगा कि यह एक वास्तविक विशेषता की तुलना में अधिक विषमता है। हालांकि यह एक शांत खोज है।
toniedzwiedz

4
ठीक है ... फिर भी मैं अपने सहकर्मियों के चेहरों को देखने के लिए उत्सुक हूं, जब मैं उन्हें इस तरह से एक प्यारा सा राक्षस दिखाता हूं ताकि फिर से दिखाने के लिए धन्यवाद। मैं सिर्फ मानक विनिर्देश पर गया था और कहा था कि यह लगभग असंभव था, जो एक गलती (तरह की) हो गई
toniedzwiedz

18
यहां "ब्राउज़र असंगतता" ज्यादातर उचित URL भागने की कमी है, अंदर सब कुछ url()url-escaped होना चाहिए। उदाहरण के लिए jsfiddle.net/6WAtQ देखें , जो ओपेरा, फ़ायरफ़ॉक्स और सफारी में ठीक काम करता है।
एरिक डाहलस्ट्रम

3
क्या बेस -64 एनकोडेड एसवीजी से गैर-बेस 64 के बीच कोई अनुकूलता अंतर है? Base64 मेरे css फ़ाइल को ब्लॉट करता है, मैं सिर्फ इनलाइन svgs का उपयोग करने के बारे में सोच रहा हूँ ..
enapupe

4
ध्यान दें, वर्ण सेट निर्दिष्ट करने का मानक तरीका "; utf8" के बजाय; चारसेट = UTF-8 "है। tools.ietf.org/html/rfc2397
कीथ शॉ

240

थोड़ी देर, लेकिन अगर आप में से कोई भी एक पृष्ठभूमि के रूप में इनलाइन एसवीजी का उपयोग करने की कोशिश में पागल हो रहा है , तो ऊपर दिए गए पलायन सुझाव काफी काम नहीं करते हैं। एक के लिए, यह IE में काम नहीं करता है, और आपके एसवीजी की सामग्री के आधार पर तकनीक एफएफ जैसे अन्य ब्राउज़रों में परेशानी का कारण होगी।

यदि आप x64 को svg (संपूर्ण url नहीं, सिर्फ svg टैग और उसकी सामग्री!) को एन्कोड करते हैं, तो यह सभी ब्राउज़रों में काम करता है। यहाँ base64 में वही jsfiddle उदाहरण है: http://jsfiddle.net/vPA9z/3/

CSS अब इस तरह दिखता है:

body { background-image: 
    url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+PGxpbmVhckdyYWRpZW50IGlkPSdncmFkaWVudCc+PHN0b3Agb2Zmc2V0PScxMCUnIHN0b3AtY29sb3I9JyNGMDAnLz48c3RvcCBvZmZzZXQ9JzkwJScgc3RvcC1jb2xvcj0nI2ZjYycvPiA8L2xpbmVhckdyYWRpZW50PjxyZWN0IGZpbGw9J3VybCgjZ3JhZGllbnQpJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJy8+PC9zdmc+");

Base64 में कनवर्ट करने से पहले भागने वाले किसी भी URL को निकालना याद रखें। दूसरे शब्दों में, उपरोक्त उदाहरण ने रंग = '# fcc' को रंग में परिवर्तित कर दिया = '% 23fcc', आपको # पर वापस जाना चाहिए।

Base64 बेहतर काम करने का कारण यह है कि यह एकल और दोहरे उद्धरण चिह्नों और url से बचने के सभी मुद्दों को समाप्त करता है

यदि आप JS का उपयोग कर रहे हैं, तो आप window.btoa()अपने base64 svg का उत्पादन करने के लिए उपयोग कर सकते हैं ; और अगर यह काम नहीं करता है (यह स्ट्रिंग में अमान्य वर्णों के बारे में शिकायत कर सकता है), तो आप बस https://www.base64encode.org/ का उपयोग कर सकते हैं ।

डिव बैकग्राउंड सेट करने के लिए उदाहरण:

var mySVG = "<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='#F00'/><stop offset='90%' stop-color='#fcc'/> </linearGradient><rect fill='url(#gradient)' x='0' y='0' width='100%' height='100%'/></svg>";
var mySVG64 = window.btoa(mySVG);
document.getElementById('myDiv').style.backgroundImage = "url('data:image/svg+xml;base64," + mySVG64 + "')";
html, body, #myDiv {
  width: 100%;
  height: 100%;
  margin: 0;
}
<div id="myDiv"></div>

जेएस के साथ आप मक्खी पर एसवीजी उत्पन्न कर सकते हैं, यहां तक ​​कि इसके मापदंडों को भी बदल सकते हैं।

SVG का उपयोग करने पर बेहतर लेखों में से एक यहाँ है: http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/

उम्मीद है की यह मदद करेगा

माइक


2
धन्यवाद दोस्त। बेस 64 के साथ समाधान ने उत्कृष्ट काम किया, जबकि मैं स्वीकृत जवाब से मुश्किल में पड़ गया।
मार्सेल

1
तुमने मेरी जान बचाई। मेरी एक एसवीजी सीमा छवि थी जो क्रोम में काम कर रही थी लेकिन एफएफ पर नहीं। अब यह काम कर रहा है! : डी
पापीपो

मेरी भी मदद की (स्वीकार किए गए उत्तर को आजमाने के बाद) - यह निश्चित रूप से स्वीकृत उत्तर होना चाहिए।
कटाई

यदि यह अभी भी आपके लिए काम नहीं कर रहा है - सुनिश्चित करें कि आपके पास आधारभूत तत्व xmlnsसेट करने से पहलेsvg तत्व है जैसे कि आप <svg xmlns="http://www.w3.org/2000/svg">...</svg>ब्राउज़र में बेस 64-एनकोड करते हैं, तो कभी - कभी इसे बिना इसके चंक करें जब svg HTML में सीधे हो - यह मामला नहीं है :)
jave.web

मामले में किसी को अभी भी 6 + साल बाद इस उत्तर में दिख रही है: आप शायद नहीं करना चाहिए बेस 64 SVGs css-tricks.com/probably-dont-base64-svg
वोल्कर ई

38

जो लोग अभी भी संघर्ष कर रहे हैं, मैं इसे सभी आधुनिक ब्राउज़रों IE11 और इसके बाद के संस्करण पर काम करने में कामयाब रहा।

base64 मेरे लिए कोई विकल्प नहीं था क्योंकि मैं किसी भी दिए गए रंग के आधार पर SVG आइकन बनाने के लिए SASS का उपयोग करना चाहता था। उदाहरण के लिए: @include svg_icon(heart, #FF0000);इस तरह मैं किसी भी रंग में एक निश्चित आइकन बना सकता हूं, और केवल एसवीजी आकार को एक बार सीएसएस में एम्बेड करना होगा। (बेस 64 के साथ आपको एसवीजी को हर एक रंग में एम्बेड करना होगा जिसे आप उपयोग करना चाहते हैं)

तीन चीजें हैं जिनकी आपको जानकारी होनी चाहिए:

  1. URL को अपने SVG में शामिल करें जैसा कि दूसरों ने सुझाव दिया है, आपको IE11 में काम करने के लिए अपने पूरे SVG स्ट्रिंग को URL से एनकोड करना होगा। मेरे मामले में, मैं इस तरह के रूप क्षेत्रों में रंग मान बाहर छोड़ दिया fill="#00FF00"और stroke="#FF0000"और उन्हें एक एस.ए.एस.एस. चर के साथ बदल दिया fill="#{$color-rgb}"इसलिए इन रंग मैं चाहता हूँ के साथ बदला जा सकता है। आप URL के किसी भी ऑनलाइन कन्वर्टर का उपयोग कर सकते हैं बाकी स्ट्रिंग को एन्कोड करें। आप इस तरह एक SVG स्ट्रिंग के साथ समाप्त करेंगे:

    % 3Csvg% 20xmlns% 3 डी% 27http% 3A% 2F% 2Fwww.w3.org% 2F2000% 2Fsvg% 27% 20viewBox% 3 डी% 270% 200% 20494.572% 20494.572% 27% 20width% 3 डी% 27,512% 27% 20height% 3 डी % 27,512% 27% 3E% 0A% 20% 20% 3Cpath% 20D% 3 डी% 27M257.063% 200C127.136% 200% 2021.808% 20,105.33% 2021.808% 20235.266c0% 2041.012% 2010.535% 2079.541% 2028.973% 20113.104L3.825 % 20464.586c345% 2012.797% 2041.813% 2012.797% 2015.467% 200% 2029.872-4.721% 2041.813-12.797v158.184z% 27% 20% 20% 3D% 27 # ($ color-rgb) % 27% 2F% 3E% 3C% 3C% 2Fsvg% 3E


  1. डेटा URL में UTF8 CHARSET से बाहर निकलें अपना डेटा URL बनाते समय, आपको IE11 में काम करने के लिए चारसेट को छोड़ना होगा।

    नहीं पृष्ठभूमि-छवि: url (डेटा: छवि / svg + xml; utf-8,% 3Csvg% 2 ....)
    BUT पृष्ठभूमि-छवि: url (डेटा: छवि / svg + xml,% 3Csvg 2) ... ।)


  1. USE RGB () HEX रंगों का INSTEAD फ़ायरफ़ॉक्स एसवीजी कोड में # पसंद नहीं करता है। तो आपको अपने रंग हेक्स मानों को आरजीबी के साथ बदलने की आवश्यकता है।

    भरें = "# FF0000"
    लेकिन भरें = "आरजीबी (255,0,0)"

मेरे मामले में मैं दिए गए हेक्स को वैध आरजीबी मूल्य में बदलने के लिए एसएएसई का उपयोग करता हूं। जैसा कि टिप्पणियों में बताया गया है, यह आपके RGB स्ट्रिंग को अच्छी तरह से एनकोड करने के लिए सबसे अच्छा है (इसलिए अल्पविराम% 2C बन जाता है)

@mixin svg_icon($id, $color) {
   $color-rgb: "rgb(" + red($color) + "%2C" + green($color) + "%2C" + blue($color) + ")";
   @if $id == heart {
      background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20494.572%20494.572%27%20width%3D%27512%27%20height%3D%27512%27%3E%0A%20%20%3Cpath%20d%3D%27M257.063%200C127.136%200%2021.808%20105.33%2021.808%20235.266c0%204%27%20fill%3D%27#{$color-rgb}%27%2F%3E%3C%2Fsvg%3E');
   }
}

मुझे लगता है कि यह बहुत जटिल एसवीजी के लिए सबसे अच्छा समाधान नहीं हो सकता है (इनलाइन एसवीजी कभी भी उस मामले में नहीं है), लेकिन केवल कुछ रंगों के साथ फ्लैट आइकन के लिए यह वास्तव में बहुत अच्छा काम करता है।

मैं एक पूरे स्प्राइट बिटमैप को छोड़ने और अपने सीएसएस में इनलाइन एसवीजी के साथ बदलने में सक्षम था, जो संपीड़न के बाद केवल 25kb के आसपास निकला। तो यह आपकी सीएसएस फ़ाइल को फूले बिना आपकी साइट के अनुरोधों की मात्रा को सीमित करने का एक शानदार तरीका है।


1
Btw, मुझे सही अगर मैं गलत हूँ, लेकिन एक बार एन्कोड rgb(255,0,0)हो जाना चाहिए rgb(255%2C0%2C0)
कैप्सूल

1
मेरा मतलब था कि मैं RGB स्ट्रिंग को एन्कोड नहीं करता और यह अभी भी काम करता है। लेकिन यह एन्कोडिंग जैसा कि आपने उल्लेख किया है शायद बेहतर है।
डेवी बर्ट

1
खैर, वास्तव में, मैंने अभी-अभी फ़ायरफ़ॉक्स के %23ff0000लिए ठीक से काम किया है और ठीक काम करता है#ff0000
कैप्सूल

1
@ कैप्शन मैं नहीं जानता कि क्या हो रहा है, लेकिन% 23ff0000 एकमात्र तरीका है जो क्रोम और एफएफ दोनों पर मेरे लिए काम करता है। # ff0000 काम नहीं करता है, और न ही RGB (255,0,0) और आरजीबी (255% 2C0% 2C0) तरीके हैं।
आइडोग्राम

1
एक विधि ( SCSS
Sphinxxx

26

मैक / लिनक्स पर, आप आसानी से एक एसवीजी फ़ाइल को इस साधारण बैश कमांड के साथ सीएसएस पृष्ठभूमि विशेषता के लिए एक बेस 64 एनकोडेड मान में बदल सकते हैं:

echo "background: transparent url('data:image/svg+xml;base64,"$(openssl base64 < path/to/file.svg)"') no-repeat center center;"

मैक ओएस एक्स पर परीक्षण किया गया है। इस तरह से आप गंदगी से बचने वाले URL से भी बचते हैं।

याद रखें कि एसवीजी फ़ाइल को बेस 64 एन्कोडिंग इसके आकार को बढ़ाता है, देखें css-tricks.com ब्लॉग पोस्ट


2
पाठकों के लिए: कृपया केवल मतदान करने के बजाय अपनी राय दें, ताकि आपके सहयोग से इस उत्तर को बेहतर बनाया जा सके! इस तरह क्यू एंड ए साइटों में सहयोग आवश्यक है। धन्यवाद!
आरा

2
@ लॉरडेक्स आपने अपनी टिप्पणी में जो लिंक दिया है, वही मेरे उत्तर में है :)
आरा

10

मैंने एक कोडपेन डेमो दिया है जिसमें सीवीजी को इनलाइन सीएसएस में एम्बेड करने की समस्या थी। एक समाधान जो SCSS के साथ काम करता है, वह एक सरल url- एन्कोडिंग फ़ंक्शन का निर्माण करना है।

एक स्ट्रिंग रिप्लेसमेंट फंक्शन को बिल्ट-इन स्ट्रैस-स्लाइस, स्ट्रैस -इंडेक्स फंक्शन्स से बनाया जा सकता है ( सीएसएस-ट्रिक्स देखें , ह्यूगो जिराडेल के लिए धन्यवाद)।

फिर, बस की जगह %, <, >, ", ', साथ %xxकोड:

@function svg-inline($string){
  $result: str-replace($string, "<svg", "<svg xmlns='http://www.w3.org/2000/svg'");
  $result: str-replace($result, '%', '%25');
  $result: str-replace($result, '"', '%22');
  $result: str-replace($result, "'", '%27');
  $result: str-replace($result, ' ', '%20');
  $result: str-replace($result, '<', '%3C');
  $result: str-replace($result, '>', '%3E');
  @return "data:image/svg+xml;utf8," + $result;
}

$mySVG: svg-inline("<svg>...</svg>");

html {
  height: 100vh;
  background: url($mySVG) 50% no-repeat;
}

image-inlineकम्पास में एक सहायक फ़ंक्शन भी उपलब्ध है, लेकिन चूंकि यह कोडपेन में समर्थित नहीं है, इसलिए यह समाधान संभवतः उपयोगी हो सकता है।

CodePen पर डेमो: http://codepen.io/terabaud/details/PZdaJo/


1
मैंने एक पेन भी बनाया है जो आपको svg स्ट्रिंग्स को एक उचित सीएसएस बैकग्राउंड वैल्यू में बदलने की अनुमति देता है: s.codepen.io/LukyVj/debug/693cb30308bf67b8c30047c060eb तो, मूल रूप से, आप <svg><path></svg>शीर्ष टेक्स्टारिया में पेस्ट करते हैं , और यह सीधे सैनिटाइज्ड पथ को आउटपुट करेगा। एक url()मूल्य के भीतर ।
लुक्विज

1
इसने कमाल का काम किया। धन्यवाद। एक नोट। IE में काम करने के लिए आपको charset = utf8 का उपयोग करना होगा।
डैनियल लेफ्वेवर

4

3 पार्टी स्रोतों (जैसे Google चार्ट) से आने वाली इनलाइन एसवीजी xmlns="http://www.w3.org/2000/svg"में एसवीजी तत्व में XML नाम स्थान विशेषता ( ) नहीं हो सकती है (या शायद एसवीजी के प्रदान किए जाने के बाद इसे हटा दिया जाता है - न तो ब्राउज़र कंसोल से और न ही ब्राउज़र कंसोल से jQuery कमांड एसवीजी तत्व में नामस्थान दिखाते हैं)।

जब आपको अपनी अन्य आवश्यकताओं के लिए इन एसवीजी स्निपेट को फिर से प्रयोजन करना होगा (सीएसएस में पृष्ठभूमि-छवि या HTML में img तत्व) लापता नामस्थान के लिए देखें। नामस्थान ब्राउज़रों के बिना एसवीजी (एन्कोडिंग utf8 या बेस 64 की परवाह किए बिना) प्रदर्शित करने से इनकार कर सकते हैं।


4

मुझे एसवीजी के लिए एक समाधान मिला। लेकिन यह केवल वेबकिट के लिए काम करता है, मैं सिर्फ अपना वर्कअराउंड आपके साथ साझा करना चाहता हूं। मेरे उदाहरण में दिखाया गया है कि एक फिल्टर (पृष्ठभूमि-छवि: url ('# ग्लिफ़') काम नहीं कर रहा है) के माध्यम से डोम से एसवीजी तत्व का उपयोग कैसे किया जाता है।

इस SVG आइकन रेंडर के लिए आवश्यक सुविधाएँ:

  1. CSS (IE और Edge का समर्थन नहीं करता) का उपयोग करके HTML तत्वों में SVG फ़िल्टर प्रभाव लागू करना
  2. feImage टुकड़ा लोड समर्थन (फ़ायरफ़ॉक्स समर्थन नहीं करता है)

.test {
  /*  background-image: url('#glyph');
    background-size:100% 100%;*/
    filter: url(#image); 
    height:100px;
    width:100px;
}
.test:before {
   display:block;
   content:'';
   color:transparent;
}
.test2{
  width:100px;
  height:100px;
}
.test2:before {
   display:block;
   content:'';
   color:transparent;
   filter: url(#image); 
   height:100px;
   width:100px;
}
<svg style="height:0;width:0;" version="1.1" viewbox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg"
     xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
     <g id="glyph">
          <path id="heart" d="M100 34.976c0 8.434-3.635 16.019-9.423 21.274h0.048l-31.25 31.25c-3.125 3.125-6.25 6.25-9.375 6.25s-6.25-3.125-9.375-6.25l-31.202-31.25c-5.788-5.255-9.423-12.84-9.423-21.274 0-15.865 12.861-28.726 28.726-28.726 8.434 0 16.019 3.635 21.274 9.423 5.255-5.788 12.84-9.423 21.274-9.423 15.865 0 28.726 12.861 28.726 28.726z" fill="crimson"/>
     </g>
    <svg id="resized-glyph"  x="0%" y="0%" width="24" height="24" viewBox="0 0 100 100" class="icon shape-codepen">
      <use xlink:href="#glyph"></use>
    </svg>
     <filter id="image">
       <feImage xlink:href="#resized-glyph" x="0%" y="0%" width="100%" height="100%" result="res"/>
       <feComposite operator="over" in="res" in2="SourceGraphic"/>
    </filter>
 </defs>
</svg>
<div class="test">
</div>
<div class="test2">
</div>

एक और उपाय, यूआरएल एनकोड का उपयोग करें

var container = document.querySelector(".container");
var svg = document.querySelector("svg");
var svgText = (new XMLSerializer()).serializeToString(svg);
container.style.backgroundImage = `url(data:image/svg+xml;utf8,${encodeURIComponent(svgText)})`;
.container{
  height:50px;
  width:250px;
  display:block;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
}
<svg  height="100" width="500" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
</svg>
<div class="container"></div>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.