How to change color of SVG image using CSS (jQuery SVG image replacement)?

后端 未结 17 1955
死守一世寂寞
死守一世寂寞 2020-11-21 17:36

This is a self Q&A of a handy piece of code I came up with.

Currently, there isn\'t an easy way to embed an SVG image and then have access to the SVG elements vi

相关标签:
17条回答
  • 2020-11-21 18:03

    You can use data-image for that. using data-image(data-URI) you can access SVG like inline.

    Here is rollover effect using pure CSS and SVG.

    I know it messy but you can do this way.

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

    You can convert your svg to data url here

    1. https://codepen.io/elliz/full/ygvgay
    2. https://websemantics.uk/tools/svg-to-background-image-conversion/
    0 讨论(0)
  • 2020-11-21 18:03

    The selected solution is fine if you want jQuery to process all svg elements in your DOM and your DOM is of reasonable size. But if your DOM is large and you decide to load parts of your DOM dynamically, it really makes no sense to have to rescan the entire DOM just to update svg elements. Instead, use a jQuery plugin to do this:

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

    In your html, specify an svg element as follows:

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

    And apply the plugin:

    $(".mySVGClass").svgLoader();
    
    0 讨论(0)
  • 2020-11-21 18:07

    If you can include files (PHP include or include via your CMS of choice) in your page, you can add the SVG code and include it into your page. This works the same as pasting the SVG source into the page, but makes the page markup cleaner.

    The benefit is that you can target parts of your SVG via CSS for hover -- no javascript required.

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

    You just have to use a CSS rule like this:

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

    Note that the !important bit is necessary to override the fill color.

    0 讨论(0)
  • 2020-11-21 18:08

    You can now use the CSS filter property in most modern browsers (including Edge, but not IE11). It works on SVG images as well as other elements. You can use hue-rotate or invert to modify colors, although they don't let you modify different colors independently. I use the following CSS class to show a "disabled" version of an icon (where the original is an SVG picture with saturated color):

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

    This makes it light grey in most browsers. In IE (and probably Opera Mini, which I haven't tested) it is noticeably faded by the opacity property, which still looks pretty good, although it's not grey.

    Here's an example with four different CSS classes for the Twemoji bell icon: original (yellow), the above "disabled" class, hue-rotate (green), and invert (blue).

    .twa-bell {
      background-image: url("https://twemoji.maxcdn.com/svg/1f514.svg");
      display: inline-block;
      background-repeat: no-repeat;
      background-position: center center;
      height: 3em;
      width: 3em;
      margin: 0 0.15em 0 0.3em;
      vertical-align: -0.3em;
      background-size: 3em 3em;
    }
    .grey-out {
      opacity: 0.4;
      filter: grayscale(100%);
      -webkit-filter: grayscale(100%);
    }
    .hue-rotate {
      filter: hue-rotate(90deg);
      -webkit-filter: hue-rotate(90deg);
    }
    .invert {
      filter: invert(100%);
      -webkit-filter: invert(100%);
    }
    <!DOCTYPE html>
    <html>
    
    <head>
    </head>
    
    <body>
      <span class="twa-bell"></span>
      <span class="twa-bell grey-out"></span>
      <span class="twa-bell hue-rotate"></span>
      <span class="twa-bell invert"></span>
    </body>
    
    </html>

    0 讨论(0)
  • 2020-11-21 18:10

    I wrote a directive to solve this issue with AngularJS. It is available here - ngReusableSvg.

    It replaces the SVG element after it's been rendered, and places it inside a div element, making its CSS easily changeable. This helps using the same SVG file in different places using different sizes/colors.

    The usage is simple:

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

    After that, you can easily have:

    .svg-class svg {
        fill: red; // whichever color you want
    }
    
    0 讨论(0)
  • 2020-11-21 18:10

    Since SVG is basically code, you need just contents. I used PHP to obtain content, but you can use whatever you want.

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

    Then, I've printed content "as is" inside a div container

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

    To finnaly set rule to container's SVG childs on CSS

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

    I got this results with a material icon SVG:

    1. Mozilla Firefox 59.0.2 (64-bit) Linux

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

    1. Opera 53.0.2907.37 Linux

    0 讨论(0)
提交回复
热议问题