Come cambiare il colore dell'immagine SVG usando CSS (sostituzione immagine SVG jQuery)?


437

Questa è una domanda e risposta personale di un utile codice che ho trovato.

Attualmente, non esiste un modo semplice per incorporare un'immagine SVG e quindi accedere agli elementi SVG tramite CSS. Esistono vari metodi per utilizzare i framework JS SVG, ma sono eccessivamente complicati se tutto ciò che stai facendo è creare un'icona semplice con uno stato di rollover.

Quindi, ecco cosa mi è venuto in mente, che penso sia di gran lunga il modo più semplice per utilizzare i file SVG su un sito Web. Prende il suo concetto dai primi metodi di sostituzione da testo a immagine, ma per quanto ne so non è mai stato fatto per gli SVG.

Questa è la domanda:

Come posso incorporare un SVG e cambiarne il colore nei CSS senza usare un framework JS-SVG?


1
Sfortunatamente il tag img non funziona con i file svg in IE, quindi tienilo a mente. IE riconosce i tag di incorporamento. Comunque, bel lavoro!

2
Per svg, dovresti usare la proprietà css "fill". Per le immagini è opportuno utilizzare il "filtro". "Filter" funziona in effetti per entrambi ma non è necessario fare tutto quel lavoro per una grafica vettoriale.
Samy Bencherif,

Risposte:


536

Innanzitutto, utilizza un tag IMG nel tuo HTML per incorporare un elemento grafico SVG. Ho usato Adobe Illustrator per realizzare la grafica.

<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>

Questo è proprio come avresti incorporato un'immagine normale. Nota che devi impostare l'IMG per avere una classe di svg. La classe "social-link" è solo a scopo esemplificativo. L'ID non è richiesto, ma è utile.

Quindi utilizzare questo codice jQuery (in un file separato o inline in HEAD).

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

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

            }, 'xml');

        });

Ciò che fa il codice sopra è cercare tutti gli IMG con la classe 'svg' e sostituirlo con l'SVG in linea del file collegato. Il grande vantaggio è che ti consente di utilizzare i CSS per cambiare il colore dell'SVG ora, in questo modo:

svg:hover path {
    fill: red;
}

Il codice jQuery che ho scritto porta anche attraverso l'ID e le classi delle immagini originali. Quindi anche questo CSS funziona:

#facebook-logo:hover path {
    fill: red;
}

O:

.social-link:hover path {
    fill: red;
}

Puoi vederne un esempio funzionante qui: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

Abbiamo una versione più complicata che include la cache qui: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90


6
A volte potrebbe non funzionare in Safari (ad esempio), per garantire che i dati restituiti siano leggibili, sostituisci });$ .get con}, 'xml');
Joan

29
Probabilmente potresti persino sostituire il selettore con img[src$=".svg"]ed eliminare la necessità della svgclasse.
Casey Chu,

2
@LeonGaban Non penso che ci sia un modo per indirizzare il riempimento di un'immagine di sfondo. Sarebbe molto utile se potessi!
Ha disegnato Baker il

3
Un po 'in ritardo, @LeonGaban, ma un modo migliore per farlo probabilmente sarebbe rimuovere del tutto l'attributo fill e fare affidamento su un file CSS per aggiungere un fill allo svg parent. $('#ico_company path').removeAttr('fill'). Quindi potresti farlo #ico_company { fill: #ccc }nel tuo file CSS
bioball

2
@Soaku sarebbe facile avere jQuery impostare tutti i percorsi in modo che siano uguali al colore del carattere facendo qualcosa come `var color = $ img.closest ('p'). Css ('color'); $ svg.find ('percorso'). attr ('riempimento', colore); `Ma penso che questo sia un lavoro che è meglio lasciare ai CSS.
Baker il

56

Stile

svg path {
    fill: #000;
}

copione

