img src SVG, stilleri CSS ile değiştirme


373

html

<img src="logo.svg" alt="Logo" class="logo-img">

css

.logo-img path {
  fill: #000;
}

Yukarıdaki svg yükler ve doğal fill: #fffama yukarı csssiyah değiştirmek için denemek için kullandığımda, bu değişmez, bu SVG ile ilk kez oynamak ve neden çalışmıyor emin değilim.


25
Bunun gibi SVG görüntülerini etkileyemezsiniz ... sadece satır içi SVG öğeleri
Paulie_D


SVG ve CSS içeriklerini kullanmak için cevabımı kontrol edin. stackoverflow.com/questions/11978995/…
Benjamin

Yanıtlar:


153

Amacınız sadece logonun rengini değiştirmekse ve CSS kullanmanız gerekmiyorsa, önceki bazı yanıtların önerdiği gibi javascript veya jquery kullanmayın.

Orijinal soruyu tam olarak cevaplamak için:

  1. Açık olan logo.svgbir metin editörü.

  2. ara fill: #fffve değiştirfill: #000

Örneğin, logo.svgbir metin düzenleyicide açıldığında şöyle görünebilirsiniz:

<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
  <path d="M0 0h24v24H0z" fill="none"/>
  <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="#fff"/>
</svg>

... sadece dolguyu değiştirin ve kaydedin.


6
... ve "dolgu" yoksa, pathveya öğesine circlebenzer öğeleri ekleyebilirsiniz <path fill="#777777" d="m129.774,74.409c-5.523,....
SaeX

1
logomun başlıkta bir renk ve altbilgide başka bir renk varsa ne olur?
rubens.lopes

. @ ruben.lopes iki farklı dosya veya iki farklı satır içi en basit olurdu
Rowe Morehouse

11
Ayrıca kullanabilirsiniz fill="currentColor"sonra kullanmak colorana öğe üzerinde css-tricks.com/cascading-svg-fill-color
Serge

10
Bu kesinlikle mümkündür ve gerçekten yararlı bir cevap değildir.
Timmmm

102

SVG'nizi maske olarak ayarlayabilirsiniz. Bu şekilde bir arka plan rengi ayarlamak dolgu renginiz olarak işlev görür.

HTML

<div class="logo"></div>

CSS

.logo {
    background-color: red;
    -webkit-mask: url(logo.svg) no-repeat center;
    mask: url(logo.svg) no-repeat center;
}

JSFiddle: https://jsfiddle.net/KuhlTime/2j8exgcb/
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/mask

Lütfen tarayıcınızın bu özelliği destekleyip desteklemediğini kontrol edin: https://caniuse.com/#search=mask


3
Yani dahili web sitesi dışında hiçbir şey kullanılamaz.
Henrik Vendelbo

9
29 Mayıs 2016 itibarıyla% 89 küresel destek.
Gajus

1
Bu, burada açıklanan gibi, css'de veri urisinden başka bir şey kullanmanın biraz acı verici olduğu durumlar için inanılmaz bir çözümdür . Teşekkürler!
Gark Garcia

3
çalışmıyor. diyor maskbir invalid property value. Bunu kromda test ediyorum.
Eren555

1
@MadMac Chrome'un aynı sürümünü kullanıyorum, ancak bu davranışı tekrarlayamadım. Denediğiniz JSFiddle mı yoksa kodunuz mu?
André Kuhlmann

78

Saf CSS'yi deneyin:

.logo-img {
  // to black
  filter: invert(1);
  // or to blue
  // filter: invert(1) sepia(1) saturate(5) hue-rotate(175deg);
}

bu makalede daha fazla bilgi https://blog.union.io/code/2017/08/10/img-svg-fill/


Son zamanlarda denemelerimden biriyle Edge'de diğer tarayıcılardan farklı bir renk alıyordum.
Julix

