Wie ändere ich die Farbe eines SVG-Elements?

346

Ich möchte diese Technik http://css-tricks.com/svg-fallbacks/ verwenden und die SVG-Farbe ändern, konnte dies aber bisher nicht. Ich habe dies in die CSS gestellt, aber mein Bild ist immer schwarz, egal was passiert. Mein Code:

.change-my-color {
  fill: green;
}
<svg>
    <image class="change-my-color" xlink:href="https://svgur.com/i/AFM.svg" width="96" height="96" src="ppngfallback.png" />
</svg>

Barbara
quelle
Ich bin kein SVG-Experte, aber haben Sie versucht, die Füllung in Hintergrundfarbe zu ändern?
Meg
@Megan in svg-Hintergrundfarbe wird mit der Eigenschaft 'fill' und dem Rand mit 'Stroke' angegeben (wie in Illustrator). w3.org/TR/SVG/propidx.html
Barbara
4
CSS aus Ihrem HTML-Dokument gilt nicht für SVG-Elemente innerhalb von <img />
pawel
1
Dies ist jetzt möglich. Einfache und funktionale Antwort hier: stackoverflow.com/a/53336754/467240
mtyson

Antworten:

188

Auf diese Weise können Sie die Farbe eines Bildes nicht ändern. Wenn Sie SVG als Bild laden, können Sie nicht ändern, wie es mit CSS oder Javascript im Browser angezeigt wird.

Wenn Sie Ihr SVG - Datei ändern möchten, müssen Sie es laden verwenden <object>, <iframe>oder mit<svg> Inline.

Wenn Sie die Techniken auf der Seite verwenden möchten, benötigen Sie die Modernizr-Bibliothek, in der Sie nach SVG-Unterstützung suchen und ein Fallback-Bild bedingt anzeigen oder nicht. Sie können dann Ihre SVG einbinden und die gewünschten Stile anwenden.

Sehen :

Sie können Ihre SVG inline setzen und Ihr Fallback-Bild mit einem Klassennamen ( my-svg-alternate) versehen:

<svg width="96px" height="96px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
<path id="time-3-icon" .../>
</svg>

<image class="my-svg-alternate" width="96" height="96" src="ppngfallback.png" />

Verwenden Sie in CSS die no-svgKlasse von Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ), um nach SVG-Unterstützung zu suchen. Wenn keine SVG-Unterstützung vorhanden ist, wird der SVG-Block ignoriert und das Bild angezeigt. Andernfalls wird das Bild aus dem DOM-Baum entfernt ( display: none):

.my-svg-alternate {
  display: none;
}
.no-svg .my-svg-alternate {
  display: block;
  width: 100px;
  height: 100px;
  background-image: url(image.png);
}

Dann können Sie die Farbe Ihres Inline-Elements ändern:

#time-3-icon {
   fill: green;
}
Helderdarocha
quelle
5
Sie können eingebettete objectSVGs nicht aus dem Hosting-Dokument formatieren.
Javier Rey
1
@JavierRey Sie können das Styling über Javascript in den Inhalt des Objekt-Tags einfügen. Sie haben jedoch Recht, dass dies nicht zutrifft, wenn Sie es einfach zum Stylesheet des Hosting-Dokuments hinzufügen.
Robert Longson
2
Ich benutze die Lösung von @ manish-menaria und sie funktioniert perfekt.
Ryan Ellis
1
Die akzeptierte Antwort sollte geändert werden in: stackoverflow.com/a/53336754/467240
mtyson
374

2020 Antwort

Der CSS-Filter funktioniert in allen aktuellen Browsern

So ändern Sie die Farbe von SVGs

  1. Fügen Sie das SVG-Bild mit einem <img>Tag hinzu.
<img src="dotted-arrow.svg" class="filter-green"/>
  1. Verwenden Sie zum Filtern nach einer bestimmten Farbe den folgenden Codepen (Klicken Sie hier, um den Codepen zu öffnen) , um einen Hex-Farbcode in einen CSS-Filter zu konvertieren:

Die Ausgabe für #00EE00ist beispielsweise

filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
  1. Fügen Sie das CSS filterzu dieser Klasse hinzu.
    .filter-green{
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
    }
