Comment changer la couleur d'un élément svg?

352

Je veux utiliser cette technique http://css-tricks.com/svg-fallbacks/ et changer la couleur svg mais jusqu'à présent je n'ai pas pu le faire. Je mets ça dans le css mais mon image est toujours noire, quoi qu'il arrive. Mon 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
la source
Je ne suis pas un expert en SVG, mais avez-vous essayé de changer le remplissage en couleur de fond?
Meg
@Megan en svg background-color est spécifié avec la propriété 'fill' et la bordure avec 'stroke' (comme vous le feriez dans Illustrator). w3.org/TR/SVG/propidx.html
Barbara
4
Le CSS de votre document HTML ne s'appliquera pas aux éléments SVG dans <img />
pawel
1
C'est possible maintenant. Réponse simple et fonctionnelle ici: stackoverflow.com/a/53336754/467240
mtyson

Réponses:

189

Vous ne pouvez pas changer la couleur d'une image de cette façon. Si vous chargez SVG en tant qu'image, vous ne pouvez pas changer la façon dont il est affiché en utilisant CSS ou Javascript dans le navigateur.

Si vous voulez changer votre image SVG, vous devez le charger en utilisant <object>, <iframe>ou à l' aide en <svg>ligne.

Si vous souhaitez utiliser les techniques de la page, vous avez besoin de la bibliothèque Modernizr, où vous pouvez vérifier la prise en charge SVG et afficher conditionnellement ou non une image de secours. Vous pouvez ensuite intégrer votre SVG et appliquer les styles dont vous avez besoin.

Voir:

Vous pouvez incorporer votre SVG, étiqueter votre image de secours avec un nom de classe ( my-svg-alternate):

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

Et en CSS, utilisez la no-svgclasse de Modernizr (CDN: http://ajax.aspnetcdn.com/ajax/modernizr/modernizr-2.7.2.js ) pour vérifier le support SVG. S'il n'y a pas de support SVG, le bloc SVG sera ignoré et l'image sera affichée, sinon l'image sera supprimée de l'arborescence DOM ( display: none):

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

Ensuite, vous pouvez changer la couleur de votre élément en ligne:

#time-3-icon {
   fill: green;
}
helderdarocha
la source
5
Vous ne pouvez pas objectstyliser les SVG intégrés à partir du document d'hébergement.
Javier Rey
1
@JavierRey, vous pouvez injecter le style dans le contenu de la balise d'objet via javascript. Mais vous avez raison, cela ne s'applique pas si vous l'ajoutez simplement à la feuille de style du document d'hébergement.
Robert Longson
2
J'utilise la solution de @ manish-menaria et cela fonctionne parfaitement.
Ryan Ellis
1
La réponse acceptée doit être remplacée par: stackoverflow.com/a/53336754/467240
mtyson
379

Réponse 2020

Le filtre CSS fonctionne sur tous les navigateurs actuels

Pour changer la couleur de n'importe quel SVG

  1. Ajoutez l'image SVG à l'aide d'une <img>balise.
<img src="dotted-arrow.svg" class="filter-green"/>
  1. Pour filtrer sur une couleur spécifique, utilisez le codepen suivant (cliquez ici pour ouvrir le codepen) pour convertir un code de couleur hexadécimal en filtre CSS:

Par exemple, la sortie pour #00EE00est

filter: invert(42%) sepia(93%) saturate(1352%) hue-rotate(87deg) brightness(119%) contrast(119%);
  1. Ajoutez le CSS filterdans cette classe.
    .filter-green{
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%);
    }
Manish Menaria
la source
5
Cela vient avec la mise en garde habituelle de ne pas être pris en charge dans les anciennes versions de navigateur: developer.mozilla.org/en-US/docs/Web/CSS/…
Kevin Wang
17
Comme indiqué dans le CodePen, si votre SVG n'est pas noir (le mien était gris), l'ajout brightness(0) saturate(100%)au début de la liste des filtres le rendra d'abord 100% noir, ce qui permet aux autres filtres de le changer à la bonne couleur.
jdunning
2
En outre, beaucoup d'histoire fascinante sur la solution de cette question StackOverflow qui a informé le CodePen.
jdunning
3
Mon gars. Le support semble acceptable caniuse.com/#feat=css-filters .
Sam Doidge
fonctionne si bien, a utilisé ce codepen non affilié pour obtenir mon hex dans un filtre: codepen.io/sosuke/pen/Pjoqqp
WEBjuju
221

Pour changer la couleur d'un SVG, vous pouvez directement changer le code svg en ouvrant le fichier svg dans n'importe quel éditeur de texte . Le code peut ressembler au code ci-dessous

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

Vous pouvez observer qu'il ya des balises XML comme chemin, cercle, polygone etc . Là, vous pouvez ajouter votre propre couleur à l'aide de l' attribut de style . Regardez l'exemple ci-dessous

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

Ajoutez l'attribut style à toutes les balises afin d'obtenir votre SVG de la couleur souhaitée

sushant047
la source
48
Pourquoi ne pas simplement utiliser un attribut fillcomme celui-ci fill = "#AB7C94":? Je ne sais pas pourquoi l' styleattribut est nécessaire
bg17aw
4
Salut Daniel, oui ça marche. Je ne savais pas que le remplissage peut être utilisé comme attribut. Désolé de ne pas avoir remarqué votre commentaire si longtemps @ bg17aw
sushant047
30

Ajout d'une page de test - pour colorer SVG via les paramètres de filtre:

PAR EXEMPLE filter: invert(0.5) sepia(1) saturate(5) hue-rotate(175deg)

Téléchargez et coloriez votre SVG - Jsfiddle

A pris l'idée de: https://blog.union.io/code/2017/08/10/img-svg-fill/

Yonatan Ayalon
la source
1
Merci, vous venez de me sauver de moi-même. .custom-disabled > svg {filter:invert(0.2) sepia(1) saturte(0) hue-rotate(0);}a fait juste le travail dont j'avais besoin pour désactiver l'icône.
roger
21

Uniquement SVG avec des informations de chemin . vous ne pouvez pas faire cela à l'image .. comme chemin, vous pouvez changer les informations de trait et de remplissage et vous avez terminé. comme Illustrator

donc: via CSS, vous pouvez remplacer la fillvaleur du chemin

path { fill: orange; }

mais si vous voulez un moyen plus flexible comme vous voulez le changer avec un texte lorsque vous avez un effet de survol en cours. utilisez

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
la source
12

la manière la plus simple serait de créer une police à partir du SVG en utilisant un service comme https://icomoon.io/app/#/select ou autre. téléchargez votre SVG, cliquez sur "générer la police", incluez les fichiers de police et le CSS dans votre côté et utilisez-le et stylisez-le comme n'importe quel autre texte. Je l'utilise toujours comme ça car cela rend le style beaucoup plus facile.

EDIT: Comme mentionné dans l' article commenté par @ CodeMouse92, les polices d'icônes gâchent les lecteurs d'écran (et sont peut-être mauvaises pour le référencement). Alors, tenez-vous plutôt aux SVG.

Felix Hagspiel
la source
5
Il gâche également les lecteurs d'écran. Voir "Death to Icon Fonts" par Seren Davies
CodeMouse92
7

Le masque SVG sur un élément de boîte avec une couleur d'arrière - plan entraînera:

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


Remarque - Les masques SVG ne sont pas pris en charge dans les navigateurs Internet Explorer

vsync
la source
1
Merci beaucoup, @vsync c'est juste le meilleur hack pour ce dont j'ai besoin.
Vixson
6

Vous pouvez changer la coloration SVG avec css si vous utilisez des astuces. J'ai écrit un petit script pour ça.

  • passer par une liste d'éléments qui ont une image svg
  • charger le fichier svg au format xml
  • récupérer uniquement la partie svg
  • changer la couleur du chemin
  • remplacer src par le svg modifié comme image en ligne
$('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')));
  });

});

le code ci-dessus peut ne pas fonctionner correctement, je l'ai implémenté pour les éléments avec une image d'arrière-plan svg qui fonctionne presque de la même manière. Mais de toute façon, vous devez modifier ce script pour l'adapter à votre cas. j'espère que cela a aidé.

cydoc
la source
Soit dit en passant: si vous êtes un développeur RoR, vous pouvez ajouter une nouvelle méthode pour le précompilateur sass qui peut également faire le travail. C'est beaucoup mieux parce que vous aurez l'image codée en base64 et de couleur correcte dans votre fichier css compilé. Plus besoin de JS! Je pourrais peut-être fournir le code que j'ai écrit, je dois en parler au CTO.
cydoc
2
+1 pour avoir fourni une solution, plutôt que de dire que cela ne peut pas être fait. Cette réponse est également pertinente: stackoverflow.com/questions/11978995/…
claytronicon
6

Ciblez le chemin dans le svg:

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

Vous pouvez faire en ligne, comme:

<path fill="#ccc">

Ou

svg{
   path{
        fill: #ccc
Michael Philips
la source
4

Pour changer simplement la couleur du svg:

Allez dans le fichier svg et sous styles, mentionnez la couleur de remplissage.

<style>.cls-1{fill:#FFFFFF;}</style>
Sethu Sathyan
la source
Déjà suggéré par cette réponse
Robert Longson
2

Si vous voulez faire ceci à un svg en ligne qui est, par exemple, une image d'arrière-plan dans votre css:

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

bien sûr, remplacez le ... par votre code d'image en ligne

Vision Hive
la source
2

Par exemple, dans votre HTML:

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

Utilisez jQuery:

$("#struct1").css("fill","<desired colour>");
Grv97
la source
Cela ne fonctionne que si vous incluez le fichier SVG en ligne dans le HTML. J'ai modifié votre réponse pour que cela soit clair.
Flimm
0

En fait, il existe une solution beaucoup plus flexible à ce problème: l'écriture d'un composant Web qui corrigera SVG en tant que texte lors de l'exécution. Également publié dans gist avec un lien vers JSFiddle

👍 filtre: inverti (42%) sépia (93%) saturé (1352%) teinte-rotation (87deg) luminosité (119%) contraste (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
la source
-1

manière la plus courte compatible avec Bootstrap, pas de 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;
}

et l'utiliser comme:

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

Ouvrez votre image à l'aide d'un navigateur, cliquez avec le bouton droit sur l'image, cliquez sur Afficher la source de la page et vous verrez la balise svg de l'image. Faites face et collez dans votre html, puis changez le remplissage à la couleur de votre choix

Chiemelie Akah
la source
La réponse acceptée suggère déjà l'incrustation puis la définition de la couleur comme solution.
Robert Longson
-1

Ajoutez simplement fill: "desireColor" dans la balise svg de l'image: exemple:

<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
la source
C'est essentiellement la même suggestion que cette réponse ou celle-ci
Robert Longson
ces réponses ont mentionné remplir la balise path, cela a fonctionné pour moi dans la balise svg, donc je l'ai posté
Shivani