4
Bu en tarayıcıda çalışır, ancak IOS-Safari tarayıcısıyla ilgili bazı sorunlar yaşadım.
Simon Ludwig

30

2018: Dinamik bir renk istiyorsanız, javascript kullanmak istemiyorsanız ve satır içi SVG istemiyorsanız, bir CSS değişkeni kullanın. Chrome, Firefox ve Safari'de çalışır. düzenleme: ve Edge

<svg>
    <use xlink:href="logo.svg" style="--color_fill: #000;"></use>
</svg>

SVG'nizde, style="fill: #000"ile olan herhangi bir örneği değiştirin style="fill: var(--color_fill)".


1
Bunun için tarayıcı desteği nedir
Kevin Goedecke

@KevinGoedecke Chrome, Firefox, Safari ve Edge
northamerican

4
Görünüyor kaldırılmış içinde SVG 2
vsync

5
@northamerican - "kanıt" olarak diğer yığın akışı yanıtlarına bağlantılar önemsizdir. Herkes bu platformda her şeyi yazabilir. MDN:"This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped"
vsync

8
Bu xlink:hreflehine itiraz edilmiş gibi görünüyor href. Bu hala işe yarayabilir.
Benjamin Intal

20

Önce SVG'yi HTML DOM'ye enjekte etmeniz gerekir.

SVGInject adında sizin için yapan açık kaynaklı bir kütüphane var. onloadEnjeksiyonu tetiklemek için bu özelliği kullanır .

İşte SVGInject kullanarak minimal bir örnek:

<html>
  <head>
    <script src="svg-inject.min.js"></script>
  </head>
  <body>
    <img src="image.svg" onload="SVGInject(this)" />
  </body>
</html>

Görüntü yüklendikten sonra onload="SVGInject(this)enjeksiyonu tetikler ve <img>eleman srcöznitelikte sağlanan SVG dosyasının içeriği ile değiştirilir .

SVG enjeksiyonuyla ilgili çeşitli sorunları çözer:

  1. SVG'ler enjeksiyon bitene kadar gizlenebilir. Yükleme sırasında bir stil zaten uygulanmışsa, aksi takdirde kısa bir "styled content flash" a neden olan bu önemlidir.

  2. <img>Elemanları kendilerini otomatik olarak enjekte edin. SVG'leri dinamik olarak eklerseniz, enjeksiyon işlevini tekrar çağırmak konusunda endişelenmenize gerek yoktur.

  3. Bir SVG birden çok kez enjekte edilirse, belgede birden çok kez aynı kimliğe sahip olmaktan kaçınmak için SVG'deki her kimliğe rastgele bir dize eklenir.

SVGInject düz bir Javascripttir ve SVG'yi destekleyen tüm tarayıcılarla çalışır.

Feragatname: SVGInject'in ortak yazarıyım


3
Bu en basit cevaptır. Chrome, Firefox ve Edge'de test ettim ve mükemmel çalışıyor.
Sébastien Lorion

15

@ Praveen'nin cevabı sağlam.

İşime cevap veremedim, bu yüzden bunun için bir jquery hover işlevi yaptım.

CSS

.svg path {
   transition:0.3s all !important;
}

JS / JQuery

// code from above wrapped into a function
replaceSVG();

// hover function
// hover over an element, and find the SVG that you want to change
$('.element').hover(function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#CCC');
}, function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#3A3A3A');
});

1
bu sadece SVG başlangıç ​​içindeyse işe yaramaz mı?
Daniel Thompson

Evet — ancak birçok SVG dosyasıyla çalışıyorsanız veya düzenli olarak güncellüyorsanız, yönetilmesi acı vericidir.
Matt Wujek

15

Neden svg resminiz veya resimlerinizle bir web yazı tipi oluşturmuyorsunuz, web yazı tipini css'e içe aktarıp sonra sadece css renk özelliğini kullanarak glifin rengini değiştirmiyorsunuz? Javascript gerekmez