Manish Menaria
quelle
5
Dies ist mit der üblichen Einschränkung verbunden, dass ältere Browserversionen nicht unterstützt werden: developer.mozilla.org/en-US/docs/Web/CSS/…
Kevin Wang
17
Wie im CodePen angegeben, wird Ihr SVG, wenn es nicht schwarz ist (meins war grau), durch Hinzufügen brightness(0) saturate(100%)zum Anfang der Filterliste zunächst zu 100% schwarz, sodass die anderen Filter es in die richtige Farbe ändern können.
Jdunning
2
Außerdem viele faszinierende Hintergrundinformationen zur Lösung in dieser StackOverflow-Frage , die den CodePen informierte.
Jdunning
3
Mein Junge. Die Unterstützung scheint akzeptabel zu sein caniuse.com/#feat=css-filters .
Sam Doidge
funktioniert so gut, habe diesen nicht verbundenen Codepen verwendet, um mein Hex in einen Filter zu bekommen: codepen.io/sosuke/pen/Pjoqqp
WEBjuju
220

Um die Farbe eines SVG zu ändern, können Sie den SVG-Code direkt ändern, indem Sie die SVG- Datei in einem beliebigen Texteditor öffnen . Der Code kann wie folgt aussehen

<?xml version="1.0" encoding="utf-8"?>
    <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
    <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
    <g>
        <path d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
            C181.113,454.921,171.371,464.663,161.629,474.404z"/>
    /*Some more code goes on*/
    </g>
    </svg>

Sie können beobachten, dass es einige XML-Tags wie Pfad, Kreis, Polygon usw. Gibt . Dort können Sie Ihre eigene Farbe mit Hilfe von Add - Stil - Attribute . Schauen Sie sich das folgende Beispiel an

<path style="fill:#AB7C94;" d="M114.26,436.584L99.023,483h301.953l-15.237-46.416H114.26z M161.629,474.404h-49.592l9.594-29.225h69.223
                C181.113,454.921,171.371,464.663,161.629,474.404z"/>

Fügen Sie allen Tags das Stilattribut hinzu, damit Sie Ihr SVG mit der gewünschten Farbe erhalten

sushant047
quelle
48
Warum nicht einfach ein solches Attribut verwenden fill: fill = "#AB7C94"? Nicht sicher, warum das styleAttribut benötigt wird
bg17aw
4
Hallo Daniel, ja es funktioniert. Ich wusste nicht, dass Füllung als Attribut verwendet werden kann. Entschuldigung, dass Sie Ihren Kommentar so lange nicht bemerkt haben @ bg17aw
sushant047
30

Eine Testseite wurde hinzugefügt, um SVG über Filtereinstellungen einzufärben:

Z.B filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)

Laden Sie Ihre SVG - Jsfiddle hoch und färben Sie sie

Die Idee stammt von: https://blog.union.io/code/2017/08/10/img-svg-fill/

Yonatan Ayalon
quelle
1
Danke, du rettest mich einfach vor mir. .custom-disabled > svg {filter:invert(0.2) sepia(1) saturte(0) hue-rotate(0);}habe genau den Job gemacht, den ich brauche, um das Symbol zu deaktivieren.
Roger
19

Nur SVG mit Pfadinformationen . Sie können das nicht mit dem Bild machen. Als Pfad können Sie den Strich ändern und Informationen füllen, und Sie sind fertig. wie Illustrator

so: via CSS Sie Pfad überschreiben fillWert

path { fill: orange; }

Aber wenn Sie eine flexiblere Methode wünschen, da Sie diese mit einem Text ändern möchten, wenn ein Schwebeeffekt auftritt

path { fill: currentcolor; }

body {
  background: #ddd;
  text-align: center;
  padding-top: 2em;
}

.parent {
  width: 320px;
  height: 50px;
  display: block;
  transition: all 0.3s;
  cursor: pointer;
  padding: 12px;
  box-sizing: border-box;
}

/***  desired colors for children  ***/
.parent{
  color: #000;
  background: #def;
}
.parent:hover{
  color: #fff;
  background: #85c1fc;
}

.parent span{
  font-size: 18px;
  margin-right: 8px;
  font-weight: bold;
  font-family: 'Helvetica';
  line-height: 26px;
  vertical-align: top;
}
.parent svg{
  max-height: 26px;
  width: auto;
  display: inline;
}

