CSS'de satır içi SVG


285

CSS'de satır içi SVG tanımı kullanmak mümkün müdür?

Gibi bir şey demek istiyorum:

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

1
Ne yapmaya çalışıyorsunuz, stil sayfasına resim "kaynak" eklemek mi?
Zuul

1
<img>SVG birkaç görüntünün karışımı (gömülü değilse), CSS görüntüleri, HTML etiketleri ve diğer durumlar için önerilen çözümlerin işe yaramayacağına dikkat edin, harici görüntü çalışmayan maskeli arka plan resmi SVG'sine ve özel olarak kullanılan SVG kısıtlamalarına bakın bir görüntü .
Skippy le Grand Gourou

Yanıtlar:


377

Evet mümkün. Bunu dene:

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>");
      }

(Bunun çalışması için SVG içeriğinin URL'den kaçması gerektiğini unutmayın, örn. #İle değiştirilir %23.)

Bu IE 9'da çalışır (SVG'yi destekler) . Veri URL'leri IE'nin eski sürümlerinde de (sınırlamalarla) çalışır, ancak yerel olarak SVG'yi desteklemez.


8
İyi çalıştığı tek tarayıcı Safari'dir (5.1.4). Opera 11.62'de gradyan siyahtır, IE 9 ve Firefox 12'de beyazdır. Chrome 19'da, SVG'nin genişliğini / yüksekliğini% birim olarak belirtmeniz SİZSİZ çalışır. Bunun gerçek bir özellikten daha tuhaf olduğunu söyleyebilirim. Yine de serin bir bulmak.
toniedzwiedz

4
Doğru ... yine de onlara böyle sevimli küçük bir canavar gösterdiğimde iş arkadaşlarımın yüzlerindeki görünüşleri görmek için endişeliyim, bu yüzden mümkün olduğunu gösterdiğiniz için tekrar teşekkürler. Sadece standart spesifikasyona gittim ve bunun neredeyse imkansız olduğunu belirttim, ki bu bir hataydı (bir çeşit)
toniedzwiedz

18
Buradaki "tarayıcı uyumsuzluğu" çoğunlukla uygun URL çıkışından yoksunluktur, içindeki her şey url()url'den kaçmalıdır. Opera, Firefox ve Safari'de iyi çalışan bir örnek için jsfiddle.net/6WAtQ adresine bakın .
Erik Dahlström

3
Base64 kodlu svg ile base64 olmayanlar arasında herhangi bir uyumluluk farkı var mı? Base64 benim css dosya bloats, ben sadece inline svgs kullanın düşünüyorum ..
enapupe

4
Not: Karakter setini belirtmenin standart yolunun "; utf8" yerine "; charset = UTF-8" kullanılmasıdır. tools.ietf.org/html/rfc2397
Keith Shaw

240

Biraz geç, ancak herhangi biriniz satır içi SVG'yi arka plan olarak kullanmaya çalışırken çıldırdıysanız , yukarıdaki kaçış önerileri işe yaramıyor. Birincisi, IE'de çalışmaz ve SVG'nizin içeriğine bağlı olarak teknik, FF gibi diğer tarayıcılarda sorun yaratacaktır.

Base64, svg'yi (tüm url'yi değil, yalnızca svg etiketini ve içeriğini!) Kodlarsanız, tüm tarayıcılarda çalışır. Base64'teki aynı jsfiddle örneği: http://jsfiddle.net/vPA9z/3/

CSS şimdi şöyle görünüyor:

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

Base64'e dönüştürmeden önce kaçan URL'leri kaldırmayı unutmayın. Başka bir deyişle, yukarıdaki örnek color = '# fcc' renge dönüştürüldü = '% 23fcc' gösterdi, # tuşuna geri dönmelisiniz.

Base64'ün daha iyi çalışmasının nedeni, tek ve çift tırnak ve URL'den kaçan tüm sorunları ortadan kaldırmasıdır.

JS kullanıyorsanız, window.btoa()base64 svg'nizi üretmek için kullanabilirsiniz ; ve işe yaramazsa (dizedeki geçersiz karakterlerden şikayet edebilir), https://www.base64encode.org/ adresini kullanabilirsiniz .

Bir div arka planı ayarlama örneği:

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>

JS ile parametrelerini değiştirerek bile anında SVG üretebilirsiniz.

SVG kullanımıyla ilgili daha iyi makalelerden biri: http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/

Bu yardımcı olur umarım

mikrofon