5
SVG'nizin farklı renklerde birkaç öğesi varsa, bu çözüm çok çirkinleşir (birkaç öğe araya girer).
kakaja

1
@kakaja Bu, yalnızca içinde 1 renk bulunan vektör görüntüleri için bir çözümdür. daha fazla bilgi için bpulecio'nun cevabına bakınız
gringo

1
Çünkü simge metin değildir. Yazı tipleri metin içindir. Svgs simgeler içindir.
Lazar Ljubenović

2
@ LazarLjubenović - teknik olarak metin sembollerden oluşan karakterlerden oluşur ve simgeler de sembollerdir, bu yüzden birçok kişinin simge yazı tiplerini kullanmada sorunu yoktur. tıpkı "başka" bir metin dili oluşturmak gibidir. Mandarin harfleri değil, "simgeleri" kullanır, simgeleri "metin" olarak kullanmak insanlıkta nadir değildir
vsync

1
bu ilginç bir çözüm gibi görünse de, cevabı gerçekten "neden olmasın" yerine "nasıl yapılır" gibi bir şeye detaylandırmanızı öneririm
YakovL

15

Bu yanıt, https://stackoverflow.com/a/24933495/3890888 yanıtına dayanmaktadır, ancak burada kullanılan komut dosyasının düz bir JavaScript sürümü vardır.

SVG'nin satır içi SVG olmasını sağlamanız gerekir . svgGörüntüye bir sınıf ekleyerek bu komut dosyasını kullanabilirsiniz :

/*
 * Replace all SVG images with inline SVG
 */
document.querySelectorAll('img.svg').forEach(function(img){
    var imgID = img.id;
    var imgClass = img.className;
    var imgURL = img.src;

    fetch(imgURL).then(function(response) {
        return response.text();
    }).then(function(text){

        var parser = new DOMParser();
        var xmlDoc = parser.parseFromString(text, "text/xml");

        // Get the SVG tag, ignore the rest
        var svg = xmlDoc.getElementsByTagName('svg')[0];

        // Add replaced image's ID to the new SVG
        if(typeof imgID !== 'undefined') {
            svg.setAttribute('id', imgID);
        }
        // Add replaced image's classes to the new SVG
        if(typeof imgClass !== 'undefined') {
            svg.setAttribute('class', imgClass+' replaced-svg');
        }

        // Remove any invalid XML tags as per http://validator.w3.org
        svg.removeAttribute('xmlns:a');

        // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
        if(!svg.getAttribute('viewBox') && svg.getAttribute('height') && svg.getAttribute('width')) {
            svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
        }

        // Replace image with new SVG
        img.parentNode.replaceChild(svg, img);

    });

});

Ve sonra, şimdi yaparsanız:

.logo-img path {
  fill: #000;
}

Ya da belki:

.logo-img path {
  background-color: #000;
}

JSFiddle: http://jsfiddle.net/erxu0dzz/1/


1
Harika .. çalışır. ayrıca sayfamızın birden fazla svg'si varsa, getirme bloğunu IIFE'ye koymamız gerekecek.
Sandeep Sharma

1
Harika! ES6 ile iyi çalışır. IE 9'u parser.parseFromString(text, "image/svg+xml");
önemsemiyorsanız

İOS 9.3.5'te bir UIWebView'da çalışmaz. Ben düşünüyorum da kullanımına bağlı olabilir fetch10.1'de Safari eklendi (hangi developer.mozilla.org/en-US/docs/Web/API/Fetch_API ). Yukarıdaki jQuery sürümü çalışıyor.
Maria-Ines Carrera

7

Herhangi bir renge dönüştürmek için filtreleri kullanın.

Kısa süre önce bu çözümü buldum ve umarım birisi bunu kullanabilir. Çözüm filtreler kullandığından, herhangi bir görüntü türüyle kullanılabilir. Sadece svg değil.