/****  magic trick  *****/
.parent svg path{
  fill: currentcolor;
}
<div class='parent'>
  <span>TEXT WITH SVG</span>
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128" viewBox="0 0 32 32">
<path d="M30.148 5.588c-2.934-3.42-7.288-5.588-12.148-5.588-8.837 0-16 7.163-16 16s7.163 16 16 16c4.86 0 9.213-2.167 12.148-5.588l-10.148-10.412 10.148-10.412zM22 3.769c1.232 0 2.231 0.999 2.231 2.231s-0.999 2.231-2.231 2.231-2.231-0.999-2.231-2.231c0-1.232 0.999-2.231 2.231-2.231z"></path>
</svg>
</div>

Biskrem Muhammad
quelle
12

Der einfachste Weg wäre, eine Schriftart aus der SVG mit einem Dienst wie https://icomoon.io/app/#/select oder ähnlichem zu erstellen . Laden Sie Ihre SVG-Datei hoch, klicken Sie auf "Schriftart generieren", fügen Sie Schriftarten und CSS in Ihre Seite ein und verwenden und formatieren Sie sie einfach wie jeden anderen Text. Ich benutze es immer so, weil es das Styling viel einfacher macht.

BEARBEITEN: Wie in dem von @ CodeMouse92 kommentierten Artikel erwähnt, bringen Schriftarten Bildschirmleser durcheinander (und sind möglicherweise schlecht für SEO). Also bleib lieber bei den SVGs.

Felix Hagspiel
quelle
4
Es bringt auch Bildschirmleser durcheinander. Siehe "Death to Icon Fonts" von Seren Davies
CodeMouse92
6

Sie können die SVG-Farbe mit CSS ändern, wenn Sie einige Tricks anwenden. Ich habe dafür ein kleines Skript geschrieben.

  • Gehen Sie eine Liste der Elemente durch, die ein SVG-Bild haben
  • Laden Sie die SVG-Datei als XML
  • Holen Sie sich nur SVG-Teil
  • Ändern Sie die Farbe des Pfades
  • Ersetzen Sie src durch das geänderte svg als Inline-Image
$('img.svg-changeable').each(function () {
  var $e = $(this);
  var imgURL = $e.prop('src');

  $.get(imgURL, function (data) {
    // Get the SVG tag, ignore the rest
    var $svg = $(data).find('svg');

    // change the color
    $svg.find('path').attr('fill', '#000');

    $e.prop('src', "data:image/svg+xml;base64," + window.btoa($svg.prop('outerHTML')));
  });

});

Der obige Code funktioniert möglicherweise nicht richtig. Ich habe ihn für Elemente mit einem SVG-Hintergrundbild implementiert, das fast ähnlich funktioniert. Trotzdem müssen Sie dieses Skript an Ihren Fall anpassen. hoffe es hat geholfen.

cydoc
quelle
Übrigens: Wenn Sie ein RoR-Entwickler sind, können Sie eine neue Methode für den Sass-Precompiler hinzufügen, die auch die Aufgabe übernehmen kann. Dies ist viel besser, da Sie das base64-codierte, korrekt farbige Bild in Ihrer kompilierten CSS-Datei haben. Kein JS mehr nötig! Vielleicht könnte ich den Code, den ich geschrieben habe, bereitstellen und mit dem CTO sprechen.
Cydoc
2
+1 für die Bereitstellung einer Lösung, anstatt zu sagen, dass dies nicht möglich ist. Diese Antwort ist auch relevant: stackoverflow.com/questions/11978995/…
Claytronicon
6

Die SVG- Maske auf einem Box-Element mit einer Hintergrundfarbe ergibt:

.icon{
  --size     : 70px;
  display    : inline-block;
  width      : var(--size);
  height     : var(--size);
  transition : .12s;
  -webkit-mask-size: cover;
  mask-size  : cover;
}

