web-dev-qa-db-fra.com

img src SVG changer la couleur de remplissage

html

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

css

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

Le svg ci-dessus se charge et est natif fill: #fff mais lorsque j'utilise le css ci-dessus pour essayer de le changer en noir, cela ne change pas, c'est la première fois que je joue avec SVG et je ne sais pas pourquoi cela ne fonctionne pas.

235
ngplayground

Vous devez faire en sorte que le SVG soit un SVG inline. Vous pouvez utiliser ce script en ajoutant une classe svg à l'image:

/*
 * Replace all SVG images with inline SVG
 */
jQuery('img.svg').each(function(){
    var $img = jQuery(this);
    var imgID = $img.attr('id');
    var imgClass = $img.attr('class');
    var imgURL = $img.attr('src');

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

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

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

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

        // Replace image with new SVG
        $img.replaceWith($svg);

    }, 'xml');

});

Et alors, maintenant si vous le faites:

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

Ou peut-être:

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

Cela marche!

Fiddle: http://jsfiddle.net/wuSF7/462/

Crédits pour le script ci-dessus: Comment changer la couleur d'une image SVG à l'aide de CSS (remplacement d'image jQuery SVG)?

202

Si votre objectif est simplement de changer la couleur du logo et que vous n'avez PAS nécessairement besoin d'utiliser CSS, n'utilisez pas javascript ou jquery comme suggéré par certaines réponses précédentes. 

Pour répondre précisément à la question initiale, il suffit de:

  1. Ouvrez votre logo.svg dans un éditeur de texte. 

  2. cherchez fill: #fff et remplacez-le par fill: #000 

Par exemple, votre logo.svg pourrait ressembler à ceci lorsqu'il est ouvert dans un éditeur de texte:

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

... changez simplement le remplissage et sauvegardez. 

105
Rowe Morehouse

Vous pouvez définir votre svg comme un masque. De cette façon, définir une couleur de fond agirait comme votre couleur de remplissage.

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/

Notez que cette méthode ne fonctionne pas pour le navigateur Edge. Vous pouvez vérifier cela en allant sur ce site: https://caniuse.com/#search=mask

42
André Kuhlmann

Essayez du CSS pur:

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

plus d'infos dans cet article https://blog.union.io/code/2017/08/10/img-svg-fill/

22
Feri

La réponse de @Praveen est solide.

Je ne pouvais pas le faire réagir dans mon travail, alors j’ai créé une fonction de survol jQuery. 

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');
});
15
Matt Wujek

Pourquoi ne pas créer une police Web avec votre ou vos images svg, importer la police Web dans le fichier css, puis changer la couleur du glyphe à l'aide de l'attribut couleur css? Aucun JavaScript requis

11
gringo

2018: Si vous voulez une couleur dynamique, ne voulez pas utiliser javascript ni un SVG intégré, utilisez une variable CSS. Fonctionne dans Chrome, Firefox et Safari. edit: et Edge

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

Dans votre SVG, remplacez toutes les instances de style="fill: #000" par style="fill: var(--color_fill)".

11
northamerican

_ {Cette réponse est basée sur la réponse https://stackoverflow.com/a/24933495/3890888 mais avec une version JavaScript du script utilisé à cet endroit.

Vous devez faire en sorte que le SVG soit un SVG inline. Vous pouvez utiliser ce script en ajoutant une classe svg à l'image:

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

    });

});

Et alors, maintenant si vous le faites:

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

Ou peut-être:

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

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

11
Seb3736

Vous devrez d’abord injecter le SVG dans le DOM HTML. 

Il existe une bibliothèque open source appelée SVGInject qui le fait pour vous. Il utilise l'attribut onload pour déclencher l'injection.

Voici un exemple minimal d'utilisation de SVGInject:

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

Une fois l'image chargée, onload="SVGInject(this) déclenchera l'injection et l'élément <img> sera remplacé par le contenu du fichier SVG fourni dans l'attribut src.

Il résout plusieurs problèmes avec l'injection de SVG:

  1. Les SVG peuvent être masqués jusqu'à la fin de l'injection. Ceci est important si un style est déjà appliqué pendant le temps de chargement, ce qui provoquerait sinon un bref "flash de contenu non style".

  2. Les éléments <img> s’injectent automatiquement. Si vous ajoutez des fichiers SVG de manière dynamique, vous n'avez pas à vous inquiéter d'appeler à nouveau la fonction d'injection.

  3. Une chaîne aléatoire est ajoutée à chaque ID du SVG pour éviter d'avoir le même ID plusieurs fois dans le document si un SVG est injecté plusieurs fois. 