Yalnızca rengini değiştirmek istediğiniz tek renkli bir görüntünüz varsa, bunu bazı filtrelerin yardımıyla yapabilirsiniz. Elbette çok renkli görüntülerde de çalışır, ancak belirli bir rengi hedefleyemezsiniz. Sadece tüm görüntü.

Filtreler, yalnızca CSS filtrelerini kullanarak siyahı herhangi bir renge dönüştürme yönteminde önerilen komut dosyasından geldi. Beyazı herhangi bir renge değiştirmek istiyorsanız, her filtrede ters çevirme değerini ayarlayabilirsiniz.

.startAsBlack{
  display: inline-block;
  width: 50px;
  height: 50px;
  background: black;
}

.black-green{
  filter: invert(43%) sepia(96%) saturate(1237%) hue-rotate(88deg) brightness(128%) contrast(119%);
}

.black-red{
  filter: invert(37%) sepia(93%) saturate(7471%) hue-rotate(356deg) brightness(91%) contrast(135%);
}

.black-blue{
  filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%);
}

.black-purple{
  filter: invert(18%) sepia(98%) saturate(2657%) hue-rotate(289deg) brightness(121%) contrast(140%);
}
Black to any color: <br/>
<div class="startAsBlack black-green"></div>
<div class="startAsBlack black-red"></div>
<div class="startAsBlack black-blue"></div>
<div class="startAsBlack black-purple"></div>


4

@Gringo yanıtını genişletmek için, diğer yanıtlarda açıklanan Javascript yöntemi çalışır, ancak kullanıcının gereksiz görüntü dosyalarını ve IMO'yu indirmesini gerektirir, kodunuzu şişirir.

Bence daha iyi bir yaklaşım, tüm 1 renkli vektör grafiklerini bir webfont dosyasına taşımaktır. Fort Awesome'i kullandımGeçmişte ve özel simgelerinizi / resimlerinizi SVG formatında ve kullanabileceğiniz herhangi bir 3. taraf simgeyle (Font Awesome, Bootstrap simgeleri vb.) Tek bir webfont dosyasında birleştirmek harika çalışıyor. kullanıcının indirmesi gerekir. Ayrıca özelleştirebilirsiniz, böylece yalnızca kullandığınız 3. taraf simgeleri dahil edersiniz. Bu, sayfanın yapması gereken istek sayısını azaltır ve özellikle üçüncü taraf simge kitaplıkları ekliyorsanız, genel sayfa ağırlığınız olur.

Daha gelişmiş bir seçeneği tercih ederseniz, Google "npm svg webfont" kullanabilir ve ortamınıza en uygun düğüm modüllerinden birini kullanabilirsiniz.

Bir kez, bu iki seçenekten birini yaptıktan sonra, rengi kolayca CSS ile değiştirebilir ve büyük olasılıkla sitenizi bu süreçte hızlandırabilirsiniz.


SVG spritelarını denemelisiniz. Deneyimlerime göre, web fontlarının tarayıcı sürümleri arasında rastgele sorunları var. Bunu deneyin: fontastic.me - ancak SVG sprite sürümlerini kullanın - ve ne düşündüğünüzü görün. :)
sheriffderek

4

Görüntüyü gerçek renk ile siyah beyaz arasında değiştiriyorsanız, bir seçiciyi şu şekilde ayarlayabilirsiniz:

{Filtre: yok;}

ve diğeri şöyle:

{filter:grayscale(100%);}

3

Basit..

Bu kodu kullanabilirsiniz:

<svg class="logo">
  <use xlink:href="../../static/icons/logo.svg#Capa_1"></use>
</svg>

Önce svg yolunu belirtin ve ardından ID, Bu durumda "Capa_1" yazın. Svg'nin kimliğini herhangi bir düzenleyicide açarak alabilirsiniz.

Css dilinde:

.logo {
  fill: red;
}