.icon-bike{
  background: black;
  -webkit-mask-image: url(https://image.flaticon.com/icons/svg/89/89139.svg);
  mask-image: url(hhttps://image.flaticon.com/icons/svg/89/89139.svg);
  animation: 1s frames infinite ease;
}

@keyframes frames {
  50% { background:red;  }
}
<i class="icon icon-bike" style="--size:150px"></i>


Hinweis - SVG-Masken werden in Internet Explorer- Browsern nicht unterstützt

vsync
quelle
5

Zielen Sie auf den Pfad innerhalb des SVG:

<svg>
   <path>....
</svg>

Sie können inline tun, wie:

<path fill="#ccc">

Oder

svg{
   path{
        fill: #ccc
Michael Philips
quelle
4

So ändern Sie einfach die Farbe des SVG:

Gehen Sie zur SVG-Datei und geben Sie unter Stile die Füllfarbe an.

<style>.cls-1{fill:#FFFFFF;}</style>
Sethu Sathyan
quelle
Bereits durch diese Antwort vorgeschlagen
Robert Longson
2

Wenn Sie dies mit einem Inline-SVG tun möchten, das beispielsweise ein Hintergrundbild in Ihrem CSS ist:

background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='rgba(31,159,215,1)' viewBox='...'/%3E%3C/svg%3E");

Ersetzen Sie natürlich das ... durch Ihren Inline-Bildcode

Vision Hive
quelle
2

Zum Beispiel in Ihrem HTML:

<body>
  <svg viewBox="" width="" height="">
    <path id="struct1" fill="#xxxxxx" d="M203.3,71.6c-.........."></path>
  </svg>
</body>

Verwenden Sie jQuery:

$("#struct1").css("fill","<desired colour>");
Grv97
quelle
Dies funktioniert nur, wenn Sie die SVG-Datei inline in den HTML-Code aufnehmen. Ich habe Ihre Antwort bearbeitet, um dies zu verdeutlichen.
Flimm
0

Tatsächlich gibt es eine flexiblere Lösung für dieses Problem: Schreiben einer Webkomponente, die SVG zur Laufzeit als Text patcht. Auch im Kern mit einem Link zu JSFiddle veröffentlicht

👍 Filter: Invertieren (42%) Sepia (93%) Sättigen (1352%) Farbton-Rotieren (87 Grad) Helligkeit (119%) Kontrast (119%);

<html>

<head>
  <title>SVG with color</title>
</head>

<body>
  <script>
    (function () {
      const createSvg = (color = '#ff9933') => `
          <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="76px" height="22px" viewBox="-0.5 -0.5 76 22">
            <defs/>
              <g>
                <ellipse cx="5" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <ellipse cx="70" cy="10" rx="5" ry="5" fill="#ff9933" stroke="none" pointer-events="all"/>
                <path d="M 9.47 12.24 L 17.24 16.12 Q 25 20 30 13 L 32.5 9.5 Q 35 6 40 9 L 42.5 10.5 Q 45 12 50 6 L 52.5 3 Q 55 0 60.73 3.23 L 66.46 6.46" fill="none" stroke="#ff9933" stroke-miterlimit="10" pointer-events="stroke"/>
              </g>
          </svg>`.split('#ff9933').join(color);

      function SvgWithColor() {
        const div = Reflect.construct(HTMLElement, [], SvgWithColor);
        const color = div.hasAttribute('color') ? div.getAttribute('color') : 'cyan';
        div.innerHTML = createSvg(color);
        return div;
      }

      SvgWithColor.prototype = Object.create(HTMLElement.prototype);
      customElements.define('svg-with-color', SvgWithColor);

      document.body.innerHTML += `<svg-with-color
        color='magenta' 
      ></svg-with-color>`;

    })();

  </script>
</body>

</html>
Petr Tripolsky
quelle
-1

kürzester Bootstrap-kompatibler Weg, kein JavaScript:

.cameraicon {
height: 1.6em;/* set your own icon size */
mask: url(/camera.svg); /* path to your image */
-webkit-mask: url(/camera.svg) no-repeat center;
}

und benutze es wie:

<td class="text-center">
    <div class="bg-secondary cameraicon"/><!-- "bg-secondary" sets actual color of your icon -->
</td>
Wolfrevo Cats
quelle
-1

Öffnen Sie Ihr Bild mit einem Browser, klicken Sie mit der rechten Maustaste auf das Bild, klicken Sie auf Seitenquelle anzeigen, und Sie sehen das SVG-Tag des Bildes. Cope und füge es in dein HTML ein und ändere dann die Füllung in die Farbe deiner Wahl

Chiemelie Akah
quelle
Die akzeptierte Antwort schlägt bereits vor, die Farbe zu inlinen und dann als Lösung festzulegen.
Robert Longson
-1

Fügen Sie einfach fill: "requiredColor" in das svg-Tag des Bildes ein: Beispiel:

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#bbb9c6">
<path d="M20 2H4c-1.1 0-1.99.9-1.99 2L2 22l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
Shivani
quelle
Das ist im Grunde der gleiche Vorschlag , wie diese Antwort oder diese
Robert Longson
In diesen Antworten wurde erwähnt, dass das Pfad-Tag ausgefüllt werden muss. Es hat bei mir im SVG-Tag funktioniert, daher habe ich es veröffentlicht
Shivani,