466 votes

Comment changer la couleur d'une image SVG à l'aide de CSS (remplacement d'image SVG par jQuery) ?

Il s'agit d'une auto-questionnaire d'un morceau de code pratique que j'ai créé.

Actuellement, il n'existe pas de moyen simple d'intégrer une image SVG et d'avoir ensuite accès aux éléments SVG via CSS. Il existe plusieurs méthodes permettant d'utiliser des cadres JS SVG, mais elles sont trop compliquées si tout ce que vous faites est de créer une simple icône avec un état de renversement.

Voici donc ce que j'ai mis au point, qui, à mon avis, est de loin le moyen le plus simple d'utiliser des fichiers SVG sur un site web. Son concept s'inspire des premières méthodes de remplacement du texte par l'image, mais pour autant que je sache, cela n'a jamais été fait pour les SVG.

C'est la question :

Comment intégrer un SVG et changer sa couleur en CSS sans utiliser un framework JS-SVG ?

2 votes

Malheureusement, la balise img ne fonctionne pas avec les fichiers svg dans IE, il faut donc en tenir compte. IE reconnaît les balises embed. Quoi qu'il en soit, bon travail !

3 votes

Pour les svg, vous devez utiliser la propriété css "fill". Pour les images, il est approprié d'utiliser "filter". En fait, "Filter" fonctionne pour les deux, mais il est inutile de faire tout ce travail pour un graphique vectoriel.

5voto

Waruyama Points 1152

Il existe une bibliothèque open source appelée SVGInject qui utilise l'option onload pour déclencher l'injection. Vous pouvez trouver le projet GitHub à l'adresse suivante https://github.com/iconfu/svg-inject

Voici un exemple minimal utilisant SVGInject :

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

Après le chargement de l'image, le onload="SVGInject(this) déclenchera l'injection et le <img> sera remplacé par le contenu du fichier SVG fourni dans l'élément src attribut.

Il résout plusieurs problèmes liés à l'injection de SVG :

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

  2. En <img> les éléments s'injectent automatiquement. Si vous ajoutez des SVG de manière dynamique, vous n'avez pas à vous soucier de rappeler la fonction d'injection.

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

SVGInject est un simple Javascript et fonctionne avec tous les navigateurs qui supportent SVG.

Disclaimer : Je suis le co-auteur de SVGInject

4voto

user3144480 Points 128

Voici un code sans framework, uniquement du js pur :

document.querySelectorAll('img.svg').forEach(function(element) {
            var imgID = element.getAttribute('id')
            var imgClass = element.getAttribute('class')
            var imgURL = element.getAttribute('src')

            xhr = new XMLHttpRequest()
            xhr.onreadystatechange = function() {
                if(xhr.readyState == 4 && xhr.status == 200) {
                    var svg = xhr.responseXML.getElementsByTagName('svg')[0];

                    if(imgID != null) {
                         svg.setAttribute('id', imgID);
                    }

                    if(imgClass != null) {
                         svg.setAttribute('class', imgClass + ' replaced-svg');
                    }

                    svg.removeAttribute('xmlns:a')

                    if(!svg.hasAttribute('viewBox') && svg.hasAttribute('height') && svg.hasAttribute('width')) {
                        svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
                    }
                    element.parentElement.replaceChild(svg, element)
                }
            }
            xhr.open('GET', imgURL, true)
            xhr.send(null)
        })

3voto

Abhishek Borar Points 1

Si nous disposons d'un grand nombre d'images svg, nous pouvons également utiliser les fichiers de police.
Des sites comme https://glyphter.com/ peut nous obtenir un fichier de police à partir de nos svgs.


Par exemple

@font-face {
    font-family: 'iconFont';
    src: url('iconFont.eot');
}
#target{
    color: white;
    font-size:96px;
    font-family:iconFont;
}

2voto

patelarpan Points 3165

Vous pouvez utiliser data-image pour cela. En utilisant data-image(data-URI) vous pouvez accéder à SVG comme en ligne.

Voici l'effet rollover en utilisant purement CSS et SVG.

Je le sais. désordonné mais vous pouvez le faire de cette façon.

 .action-btn {
    background-size: 20px 20px;
    background-position: center center;
    background-repeat: no-repeat;
    border-width: 1px;
    border-style: solid;
    border-radius: 30px;
    height: 40px;
    width: 60px;
    display: inline-block;
 }

.delete {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#FB404B' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
     border-color:#FB404B;

 }

 .delete:hover {
     background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#fff' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");        
     background-color: #FB404B;
    }

<a class="action-btn delete">&nbsp;</a>

Vous pouvez convertir votre svg en url de données ici

  1. https://codepen.io/elliz/full/ygvgay
  2. https://websemantics.uk/tools/svg-to-background-image-conversion/

2voto

Benjamin Points 330

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

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

Ensuite, j'ai imprimé le contenu "tel quel" à l'intérieur d'un conteneur div.

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

Pour définir définitivement la règle pour les enfants SVG du conteneur sur CSS

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

J'ai obtenu ce résultat avec une icône matérielle SVG :

  1. Mozilla Firefox 59.0.2 (64 bits) Linux

enter image description here

  1. Google Chrome66.0.3359.181 (Build oficial) (64 bits) Linux

enter image description here

  1. Opera 53.0.2907.37 Linux

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X