$(document).ready(function() {
    $('img[src$=".svg"]').each(function() {
        var $img = jQuery(this);
        var imgURL = $img.attr('src');
        var attributes = $img.prop("attributes");

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

            // Remove any invalid XML tags
            $svg = $svg.removeAttr('xmlns:a');

            // Loop through IMG attributes and apply on SVG
            $.each(attributes, function() {
                $svg.attr(this.name, this.value);
            });

            // Replace IMG with SVG
            $img.replaceWith($svg);
        }, 'xml');
    });
});

1
Se non hai una larghezza attr, ne crea una con un numero errato. width="170.667"nel mio caso
stallo,

2
Questo non è perfetto poiché perde le dimensioni img precedenti.
RichieHH,

Ciao supponiamo di avere diversi svg con colore differnet ciascuno. Usando questo metodo, tutti i miei colori svg diventano gli stessi del primo svg in loop. Qualche idea su come posso manovrare in modo che ogni colore rimanga lo stesso di prima?
tnkh

1
nota che se il tuo svg è fatto anche da non- pathforme (come rect) avresti bisogno di gestirle anche in CSS
Mugen,

33

Ora puoi utilizzare la proprietà CSSfilter nella maggior parte dei browser moderni (incluso Edge, ma non IE11). Funziona su immagini SVG e altri elementi. Puoi utilizzare hue-rotateo invertmodificare i colori, anche se non ti consentono di modificare colori diversi in modo indipendente. Uso la seguente classe CSS per mostrare una versione "disabilitata" di un'icona (dove l'originale è un'immagine SVG con colore saturo):

.disabled {
    opacity: 0.4;
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
}

Questo lo rende grigio chiaro nella maggior parte dei browser. In IE (e probabilmente Opera Mini, che non ho testato) è notevolmente sbiadito dalla proprietà di opacità, che sembra ancora abbastanza buona, anche se non è grigia.

Ecco un esempio con quattro diverse classi CSS per l' icona della campana Twemoji : originale (giallo), la classe "disabilitata" sopra, hue-rotate(verde) e invert(blu).


Ho appena notato che invert è una buona soluzione se non vuoi creare caratteri icona. Ho usato questo codice jQuery per cambiare l'icona nell'intestazione del mio sito Web in base alla proprietà css color (nota che sto usando icone bianche png):if ($('.w3-top img').css("color") == "rgb(0, 0, 0)") { $('.w3-top img').css("filter", "invert(100%)"); $('.w3-top img').css("-webkit-filter", "invert(100%)"); };
RedClover

Ottimo approccio Ho modificato il mio xml SVG per aggiungere il colore dell'icona di destinazione, quindi ho usato una classe disabilitata per .icon per renderlo grigio.
SushiGuy

Si noti che il vecchio Explores non supporta il filtro: w3schools.com/cssref/css3_pr_filter.asp
JillAndMe

25

In alternativa, è possibile utilizzare i CSS mask, dato che il supporto del browser non è buono ma è possibile utilizzare un fallback

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}

14
MDN specifica che -webkit-masknon deve essere utilizzato su alcun sito Web di produzione.
vaindil

1
non colorare lo SVG
Vishal

Forse è importante dire che ora, quattro anni dopo, questa soluzione funziona su tutti i principali browser. Ho appena testato qui ed è ok al 100%.
Daniel Lemes,

23

Se puoi includere file (includi o includi PHP tramite il tuo CMS preferito) nella tua pagina, puoi aggiungere il codice SVG e includerlo nella tua pagina. Funziona come incollare l'origine SVG nella pagina, ma rende il markup della pagina più pulito.

Il vantaggio è che puoi scegliere come target parti del tuo SVG tramite CSS per il passaggio del mouse - non è richiesto JavaScript.

http://codepen.io/chriscoyier/pen/evcBu

Devi solo usare una regola CSS come questa:

#pathidorclass:hover { fill: #303 !important; }

Si noti che il !importantbit è necessario per sovrascrivere il colore di riempimento.


3
Per coloro che usano AngularJS:<div ng-include="'svg.svg'"></div>
Mikel