kabrice, Bu kodu kullanabilirsiniz codepen.io/hmzajmal/pen/ZEGvWYa
Hamza Jamal

2

Sizin durumunuzdaki temel sorun, svg'yi <img>SVG yapısını gizleyecek bir etiketten içe aktarmanızdır .

İstenilen efekti elde etmek için <svg>etiketi ile birlikte kullanmanız gerekir <use>. Çalışmasını sağlamak idiçin SVG dosyasında kullanmak istediğiniz yola bir etiket vermeniz <path id='myName'...>ve ardından bunları <use xlink:href="#myName"/>etiketten alabilmeniz gerekir . Aşağıdaki snipsi deneyin.

#SVG'yi harici bir kaynaktan yüklemek (ve HTML'nize gömmek istemiyorsanız) parçanın önüne herhangi bir URL koyabileceğinizi unutmayın . Ayrıca, genellikle dolguyu CSS'ye belirtmezsiniz. fill:"currentColor"SVG'nin içinde kullanmayı düşünmek daha iyidir . İlgili öğenin CSS renk değeri daha sonra yerinde kullanılacaktır.


2

SVG temel olarak kod olduğundan, sadece içeriğe ihtiyacınız vardır. İçerik elde etmek için PHP kullandım, ancak istediğinizi kullanabilirsiniz.

<?php
$content    = file_get_contents($pathToSVG);
?>

Sonra, div kabının içine "olduğu gibi" içerik yazdırdım

<div class="fill-class"><?php echo $content;?></div>

CSS'de kabın SVG alt öğesi için kuralı sonlandırmak için

.fill-class > svg { 
    fill: orange;
}

Bu sonuçları malzeme simgesi SVG ile aldım:

Mozilla Firefox 59.0.2 (64 bit) Linux

resim açıklamasını buraya girin

Google Chrome66.0.3359.181 (Derleme resmi) (64 bit) Linux

resim açıklamasını buraya girin

Opera 53.0.2907.37 Linux

resim açıklamasını buraya girin


Aşağı inemiyorum ama lütfen bunu asla asla yapmayın.
zımpara

5
Nedenleri? Alternatifler?
Benjamin

Bunu yapmamamın nedeni, tarayıcının SVG'yi önbelleğe almasını engellemesidir. Alternatif, burada birkaç cevapta belirtilen bir SVG enjektörü kullanmaktır. SVG dosyası yine de tarayıcı tarafından önbelleğe alınır ve enjekte edilen SVG hala CSS ile stillendirilebilir. Ama seni küçümsemiyorum.
Sơn Trần-Nguyễn

Anlıyorum, ama yine de önbellekten bahsedilmiyor. En iyi yanıt, başlık tarafından her zaman yeniden yüklenebilen (veya değiştirilemeyen) JavaScript koduna sahiptir.
Benjamin

2

Bu , CSS ile değiştirmek istedikleri görüntülerle PHPbirlikte kullanan kişiler için yararlı olabilir .svg.

CSS ile bir img etiketi içindeki özelliklerin üzerine yazamazsınız. Ancak svg kaynak kodu HTML'ye gömüldüğünde mutlaka yapabilirsiniz. Dosya require_onceeklediğim bir işlevle bu sorunu çözmek istiyorum .svg.php. Bir görüntüyü içe aktarmak gibidir, ancak yine de stilleri CSS ile üzerine yazabilirsiniz!

Önce svg dosyasını ekleyin:

<?php require_once( '/assets/images/my-icon.svg.php' ); ?>

Ve bu simgeyi içerir örneğin:

<svg xmlns="http://www.w3.org/2000/svg" width="20.666" height="59.084" viewBox="0 0 20.666 59.084"><g transform="translate(-639.749 -3139)"><path d="M648.536,3173.876c0-2.875-1.725-3.8-3.471-3.8-1.683,0-3.49.9-3.49,3.8,0,3,1.786,3.8,3.49,3.8C646.811,3177.676,648.536,3176.769,648.536,3173.876Zm-3.471,2.341c-.883,0-1.437-.513-1.437-2.341,0-1.971.615-2.381,1.437-2.381.862,0,1.438.349,1.438,2.381,0,1.907-.616,2.339-1.438,2.339Z" fill="#142312"/><path d="M653.471,3170.076a1.565,1.565,0,0,0-1.416.9l-6.558,13.888h1.2a1.565,1.565,0,0,0,1.416-.9l6.559-13.887Z" fill="#142312"/><path d="M655.107,3177.263c-1.684,0-3.471.9-3.471,3.8,0,3,1.766,3.8,3.471,3.8,1.745,0,3.49-.9,3.49-3.8C658.6,3178.186,656.851,3177.263,655.107,3177.263Zm0,6.139c-.884,0-1.438-.514-1.438-2.34,0-1.972.617-2.381,1.438-2.381.862,0,1.437.349,1.437,2.381,0,1.909-.616,2.34-1.437,2.34Z" fill="#142312"/><path d="M656.263,3159.023l-1.49-14.063a1.35,1.35,0,0,0,.329-.293,1.319,1.319,0,0,0,.268-1.123l-.753-3.49a1.328,1.328,0,0,0-1.306-1.054h-6.448a1.336,1.336,0,0,0-1.311,1.068l-.71,3.493a1.344,1.344,0,0,0,.276,1.112,1.532,1.532,0,0,0,.283.262l-1.489,14.087c-1.7,1.727-4.153,4.871-4.153,8.638v28.924a1.339,1.339,0,0,0,1.168,1.49,1.357,1.357,0,0,0,.17.01h17.981a1.366,1.366,0,0,0,1.337-1.366v-29.059C660.414,3163.893,657.963,3160.749,656.263,3159.023Zm-8.307-17.349h4.274l.176.815H647.79Zm9.785,43.634v10.1H642.434v-17.253a4.728,4.728,0,0,1-2.028-4.284,4.661,4.661,0,0,1,2.028-4.215v-2c0-3.162,2.581-5.986,3.687-7.059a1.356,1.356,0,0,0,.4-.819l1.542-14.614H652.1l1.545,14.618a1.362,1.362,0,0,0,.4.819c1.109,1.072,3.688,3.9,3.688,7.059v9.153a5.457,5.457,0,0,1,0,8.5Z" fill="#142312"/></g></svg>

Şimdi CSS ile dolgu rengini kolayca değiştirebiliriz:

svg path {
  fill: blue;
}

İlk olarak bu sorunu çözmeye çalıştım file_get_contents()ama yukarıdaki çözüm çok daha hızlı.


0

Bu eski bir soru olduğunu biliyorum ama son zamanlarda aynı sorunla karşılaştık ve sunucu tarafından çözdük. Bu php özel bir cevap ama diğer envs benzer bir şey var pozitif. img etiketini kullanmak yerine svg'yi get-go'dan svg olarak işlersiniz.

public static function print_svg($file){
    $iconfile = new \DOMDocument();
    $iconfile->load($file);
    $tag = $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
    return $tag;
}

şimdi dosyayı oluşturduğunuzda tam satır içi svg alacaksınız


0

kod düzenleyicinizde svg simgesini açın ve yol etiketinden sonra bir sınıf ekleyin:

<path class'colorToChange' ...

Svg'ye sınıf ekleyebilir ve rengi şu şekilde değiştirebilirsiniz:

codepen


-2

JQuery'ye erişiminiz varsa, Praveen'in cevabına kadar uzanan bir kişi SVG içindeki farklı iç içe öğelerin rengini şu şekilde programlayabilir:

$('svg').find('path, text').css('fill', '#ffffff');

Bulmanın içinde, renk değiştirmesi gereken farklı unsurlardan bahsedebilirsiniz.

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.