¿Cómo cambiar el color de la imagen SVG usando CSS (reemplazo de imagen jQuery SVG)?

Resuelto Drew Baker asked hace 12 años • 19 respuestas

Esta es una sesión de preguntas y respuestas sobre un código útil que se me ocurrió.

Actualmente, no existe una manera fácil de incrustar una imagen SVG y luego tener acceso a los elementos SVG a través de CSS. Existen varios métodos para usar marcos JS SVG, pero son demasiado complicados si todo lo que hace es crear un ícono simple con un estado de desplazamiento.

Esto es lo que se me ocurrió, que creo que es, con diferencia, la forma más sencilla de utilizar archivos SVG en un sitio web. Toma su concepto de los primeros métodos de reemplazo de texto a imagen, pero hasta donde yo sé, nunca se ha hecho para SVG.

Esta es la pregunta:

¿Cómo incrusto un SVG y cambio su color en CSS sin utilizar un marco JS-SVG?

Drew Baker avatar Aug 16 '12 07:08 Drew Baker
Aceptado

En primer lugar, utilice una etiqueta IMG en su HTML para incrustar un gráfico SVG. Usé Adobe Illustrator para hacer el gráfico.

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

Esto es como insertar una imagen normal. Tenga en cuenta que debe configurar el IMG para que tenga una clase de svg. La clase de 'vínculo social' es sólo para dar ejemplos. La identificación no es obligatoria, pero es útil.

Luego use este código jQuery (en un archivo separado o en línea en 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');

        });

Lo que hace el código anterior es buscar todos los IMG con la clase 'svg' y reemplazarlos con el SVG en línea del archivo vinculado. La gran ventaja es que te permite usar CSS para cambiar el color del SVG ahora, así:

svg:hover path {
    fill: red;
}

El código jQuery que escribí también traslada el ID y las clases de las imágenes originales. Entonces este CSS también funciona:

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

O:

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

Puede ver un ejemplo de cómo funciona aquí: http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

Tenemos una versión más complicada que incluye almacenamiento en caché aquí: https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90

Drew Baker avatar Aug 16 '2012 00:08 Drew Baker

Estilo

svg path {
    fill: #000;
}

Guion

$(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');
    });
});
Henrik Albrechtsson avatar Feb 01 '2016 09:02 Henrik Albrechtsson

Ahora puede utilizar la propiedad CSSfilter en la mayoría de los navegadores modernos (incluido Edge, pero no IE11). Funciona con imágenes SVG y con otros elementos. Puedes usar hue-rotateo invertpara modificar colores, aunque no te permiten modificar diferentes colores de forma independiente. Utilizo la siguiente clase CSS para mostrar una versión "deshabilitada" de un ícono (donde el original es una imagen SVG con color saturado):

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

Esto lo hace gris claro en la mayoría de los navegadores. En IE (y probablemente en Opera Mini, que no he probado) está notablemente descolorido por la propiedad de opacidad, que todavía se ve bastante bien, aunque no es gris.

Aquí hay un ejemplo con cuatro clases CSS diferentes para el ícono de campana de Twemoji : original (amarillo), la clase "deshabilitada" anterior hue-rotate(verde) y invert(azul).

Mostrar fragmento de código

aldel avatar Jun 28 '2016 19:06 aldel

Alternativamente, podrías usar CSS mask, la compatibilidad con el navegador no es buena, pero podrías usar un respaldo.

.frame {
    background: blue;
    -webkit-mask: url(image.svg) center / contain no-repeat;
}
seanjacob avatar Aug 14 '2014 10:08 seanjacob