2
Teşekkürler dostum. Base64 ile çözüm mükemmel çalıştı, kabul edilen cevapla başım belaya girdi.
Marcel

1
Hayatımı kurtardın. Kromda çalışan ancak FF'de olmayan bir SVG kenarlık resmim vardı. Şimdi çalışıyor! : D
Papipo

Bana da yardımcı oldu (kabul edilen cevabı denedikten sonra zaman kaybettikten sonra) - bu kesinlikle kabul edilen cevap olmalıdır.
Katai

Bu hala sizin için çalışmıyorsa, tarayıcılar gibi base64 kodlamadan önce öğeye xmlnsayarlanmış bir özniteliğe sahip olduğunuzdan emin olun , svg doğrudan svg<svg xmlns="http://www.w3.org/2000/svg">...</svg>
HTML'deyken bazen onsuz yığınlar

Birinin hala 6+ yıl sonra bu cevaba bakması durumunda: Muhtemelen 64 SVG'yi css-tricks.com/probably-dont-base64-svg
Volker E.

38

Hala mücadele eden insanlar için, tüm modern tarayıcılar IE11 ve üstü üzerinde çalışmayı başardım.

base64 benim için bir seçenek değildi çünkü herhangi bir renge dayalı SVG simgeleri oluşturmak için SASS kullanmak istedim. Örneğin:@include svg_icon(heart, #FF0000); Bu şekilde herhangi bir renkte belirli bir simge oluşturabilirim ve SVG şeklini yalnızca bir kez CSS'ye gömmek zorundayım. (base64 ile SVG'yi kullanmak istediğiniz her renge gömmeniz gerekir)

Dikkat etmeniz gereken üç şey vardır:

  1. URL SVG'NİZİ KODLAMA Başkalarının önerdiği gibi IE11'de çalışması için URL'nin tamamını SVG dizeniz olarak kodlamanız gerekir. Benim durumumda, ben gibi alanlarda renk değerlerini dışında kalan fill="#00FF00"ve stroke="#FF0000"bir SUKDÖ'nün değişkeni ile değiştirilir fill="#{$color-rgb}"bu İstediğim renk ile değiştirilebilir böylece. Dizenin geri kalanını kodlamak için herhangi bir çevrimiçi dönüştürücüyü kullanabilirsiniz . Bunun gibi bir SVG dizesi elde edersiniz:

    % 3Csvg% 20xmlns% 3D% 27http% 3A% 2F% 2Fwww.w3.org% 2F2000% 2Fsvg% 27% 20viewBox% 3D% 270,% 200,% 20494,572% 20494,572% 27% 20width% 3D% 27.512,% 27,% 20height% 3D % 27.512,% 27,% 3E% 0A% 20,% 20,% 3Cpath% 20d% 3D% 27M257.063% 200C127.136% 200,% 2021,808% 20105,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 dolgu% 3D% 27 # {$ color-rgb} % 27% 2F% 3E% 3C% 2Fsvg% 3E


  1. VERİ URL'sinde UTF8 CHARSET'İ OMIT EDİN Veri URL'nizi oluştururken IE11'de çalışması için karakter kümesini dışarıda bırakmanız gerekir.

    DEĞİL arka plan resmi: url (veri: görüntü / svg + xml; utf-8,% 3Csvg% 2 ....)
    AMA arka plan resmi: url (veri: görüntü / svg + xml,% 3Csvg% 2 ... .)


  1. RGB () KULLANMA HEX renklerinin yerleştirilmesi Firefox, SVG kodunda # beğenmez. Bu nedenle renk altıgen değerlerinizi RGB değerleriyle değiştirmeniz gerekir.

    DEĞİL doldurmak = "# FF0000"
    AMA dolgu = "rgb (255,0,0)"

Benim durumumda belirli bir hex geçerli bir rgb değerine dönüştürmek için SASS kullanın. Yorumlarda belirtildiği gibi, RGB dizenizi de kodlamak en iyisidir (virgül% 2C olur)

@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');
   }
}

Bunun çok karmaşık SVG'ler için en iyi çözüm olmayabilir (inline SVG asla bu durumda değildir), ancak sadece birkaç renge sahip düz simgeler için bu gerçekten harika çalışıyor.

Tüm sprite bitmap'ini bırakıp CSS'mde satır içi SVG ile değiştirebildim, bu da sıkıştırmadan sonra sadece 25kb civarında olduğu ortaya çıktı. Bu nedenle, CSS dosyanızı engellemeden sitenizin yapması gereken istek miktarını sınırlamanın harika bir yoludur.