Tuttavia, non è una soluzione molto elegante che memorizza i dati svg in un database. Non è sbagliato, ma pompare i dati DOM xml / html / svg da un'API o CMS piuttosto che usare modelli o altre risorse sembra semplicemente sbagliato.
ChristoKiwi,

Grazie per questo contributo ... I siti più avanzati oggi nidificano i dati svg per consentire tutti i tipi di attività, senza questa risposta non lo avrei immaginato!
webMan il

Inoltre, se il tuo SVG ha aree trasparenti, queste non verranno considerate come in bilico e potresti riscontrare un "hover appariscente". Per risolvere ciò, basta aggiungere un elemento wrapper (un <a>, se è conveniente) e quindi aggiungerlo alla regola CSS. #pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }O anche semplicemente eliminare il passaggio del mouse originale del percorso SVG poiché lo stai indirizzando tramite l'elemento wrapper ora comunque.
Neil Monroe,

18

@Drew Baker ha fornito un'ottima soluzione per risolvere il problema. Il codice funziona correttamente. Tuttavia, coloro che usano AngularJs possono trovare molta dipendenza da jQuery. Di conseguenza, ho pensato che fosse una buona idea incollare per gli utenti di AngularJS, un codice che segue la soluzione di @Drew Baker.

AngularJs con lo stesso codice

1. HTML : usa il tag qui sotto nel tuo file HTML:

<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>

2. Direttiva : questa sarà la direttiva che dovrai riconoscere il tag:

'use strict';
angular.module('myApp')
  .directive('svgImage', ['$http', function($http) {
    return {
      restrict: 'E',
      link: function(scope, element) {
        var imgURL = element.attr('src');
        // if you want to use ng-include, then
        // instead of the above line write the bellow:
        // var imgURL = element.attr('ng-include');
        var request = $http.get(
          imgURL,
          {'Content-Type': 'application/xml'}
        );

        scope.manipulateImgNode = function(data, elem){
          var $svg = angular.element(data)[4];
          var imgClass = elem.attr('class');
          if(typeof(imgClass) !== 'undefined') {
            var classes = imgClass.split(' ');
            for(var i = 0; i < classes.length; ++i){
              $svg.classList.add(classes[i]);
            }
          }
          $svg.removeAttribute('xmlns:a');
          return $svg;
        };

        request.success(function(data){
          element.replaceWith(scope.manipulateImgNode(data, element));
        });
      }
    };
  }]);

3. CSS :

.any-class-you-wish{
    border: 1px solid red;
    height: 300px;
    width:  120px
}

4. Unit test con karma-gelsomino :

'use strict';

describe('Directive: svgImage', function() {

  var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data;

  beforeEach(function() {
    module('myApp');

    inject(function($injector) {
      $rootScope = $injector.get('$rootScope');
      $compile = $injector.get('$compile');
      $httpBackend = $injector.get('$httpBackend');
      apiUrl = $injector.get('apiUrl');
    });

    scope = $rootScope.$new();
    element = angular.element('<svg-image src="/icons/icon-man.svg" class="svg"></svg-image>');
    element = $compile(element)(scope);

    spyOn(scope, 'manipulateImgNode').andCallThrough();
    $httpBackend.whenGET(apiUrl + 'me').respond(200, {});

    data = '<?xml version="1.0" encoding="utf-8"?>' +
      '<!-- Generator: Adobe Illustrator 17.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">' +
      '<!-- Obj -->' +
      '<!-- Obj -->' +
      '<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' +
      'width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">' +
        '<g>' +
          '<path fill="#F4A902" d=""/>' +
          '<path fill="#F4A902" d=""/>' +
        '</g>' +
      '</svg>';
    $httpBackend.expectGET('/icons/icon-man.svg').respond(200, data);
  });

  afterEach(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
  });

  it('should call manipulateImgNode atleast once', function () {
    $httpBackend.flush();
    expect(scope.manipulateImgNode.callCount).toBe(1);
  });

  it('should return correct result', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    expect(result).toBeDefined();
  });

  it('should define classes', function () {
    $httpBackend.flush();
    var result = scope.manipulateImgNode(data, element);
    var classList = ["svg"];
    expect(result.classList[0]).toBe(classList[0]);
  });
});

