img src SVG Ändern der Stile mit CSS

373

html

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

CSS

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

Das obige SVG wird geladen und ist nativ, fill: #fffaber wenn ich das Obige verwende css, um es in Schwarz zu ändern, ändert es sich nicht. Ich spiele zum ersten Mal mit SVG und bin mir nicht sicher, warum es nicht funktioniert.

Spielplatz
quelle
25
Sie können
solche
Überprüfen Sie meine Antwort hier, um Inhalte von SVG und CSS zu verwenden. stackoverflow.com/questions/11978995/…
Benjamin

Antworten:

153

Wenn Ihr Ziel nur darin besteht, die Farbe des Logos zu ändern, und Sie nicht unbedingt CSS verwenden müssen, verwenden Sie kein Javascript oder keine Abfrage, wie dies in einigen früheren Antworten vorgeschlagen wurde.

Um die ursprüngliche Frage genau zu beantworten, einfach:

  1. Öffnen Sie Ihre logo.svgin einem Texteditor.

  2. suchen fill: #fffund ersetzen durchfill: #000

Sie logo.svgkönnten beispielsweise so aussehen, wenn Sie sie in einem Texteditor öffnen:

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

... einfach die Füllung ändern und speichern.

Rowe Morehouse
quelle
6
... und wenn es keine "Füllung" gibt, können Sie es einfach zu den pathoder circleElementen wie hinzufügen <path fill="#777777" d="m129.774,74.409c-5.523,....
SaeX
1
Was ist, wenn mein Logo eine Farbe in der Kopfzeile und eine andere Farbe in der Fußzeile hat?
rubens.lopes
. @ ruben.lopes zwei verschiedene Dateien oder zwei verschiedene Inlines wären am einfachsten
Rowe Morehouse
11
Sie können auch fill="currentColor"das colorauf dem übergeordneten Element verwendete Element css-tricks.com/cascading-svg-fill-color verwenden
Serge
10
Dies ist offensichtlich möglich und keine wirklich hilfreiche Antwort.
Timmmm
102

Sie können Ihre SVG als Maske festlegen. Auf diese Weise würde das Festlegen einer Hintergrundfarbe als Füllfarbe fungieren.

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

Bitte überprüfen Sie, ob Ihr Browser diese Funktion unterstützt: https://caniuse.com/#search=mask

André Kuhlmann
quelle
3
Also für alles andere als interne Website unbrauchbar.
Henrik Vendelbo
9
89% weltweite Unterstützung ab 29. Mai 2016.
Gajus
1
Dies ist eine erstaunliche Lösung für Situationen wie die hier beschriebene, in denen die Verwendung von etwas anderem als Daten-Uris in CSS ein bisschen mühsam ist. Vielen Dank!
Gark Garcia
3
es funktioniert nicht. es heißt maskein invalid property value. Ich teste dies in Chrom.
Eren555
1
@MadMac Ich verwende dieselbe Version von Chrome, konnte dieses Verhalten jedoch nicht replizieren. Ist es die JSFiddle, die Sie ausprobiert haben, oder Ihr Code?
André Kuhlmann
78

Versuchen Sie reines CSS:

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

Weitere Informationen in diesem Artikel https://blog.union.io/code/2017/08/10/img-svg-fill/

Feri
quelle
Bei Edge habe ich kürzlich bei einem meiner Versuche eine andere Farbe als bei anderen Browsern erhalten.
Julix
4
Dies funktioniert in den meisten Browsern, aber ich hatte einige Probleme mit dem IOS-Safari-Browser.
Simon Ludwig
30

2018: Wenn Sie eine dynamische Farbe möchten, kein Javascript und kein Inline-SVG verwenden möchten, verwenden Sie eine CSS-Variable. Funktioniert in Chrome, Firefox und Safari. edit: und Edge

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

Ersetzen Sie in Ihrer SVG alle Instanzen von style="fill: #000"durch style="fill: var(--color_fill)".

nordamerikanisch
quelle
1
Was ist die Browser-Unterstützung dafür
Kevin Goedecke
@ KevinGoedecke Chrome, Firefox, Safari und Edge
Nordamerikaner
4
Scheint in SVG 2
vsync
5
@northamerican - Links zu anderen Stackoverflow-Antworten als "Beweise" sind irrelevant. Jeder kann auf dieser Plattform alles schreiben. 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
Es scheint, dass xlink:hrefzugunsten von veraltet ist href. Das kann also immer noch funktionieren.
Benjamin Intal
20