SVGInject est un script Javascript simple qui fonctionne avec tous les navigateurs prenant en charge SVG.

Disclaimer: Je suis co-auteur de SVGInject

6
Waruyama

Pour développer la réponse @gringo, la méthode Javascript décrite dans d’autres réponses fonctionne, mais nécessite que l’utilisateur télécharge les fichiers d’image non nécessaires, et IMO, cela gonfle votre code. 

Je pense qu'une meilleure approche serait de migrer tous les graphiques vectoriels à une couleur dans un fichier webfont. J'ai déjà utilisé Fort Awesome dans le passé, et il est très pratique d'associer vos icônes/images personnalisées au format SVG, ainsi que toutes les icônes tierces que vous utilisez (icônes Font Awesome, Bootstrap, etc.) un seul fichier de police Web que l'utilisateur doit télécharger. Vous pouvez également le personnaliser, de sorte que vous n'incluez que les icônes tierces que vous utilisez. Cela réduit le nombre de requêtes que la page doit faire et vous donne le poids de la page, surtout si vous incluez déjà des bibliothèques d'icônes tierces. 

Si vous préférez une option plus orientée développement, vous pouvez Google "npm svg webfont" , et utiliser l'un des modules de nœud les plus appropriés pour votre environnement.

Une fois que vous avez choisi l'une ou l'autre de ces options, vous pouvez facilement changer la couleur via CSS et très probablement, vous avez accéléré votre site au cours du processus.

5
bpulecio

Si vous ne faites que basculer l'image entre la couleur réelle et le noir et blanc, vous pouvez définir un sélecteur sur:

{filtre: aucun;}

et un autre comme:

{filter:grayscale(100%);}
2
wcb1

Le principal problème dans votre cas est que vous importez le svg à partir d'une balise <img> qui masquera la structure SVG.

Vous devez utiliser la balise <svg> avec le <use> pour obtenir l'effet souhaité. Pour que cela fonctionne, vous devez donner une id au chemin que vous voulez utiliser dans le fichier SVG <path id='myName'...> pour pouvoir ensuite les récupérer à partir de la balise <use xlink:href="#myName"/> .

.icon {
  display: inline-block;
  width: 2em;
  height: 2em;
  transition: .5s;
  fill: currentColor;
  stroke-width: 5;
  }
  .icon:hover {
    fill: rgba(255,255,255,0);
    stroke: black;
    stroke-width: 2;
    }

.red {
  color: red;
  }

.blue {
  color: blue;
  }
<svg width="0" height="0">
  <defs>
    <path id="home" d="M100 59.375l-18.75-18.75v-28.125h-12.5v15.625l-18.75-18.75-50 50v3.125h12.5v31.25h31.25v-18.75h12.5v18.75h31.25v-31.25h12.5z"/>
</svg>

  
  <span class="icon red">
          <svg viewbox="0 0 100 100">
            <use xlink:href="#home"/>
          </svg>
        </span>
  
    <span class="icon blue">
          <svg viewbox="0 0 100 100">
            <use xlink:href="#home"/>
          </svg>
        </span>

Notez que vous pouvez mettre n'importe quelle URL avant le fragment # si vous voulez charger le fichier SVG depuis une source external (et ne pas l'intégrer dans votre code HTML). En outre, en général, vous ne spécifiez pas le remplissage dans le CSS. Il vaut mieux envisager d'utiliser fill:"currentColor" au sein même du SVG. La valeur de couleur CSS de l'élément correspondant sera alors utilisée à la place.

2
Flavien Volken

Puisque SVG est fondamentalement du code, vous n'avez besoin que de contenu. J'ai utilisé PHP pour obtenir du contenu, mais vous pouvez utiliser ce que vous voulez.

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

Ensuite, j'ai imprimé le contenu "tel quel" dans un conteneur div

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

Définir finalement la règle sur les enfants SVG du conteneur sur CSS

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

J'ai obtenu ces résultats avec une icône de matériau SVG:

Mozilla Firefox 59.0.2 (64 bits) Linux

 enter image description here

Google Chrome66.0.3359.181 (Version officielle) (64 bits) Linux

 enter image description here

Opera 53.0.2907.37 Linux

 enter image description here

0
Benjamin

Sachez qu’il s’agit d’une question ancienne, mais nous avons récemment rencontré le même problème, que nous avons résolu du côté serveur. Ceci est une réponse php spécifique mais je suis certain que d’autres envs ont quelque chose de similaire ... au lieu d’utiliser la balise img vous rendez le svg en tant que svg dès le début.

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

maintenant, lorsque vous rendrez le fichier, vous obtiendrez un svg complet en ligne 

0
nechemya ungar