1
la tua soluzione non funziona, potrebbe essere<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent,

@guillaumevincent se vuoi usarlo con, ng-includebasta cambiare questa riga var imgURL = element.attr('src');invar imgURL = element.attr('ng-include');
Max

Questa è una soluzione molto utile, ma fai attenzione a usarla in modo eccessivo in quanto può compromettere le prestazioni abbastanza - IE un set di 5 icone di condivisione ripetute su un elenco di articoli o qualcosa del genere.
skxc,

1
Si è verificato un problema con il codice in IE. Puoi usare solo al if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }posto di split e for loop.
Robert Bokori,

2
Ottimo lavoro! Ma per una certa immagine devi prendere il primo elemento di svg ( angular.element(data)[0];) e farlo funzionare con IE if ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }. Inoltre potresti voler aggiungere cache: truealle opzioni $http.getaltrimenti la tua pagina potrebbe diventare molto lenta.
leo

16

Mi rendo conto che vuoi realizzare questo con CSS, ma solo un promemoria nel caso in cui sia un'immagine piccola e semplice: puoi sempre aprirla in Notepad ++ e cambiare il percorso / riempimento di qualunque elemento:

<path style="fill:#010002;" d="M394.854,205.444c9.218-15.461,19.102-30.181,14.258-49.527
    ...
    C412.843,226.163,402.511,211.451,394.854,205.444z"/>

Potrebbe salvare un sacco di brutte sceneggiature. Scusate se è off-base, ma a volte le semplici soluzioni possono essere trascurate.

... anche lo scambio di più immagini svg potrebbe avere dimensioni inferiori rispetto ad alcuni frammenti di codice per questa domanda.


7

Ho scritto una direttiva per risolvere questo problema con AngularJS. È disponibile qui - ngReusableSvg .

Sostituisce l'elemento SVG dopo il rendering e lo posiziona all'interno di un divelemento, rendendo facilmente modificabile il CSS. Ciò consente di utilizzare lo stesso file SVG in luoghi diversi utilizzando dimensioni / colori diversi.

L'utilizzo è semplice:

<object oa-reusable-svg
        data="my_icon.svg"
        type="image/svg+xml"
        class="svg-class"
        height="30"  // given to prevent UI glitches at switch time
        width="30">
</object>

Successivamente, puoi facilmente avere:

.svg-class svg {
    fill: red; // whichever color you want
}

Ciao, grazie per aver fornito questa soluzione. L'ho provato e produce: <div ng-click = "eventHandler ()" ng-class = "classEventHandler ()" style = "height: 30px; larghezza: 30px; float: left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[object SVGSVGElement]] </div> Nell'html inserisce semplicemente [[object SVGSVGElement]]. Sai qual è il problema? Un'altra domanda, ha un grande impatto sulle prestazioni o posso usarlo su molti svg su una pagina? E infine, è ancora sull'angolare 1.3 (il pergolato).
bersling

Quale versione di angolare stai usando? Non hai riscontrato il tuo problema .. forse è qualcosa con l'SVG? Per quanto riguarda le prestazioni, l'interruttore è relativamente pesante, l'ho usato da solo come 10 ed è andato bene .. Immagino che dipende dalla quantità / dimensione, quindi prova e sperimentalo. Qual è il problema con il pergolato? Stai usando una versione diversa e c'è un conflitto?
Omri Aharon,

5

TL / DR: VAI qui-> https://codepen.io/sosuke/pen/Pjoqqp

Spiegazione:

Suppongo che tu abbia html qualcosa del genere:

<img src="/img/source.svg" class="myClass">

Sicuramente seguire il percorso del filtro, ad es. il tuo svg è molto probabilmente bianco o nero. Puoi applicare un filtro per farlo diventare di qualsiasi colore tu voglia, ad esempio ho uno svg nero che voglio verde menta. In primo luogo lo invertisco per essere bianco (che è tecnicamente tutti i colori RGB pieni), quindi gioco con la saturazione della tonalità ecc. Per farlo bene:

filter: invert(86%) sepia(21%) saturate(761%) hue-rotate(92deg) brightness(99%) contrast(107%);

Ancora meglio è che potresti semplicemente usare uno strumento per convertire l'esagono che vuoi in un filtro per te: https://codepen.io/sosuke/pen/Pjoqqp


Questa è un'ottima soluzione solo per CSS, inoltre il codice da hex a filter è semplicemente fantastico.
Richi González,

4

Ecco una versione per knockout.jsbasata sulla risposta accettata:

Importante: in realtà richiede anche jQuery per la sostituzione, ma ho pensato che potrebbe essere utile ad alcuni.

ko.bindingHandlers.svgConvert =
    {
        'init': function ()
        {
            return { 'controlsDescendantBindings': true };
        },

        'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
        {
            var $img = $(element);
            var imgID = $img.attr('id');
            var imgClass = $img.attr('class');
            var imgURL = $img.attr('src');

            $.get(imgURL, function (data)
            {
                // Get the SVG tag, ignore the rest
                var $svg = $(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');

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

            }, 'xml');

        }
    };

Quindi basta applicare data-bind="svgConvert: true"al tag img.

Questa soluzione sostituisce completamente il imgtag con un file SVG e tutti i collegamenti aggiuntivi non verranno rispettati.


2
Questo è fantastico! Se vuoi portarlo al livello successivo, abbiamo una versione aggiornata che include la memorizzazione nella cache, quindi lo stesso SVG non è richiesto due volte. github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker

Ero un po 'preoccupato per questo, ma non ho avuto il tempo di esaminarlo da solo.
Avevo

1
@DrewBaker in realtà ero più preoccupato che il tag img avrebbe richiesto il file e quindi l' getavrebbe richiesto di nuovo. Ho considerato cambiando la srcad un data-srcattributo del imgtag, ma ha concluso che i browser moderni sono probabilmente abbastanza intelligente per memorizzare nella cache il file in ogni caso
Simon_Weaver

3

Ecco un codice no framework, solo js puro:

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

3

Esiste una libreria open source chiamata SVGInject che utilizza l' onloadattributo per attivare l'iniezione. Puoi trovare il progetto GitHub su https://github.com/iconfu/svg-inject

Ecco un esempio minimo usando SVGInject:

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

Dopo che l'immagine è stata caricata, onload="SVGInject(this)verrà innescata l'iniezione e l' <img>elemento verrà sostituito dal contenuto del file SVG fornito srcnell'attributo.

Risolve diversi problemi con l'iniezione SVG:

  1. Gli SVG possono essere nascosti fino al termine dell'iniezione. Questo è importante se uno stile è già applicato durante il tempo di caricamento, che altrimenti causerebbe un breve "flash di contenuto non stilato".

  2. Gli <img>elementi si iniettano automaticamente. Se aggiungi SVG in modo dinamico, non devi preoccuparti di chiamare nuovamente la funzione di iniezione.

  3. Una stringa casuale viene aggiunta a ciascun ID nel file SVG per evitare di avere lo stesso ID più volte nel documento se un SVG viene iniettato più di una volta.

SVGInject è semplice Javascript e funziona con tutti i browser che supportano SVG.

Disclaimer: sono il coautore di SVGInject


1
Mi piace di più questa soluzione, perché si occupa di SVG aggiunti dinamicamente.
VickyB,

2

Se abbiamo un numero maggiore di tali immagini svg, possiamo anche prendere l'aiuto di file di font.
Siti come https://glyphter.com/ possono procurarci un file di font dal nostro svgs.


Per esempio

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

5
Personalmente odio la tecnica delle "immagini come carattere". Rende difficile aggiungere / modificare immagini, aggiunge un sacco di markup senza senso. I caratteri dovrebbero essere caratteri, immagini dovrebbero essere immagini ecc.
Drew Baker,

Concordato. È inoltre necessario ricordare / cercare le immagini assegnate ai personaggi. ma nel caso specifico in cui le immagini vengono utilizzate come icone / pulsanti / punti elenco, fungono più da testo che da media, i file di caratteri possono anche essere un'alternativa
Abhishek Borar

anche github non usa più il font per icon github.com/blog/2112-delivering-octicons-with-svg
gagarine

2

È possibile utilizzare l'immagine dei dati per questo. usando data-image (data-URI) puoi accedere a SVG come inline.

Ecco l'effetto di rollover usando CSS e SVG puri.

Lo so disordinato ma puoi farlo in questo modo.

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

Puoi convertire il tuo svg in url di dati qui

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

Questo non funzionerebbe per SVG complessi in cui si desidera cambiare solo determinati percorsi / poligoni / ecc. Al passaggio del mouse, giusto?
Drew Baker

No, puoi ... ma è molto complesso
patelarpan,

Sono solo soluzioni per icona
patelarpan

Se alcuni funzionano con l'icona. Quindi fantastico. Bootstrap 4 usa anche questa tecnica
patelarpan

2

Poiché SVG è fondamentalmente un codice, sono necessari solo i contenuti. Ho usato PHP per ottenere contenuti, ma puoi usare quello che vuoi.

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

Quindi, ho stampato il contenuto "così com'è" all'interno di un contenitore div

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

Per impostare in modo definitivo la regola sui figli SVG del container su CSS

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

Ho ottenuto questi risultati con un'icona materiale SVG:

  1. Mozilla Firefox 59.0.2 (64-bit) Linux

inserisci qui la descrizione dell'immagine

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

inserisci qui la descrizione dell'immagine

  1. Opera 53.0.2907.37 Linux

inserisci qui la descrizione dell'immagine


1

La soluzione selezionata va bene se vuoi che jQuery elabori tutti gli elementi svg nel tuo DOM e il tuo DOM abbia dimensioni ragionevoli. Ma se il tuo DOM è grande e decidi di caricare parti del tuo DOM in modo dinamico, non ha davvero senso dover ripetere la scansione dell'intero DOM solo per aggiornare gli elementi svg. Invece, usa un plugin jQuery per fare questo:

/**
 * A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
 *
 * The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
 *
 * The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
 * underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
 * any styles in a style class instead.
 */
(function ($) {
    $.fn.svgLoader = function () {
        var src = $(this).attr("src");
        var width = this.attr("width");
        var height = this.attr("height");
        var cls = this.attr("class");
        var ctx = $(this);

        // Get the svg file and replace the <svg> element.
        $.ajax({
            url: src,
            cache: false
        }).done(function (html) {
            let svg = $(html);
            svg.attr("width", width);
            svg.attr("height", height);
            svg.attr("class", cls);
            var newHtml = $('<a></a>').append(svg.clone()).html();
            ctx.replaceWith(newHtml);
        });

        return this;
    };

}(jQuery));

Nel tuo html, specifica un elemento svg come segue:

<svg src="images/someSvgFile.svg" height="45" width="45" class="mySVGClass"/>

E applica il plug-in:

$(".mySVGClass").svgLoader();

Sì, ci sono sicuramente modi più efficienti per usare il codice che ho dato. Ecco come lo usiamo effettivamente nei siti di produzione. Memorizza gli SVG! github.com/funkhaus/style-guide/blob/master/template/js/…
Drew Baker,

1

per: animazioni di eventi al passaggio del mouse possiamo lasciare gli stili all'interno del file svg, come a

<svg xmlns="http://www.w3.org/2000/svg">
<defs>
  <style>
  rect {
    fill:rgb(165,225,75);
    stroke:none;
    transition: 550ms ease-in-out;
    transform-origin:125px 125px;
  }
  rect:hover {
    fill:rgb(75,165,225);
    transform:rotate(360deg);
  }
  </style>
</defs>
  <rect x='50' y='50' width='150' height='150'/>
</svg>

controlla questo su svgshare

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.