Sie müssen zuerst die SVG in das HTML-DOM einfügen.

Es gibt eine Open-Source-Bibliothek namens SVGInject , die dies für Sie erledigt. Es verwendet das onloadAttribut, um die Injektion auszulösen.

Hier ist ein minimales Beispiel für die Verwendung von SVGInject:

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

Nachdem das Bild geladen wurde onload="SVGInject(this), löst das die Injektion aus und das <img>Element wird durch den Inhalt der SVG-Datei ersetzt, die in dersrc Attribut .

Es löst mehrere Probleme mit der SVG-Injektion:

  1. SVGs können ausgeblendet werden, bis die Injektion beendet ist. Dies ist wichtig, wenn bereits während der Ladezeit ein Stil angewendet wird, der andernfalls einen kurzen "nicht gestylten Inhaltsblitz" verursachen würde.

  2. Die <img>Elemente injizieren sich automatisch. Wenn Sie SVGs dynamisch hinzufügen, müssen Sie sich keine Gedanken mehr über das erneute Aufrufen der Injektionsfunktion machen.

  3. Jeder ID in der SVG wird eine zufällige Zeichenfolge hinzugefügt, um zu vermeiden, dass dieselbe ID mehrmals im Dokument enthalten ist, wenn eine SVG mehr als einmal injiziert wird.

SVGInject ist einfaches Javascript und funktioniert mit allen Browsern, die SVG unterstützen.

Haftungsausschluss: Ich bin Mitautor von SVGInject

Waruyama
quelle
3
Dies ist die einfachste Antwort. Ich habe es in Chrome, Firefox und Edge getestet und es funktioniert perfekt.
Sébastien Lorion
15

Die Antwort von @Praveen ist solide.

Ich konnte es nicht dazu bringen, in meiner Arbeit zu antworten, also habe ich eine JQuery-Hover-Funktion dafür erstellt.

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');
});
Matt Wujek
quelle
1
würde das nicht nur funktionieren, wenn die SVG von Anfang an inline wäre?
Daniel Thompson
Ja, aber wenn Sie mit vielen SVG-Dateien arbeiten oder diese regelmäßig aktualisieren, ist die Verwaltung schwierig.
Matt Wujek
15

Warum erstellen Sie nicht einen Webfont mit Ihrem SVG-Bild oder Ihren SVG-Bildern, importieren den Webfont in das CSS und ändern dann einfach die Farbe des Glyphen mithilfe des CSS-Farbattributs? Kein Javascript erforderlich

Gringo
quelle
5
Wenn Ihr SVG mehrere Elemente mit unterschiedlichen Farben enthält, wird diese Lösung sehr hackig (mehrere Elemente dazwischen).
Kakaja
1
@kakaja Dies ist eine Lösung nur für Vektorbilder, die 1 Farbe enthalten. Siehe Bpulecios Antwort für weitere Details
Gringo
1
Weil das Symbol kein Text ist. Schriftarten sind für Text. Svgs sind für Symbole.
Lazar Ljubenović
2
@ LazarLjubenović - Technisch gesehen besteht Text aus Zeichen, die Symbole sind, und Symbole sind auch Symbole. Aus diesem Grund haben viele keine Probleme mit der Verwendung von Symbolschriftarten. Es ist wie das Erstellen einer "anderen" Textsprache. Mandarin verwendet "Symbole" und nicht auch Buchstaben. Es ist in der Menschheit nicht ungewöhnlich, Symbole als "Text" zu verwenden
vsync
1
Während dies als interessante Lösung klingt, empfehle ich wirklich, die Antwort in etwas mehr wie "wie" anstatt "warum nicht"
auszuarbeiten
15

Diese Antwort basiert auf der Antwort https://stackoverflow.com/a/24933495/3890888, jedoch mit einer einfachen JavaScript-Version des dort verwendeten Skripts.

Sie müssen die SVG zu einer Inline-SVG machen . Sie können dieses Skript verwenden, indem Sie svgdem Bild eine Klasse hinzufügen :