1
Yanılıyorsam ama eğer Btw, beni düzelt rgb(255,0,0)haline gelmelidir rgb(255%2C0%2C0)kodlanmış bir kez.
Kapsül

1
RGB dizgisini kodlamamıştım ve hala çalışıyor. Ancak bahsettiğiniz gibi kodlamak muhtemelen daha iyidir.
Davy Baert

1
Aslında, yeni test ettim ve Firefox'ta %23ff0000iyi çalıştım#ff0000
Kapsül

1
@Capsule Ne olduğunu bilmiyorum, ancak% 23ff0000, Chrome ve FF'de benim için çalışan SADECE yöntem. # ff0000 çalışmıyor ve RGB (255,0,0) ve rgb (255% 2C0% 2C0) yöntemleri de çalışmıyor.
İdeogram

1
Daha az kodlama gerektiren bir yöntem ( SCSS
Sphinxxx

26

Mac / Linux'ta, bu basit bash komutuyla bir SVG dosyasını CSS arka plan özelliği için base64 kodlu bir değere kolayca dönüştürebilirsiniz:

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

Mac OS X'te test edilmiştir. Bu şekilde URL'nin karmaşadan kaçmasını da önlersiniz.

Bir SVG dosyasını kodlayan base64'ün boyutunu artırdığını unutmayın, bkz. Css-tricks.com blog yazısı .


2
Okuyucular için: Lütfen oy vermek yerine fikrinizi yorumlayın, böylece bu cevap işbirliğinizle geliştirilebilir! Bunun gibi soru-cevap sitelerinde işbirliği şarttır. Teşekkür ederim!
araks

2
@LorDex Yorumunuzda sağladığınız bağlantı cevabımdakiyle aynı :)
araks

10

Satır içi SVG'yi CSS'ye gömmekle aynı sorunu yaşayan bir CodePen demosunu çatalladım. SCSS ile çalışan bir çözüm, basit bir url kodlama işlevi oluşturmaktır.

Yerleşik str-slice, str-index işlevlerinden bir dize değiştirme işlevi oluşturulabilir ( Hugo Giraudel sayesinde css- tricks'e bakın).

Sonra, sadece yerine %, <, >, ", ', ile %xxkodları:

@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-inlineCompass'ta bir yardımcı işlev de vardır , ancak CodePen'de desteklenmediğinden, bu çözüm muhtemelen yararlı olabilir.

CodePen hakkında demo: http://codepen.io/terabaud/details/PZdaJo/


1
Ayrıca, svg dizelerini uygun bir css arka plan değerine dönüştürmenize izin veren bir kalem oluşturdum: Temel olarak, üst textarea'ya yapıştıracaksınız ve doğrudan sterilize edilmiş yolu çıktılayacaksınız.<svg><path></svg> bir url()değer içinde .
LukyVj

1
Bu harika çalıştı. Teşekkür ederim. Bir not. IE'de çalışmak için; charset = utf8 kullanmanız gerekir.
Daniel Lefebvre

4

Üçüncü taraf kaynaklardan gelen (Google grafikler gibi) satır içi SVG, XML ad alanı özelliği (xmlns="http://www.w3.org/2000/svg" , SVG öğesinde ) (veya SVG oluşturulduktan sonra kaldırılabilir - ne tarayıcı denetçisinden ne de tarayıcı konsolundan jQuery komutları SVG öğesinde ad alanını gösterir).

Bu svg snippet'lerini diğer ihtiyaçlarınız için yeniden amaçlamanız gerektiğinde (CSS'de arka plan resmi veya HTML'de img öğesi) eksik ad alanına dikkat edin. Ad alanı olmadan tarayıcılar SVG görüntülemeyi reddedebilir (utf8 veya base64 kodlamasına bakılmaksızın).


4

SVG için bir çözüm buldum. Ama bu sadece Webkit için işe yarıyor, sadece geçici çözümümü sizinle paylaşmak istiyorum. Örneğimde DOM'dan SVG öğesini bir filtre aracılığıyla arka plan olarak nasıl kullanacağım gösterilmektedir (background-image: url ('# glyph') çalışmıyor).

Bu SVG simgesi için gerekli özellikler görüntülenir:

  1. CSS kullanarak HTML öğelerine SVG filtre efektleri uygulama (IE ve Edge desteklemez)
  2. feImage parça yükü desteği (firefox desteklemez)

.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>

Bir çözüm daha, url kodlaması kullanmaktır

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.