/*
 * 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);

    });

});

Und dann, wenn Sie das tun:

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

Oder vielleicht:

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

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

Seb3736
quelle
1
Gute Arbeit. Wenn unsere Seite mehrere SVGs enthält, müssen wir außerdem den Abrufblock in das IIFE einfügen.
Sandeep Sharma
1
Großartig! Funktioniert gut mit ES6. Wenn Sie sich nicht für IE 9 interessieren, können Sie sogar verwenden: parser.parseFromString(text, "image/svg+xml");
ChristoKiwi
Funktioniert nicht in einem UIWebView unter iOS 9.3.5. Ich denke, es könnte daran liegen fetch, dass Safari in 10.1 ( developer.mozilla.org/en-US/docs/Web/API/Fetch_API ) verwendet wurde. Die obige jQuery-Version funktioniert.
Maria-Ines Carrera
7

Verwenden Sie Filter, um in eine beliebige Farbe zu transformieren.

Ich habe diese Lösung kürzlich gefunden und hoffe, dass jemand sie verwenden kann. Da die Lösung Filter verwendet, kann sie mit jeder Art von Bild verwendet werden. Nicht nur svg.

Wenn Sie ein einfarbiges Bild haben, dessen Farbe Sie nur ändern möchten, können Sie dies mithilfe einiger Filter tun. Es funktioniert natürlich auch bei mehrfarbigen Bildern, aber Sie können nicht auf eine bestimmte Farbe zielen. Nur das ganze Bild.

Die Filter stammen aus dem Skript unter So transformieren Sie Schwarz in eine bestimmte Farbe, indem Sie nur CSS-Filter verwenden. Wenn Sie Weiß in eine beliebige Farbe ändern möchten, können Sie den Invertierungswert in jedem Filter anpassen.

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

JasperZelf
quelle
4

Um die @ gringo-Antwort zu erweitern, funktioniert die in anderen Antworten beschriebene Javascript-Methode, der Benutzer muss jedoch unnötige Bilddateien herunterladen, und IMO wird Ihr Code aufgebläht.

Ich denke, ein besserer Ansatz wäre es, alle einfarbigen Vektorgrafiken in eine Webfont-Datei zu migrieren. Ich habe Fort Awesome in der Vergangenheit verwendet und es funktioniert hervorragend, wenn Sie Ihre benutzerdefinierten Symbole / Bilder im SVG-Format zusammen mit den von Ihnen verwendeten Symbolen von Drittanbietern (Font Awesome, Bootstrap-Symbole usw.) in einer einzigen Webfont-Datei kombinieren Der Benutzer muss herunterladen. Sie können es auch anpassen, sodass Sie nur die von Ihnen verwendeten Symbole von Drittanbietern einschließen. Dies reduziert die Anzahl der Anforderungen, die die Seite stellen muss, und das Gesamtseitengewicht, insbesondere wenn Sie bereits Symbolbibliotheken von Drittanbietern enthalten.

Wenn Sie eine dev-orientierte Option bevorzugen, können Sie Google "npm svg webfont" verwenden. und eines der für Ihre Umgebung am besten geeigneten Knotenmodule verwenden.

Sobald Sie eine dieser beiden Optionen ausgeführt haben, können Sie die Farbe problemlos über CSS ändern, und höchstwahrscheinlich haben Sie Ihre Website dabei beschleunigt.

bpulecio
quelle
Sie sollten SVG-Sprites ausprobieren. Nach meiner Erfahrung treten bei Web-Schriftarten zufällige Probleme zwischen den Browserversionen auf. Versuchen Sie Folgendes : fontastic.me - aber verwenden Sie die SVG-Sprite-Versionen - und sehen Sie, was Sie denken. :)
sheriffderek
4

Wenn Sie nur das Bild zwischen der echten Farbe und Schwarzweiß umschalten, können Sie einen Selektor wie folgt einstellen:

{Filter: keine;}

und eine andere als:

{filter:grayscale(100%);}
wcb1
quelle
3

Einfach..

Sie können diesen Code verwenden:

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

Geben Sie zuerst den Pfad von svg an und schreiben Sie dann die ID, in diesem Fall "Capa_1". Sie können die ID von svg erhalten, indem Sie sie in einem beliebigen Editor öffnen.

In CSS:

.logo {
  fill: red;
}
Hamza Jamal
quelle
kabrice, Sie können diesen Code verwenden codepen.io/hmzajmal/pen/ZEGvWYa
Hamza Jamal
2

Das Hauptproblem in Ihrem Fall ist, dass Sie <img>das SVG aus einem Tag importieren, das die SVG-Struktur verbirgt.

Sie müssen das <svg>Tag in Verbindung mit dem verwenden <use>, um den gewünschten Effekt zu erzielen. Damit es funktioniert, müssen Sie iddem Pfad, den Sie in der SVG-Datei verwenden möchten, <path id='myName'...>einen geben, um sie dann aus dem <use xlink:href="#myName"/>Tag abrufen zu können . Versuchen Sie das unten geschnippte.

Beachten Sie, dass Sie eine beliebige URL vor das Fragment stellen können, #wenn Sie die SVG-Datei aus einer externen Quelle laden möchten (und nicht in Ihren HTML-Code einbetten möchten ). Außerdem geben Sie die Füllung normalerweise nicht im CSS an. Es ist besser, die Verwendung fill:"currentColor"innerhalb der SVG selbst in Betracht zu ziehen . Der CSS-Farbwert des entsprechenden Elements wird dann an Ort und Stelle verwendet.

Flavien Volken
quelle
2

Da SVG im Grunde genommen Code ist, benötigen Sie nur Inhalte. Ich habe PHP verwendet, um Inhalte zu erhalten, aber Sie können verwenden, was Sie wollen.

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

Dann habe ich den Inhalt "wie er ist" in einem div-Container gedruckt

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

Um die Regel endgültig auf die SVG-Childs des Containers in CSS festzulegen

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

Ich habe diese Ergebnisse mit einem Material-Symbol SVG erhalten:

Mozilla Firefox 59.0.2 (64-Bit) Linux

Geben Sie hier die Bildbeschreibung ein

Google Chrome66.0.3359.181 (Build oficial) (64 Bit) Linux

Geben Sie hier die Bildbeschreibung ein

Opera 53.0.2907.37 Linux

Geben Sie hier die Bildbeschreibung ein

Benjamin
quelle
Ich kann nicht abstimmen, aber bitte mache das niemals.
Schleifer
5
Gründe dafür? Alternativen?
Benjamin
Mein Grund dafür ist, dass der Browser die SVG nicht zwischenspeichern kann. Die Alternative besteht darin, einen SVG-Injektor zu verwenden, der in einigen anderen Antworten hier erwähnt wird. Die SVG-Datei wird weiterhin vom Browser zwischengespeichert, und die injizierte SVG-Datei kann weiterhin mit CSS gestaltet werden. Aber ich stimme dir nicht zu.
Sơn Trần-Nguyễn
Ich verstehe, aber der Cache wird sowieso nicht erwähnt. Die beste Antwort ist JavaScript-Code, der jedes Mal neu geladen werden kann (oder nicht), wenn die Manipulation des Headers abläuft oder ein Hash nach dem Dateinamen-Link erzwungen wird.
Benjamin
2

Dies kann für Personen hilfreich sein, die PHPin Kombination mit verwenden.svg Bilder Bildern verwenden, die sie mit CSS bearbeiten möchten.

Sie können Eigenschaften in einem img-Tag nicht mit CSS überschreiben. Aber wenn der SVG-Quellcode in den HTML-Code eingebettet ist, können Sie dies sicherlich. Ich möchte dieses Problem mit einer require_onceFunktion lösen, in die ich a.svg.php Datei einbinde. Es ist wie beim Importieren eines Bildes, aber Sie können Stile trotzdem mit CSS überschreiben!

Fügen Sie zuerst die SVG-Datei hinzu:

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

Und es enthält dieses Symbol zum Beispiel:

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

Jetzt können wir die Füllfarbe mit CSS ganz einfach so ändern:

svg path {
  fill: blue;
}

Ich habe zuerst versucht, dieses Problem mit zu lösen, file_get_contents()aber die obige Lösung ist viel schneller.

Floris
quelle
0

Ich weiß, dass dies eine alte Frage ist, aber kürzlich sind wir auf dasselbe Problem gestoßen und haben es von der Serverseite aus gelöst. Dies ist eine PHP-spezifische Antwort, aber ich bin mir sicher, dass andere Envs etwas Ähnliches haben. Anstatt das img-Tag zu verwenden, rendern Sie das SVG von Anfang an als SVG.

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

Jetzt, wenn Sie die Datei rendern, erhalten Sie vollständige Inline-SVG

nechemya ungar
quelle
0

Öffnen Sie das SVG-Symbol in Ihrem Code-Editor und fügen Sie nach dem Pfad-Tag eine Klasse hinzu:

<path class'colorToChange' ...

Sie können svg eine Klasse hinzufügen und die Farbe folgendermaßen ändern:

Codepen

Hamza Jamal
quelle
-2

Wenn Sie Zugriff auf JQuery haben und die Antwort von Praveen erweitern, können Sie die Farbe verschiedener verschachtelter Elemente in SVG programmgesteuert ändern, indem Sie:

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

In find können Sie verschiedene Elemente erwähnen, deren Farbe geändert werden muss.

manyu
quelle