CSS(jQuery SVG画像の置き換え)を使用してSVG画像の色を変更する方法


437

これは、私が思いついた便利なコードの自己Q&Aです。

現在、SVG画像を埋め込み、CSSを介してSVG要素にアクセスする簡単な方法はありません。JS SVGフレームワークを使用するにはさまざまな方法がありますが、ロールオーバー状態のシンプルなアイコンを作成するだけの場合は、非常に複雑です。

これが私が思いついたものです。これは、WebサイトでSVGファイルを使用する最も簡単な方法だと思います。それは、初期のテキストからイメージへの置換方法からその概念を取り入れていますが、私が知る限り、SVGに対して行われたことはありません。

これは質問です:

JS-SVGフレームワークを使用せずにSVGを埋め込み、その色をCSSで変更するにはどうすればよいですか?


1
残念ながら、imgタグはIEのsvgファイルでは機能しないため、注意してください。IEは埋め込みタグを認識します。とにかく、いい仕事だ!

2
svgの場合、「fill」cssプロパティを使用する必要があります。画像の場合は、「フィルター」を使用するのが適切です。「フィルター」は実際には両方で機能しますが、ベクターグラフィックですべての機能を実行する必要はありません。
Samy Bencherif 2016

回答:


536

まず、HTMLでIMGタグを使用してSVGグラフィックを埋め込みます。Adobe Illustratorを使用してグラフィックを作成しました。

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

これは、通常の画像を埋め込む方法と同じです。IMGがsvgのクラスを持つように設定する必要があることに注意してください。'social-link'クラスは単なる例です。IDは必須ではありませんが、役立ちます。

次に、このjQueryコードを使用します(別のファイルまたは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');

        });

上記のコードは、クラス「svg」を持つすべてのIMGを探し、リンクされたファイルからのインラインSVGで置き換えます。大きな利点は、CSSを使用してSVGの色を変更できることです。

svg:hover path {
    fill: red;
}

私が書いたjQueryコードも、元のイメージIDとクラス全体に移植されています。したがって、このCSSも機能します。

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

または:

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

ここで動作する例を見ることができます:http : //labs.funkhausdesign.com/examples/img-svg/img-to-svg.html

ここにはキャッシュを含むより複雑なバージョンがあります:https : //github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90


6
Safariでは(たとえば)機能しない場合があります。返されたデータが読み取り可能であることを確認するには});、$。getを置き換えます}, 'xml');
Joan

29
セレクタを置き換えてimg[src$=".svg"]svgクラスの必要性をなくすこともできます。
Casey Chu

2
@LeonGaban背景画像の塗りつぶしをターゲットにする方法はないと思います。できればそれは非常に役に立ちます!
Drew Baker

3
少し遅れて@LeonGabanですが、より良い方法は、おそらくfill属性を完全に削除し、CSSファイルを使用して親svgにfillを追加することです。$('#ico_company path').removeAttr('fill')。次に#ico_company { fill: #ccc }、CSSファイルで行うことができます
bioball '16年

2
@Soakuでは、j varですべてのパスをフォントの色と同じに設定して、 `var color = $ img.closest( 'p')。css( 'color');のようにするのは簡単です。$ svg.find( 'path')。attr( 'fill'、color); `しかし、これはCSSに任せる方がましだと思います。
Drew Baker

56

スタイル

svg path {
    fill: #000;
}

脚本

$(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
幅属性がない場合は、間違った数の属性が作成されるだけです。width="170.667"私の場合
ストール1

2
以前のimgの寸法が失われるため、これは完璧ではありません。
RichieHH 2017年

こんにちは私はそれぞれ異なるネットカラーで異なるsvgを持っていると仮定します。この方法を使用すると、すべてのsvgカラーが、ループされている最初のsvgと同じになります。どのようにこれを回避して、各色が以前と同じになるように操作できますか?
tnkh

1
svgがpath(のようなrect)非形状からも作成されている場合は、それらもcssで処理する必要があることに注意してください
Mugen

33

CSSを使用できるようになりましたfilter最近のほとんどのブラウザー(Edgeを含むがIE11は不可)でプロパティを。SVG画像やその他の要素で機能します。hue-rotateまたはinvertを使用して色を変更できますが、色を個別に変更することはできません。次のCSSクラスを使用して、アイコンの「無効」バージョンを表示します(元のアイコンは飽和色のSVG画像です)。

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

これにより、ほとんどのブラウザで明るい灰色になります。IE(およびおそらく私がテストしていないOpera Mini)では、灰色ではありませんが、不透明度プロパティによって著しくフェードします。

Twemojiベルのアイコンに4つの異なるCSSクラスを使用した例を次に示します。オリジナル(黄色)、上記の「無効」クラス、hue-rotate(緑)、invert(青)。


アイコンフォントを作成したくない場合は、invertが優れたソリューションであることに注意してください。私はこのjQueryコードを使用して、cssのcolorプロパティに従ってWebサイトのヘッダーのアイコンを変更しました(白い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

素晴らしいアプローチ。SVG xmlを編集してターゲットアイコンの色を追加し、.icon-disabledクラスを使用して灰色にしました。
SushiGuy


25

またはmask、CSSを使用することもできますが、ブラウザのサポートは適切ではありませんが、フォールバックを使用できます。

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

14
MDN-webkit-maskは、本番ウェブサイトでは使用しないことを指定しています。
vaindil 2016年

1
SVGを色付け

たぶん、4年後の今、このソリューションはすべての主要なブラウザーで機能していると言えるでしょう。ここでテストしただけで100%正常です。
Daniel Lemes

23

ページにファイル(PHPインクルードまたは選択したCMSを介したインクルード)を含めることができる場合は、SVGコードを追加してページに含めることができます。これは、SVGソースをページに貼り付けるのと同じように機能しますが、ページのマークアップがよりクリーンになります。

利点は、ホバーのためにCSSを介してSVGの一部をターゲットにできることです。JavaScriptは必要ありません。

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

次のようなCSSルールを使用する必要があります。

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

!important塗りつぶし色を上書きするにはビットが必要であることに注意してください。


3
AngularJSを使用している場合:<div ng-include="'svg.svg'"></div>
Mikel

ただし、データベースにsvgデータを保存する非常にエレガントなソリューションではありません。間違いではありませんが、テンプレートやその他のアセットを使用するのではなく、APIまたはCMSからxml / html / svg DOMデータを汲み出すのは間違っていると感じています。
ChristoKiwi 2017

この貢献をありがとう...今日の最も先進的なサイトは、あらゆる種類の活動を可能にするためにsvgデータをネストしています。この答えがなければ、私はそれを推測していませんでした!
webMan、2017年

さらに、SVGに透明な領域がある場合、これらはホバリングとしてカウントされず、「派手なホバリング」が発生する可能性があります。これを修正するには、ラッパー要素(便利な場合は<a>)を追加し、それをCSSルールに追加します。#pathidorclass:hover, .wrapperclass:hover #pathidorclass { fill: green; }あるいは、とにかく今ラッパー要素を介してSVGパスをターゲットにしているため、SVGパスの元のホバーを削除するだけです。
Neil Monroe

18

@Drew Bakerは、問題を解決するための優れたソリューションを提供しました。コードは正しく動作します。ただし、AngularJを使用するユーザーは、jQueryに多くの依存関係を見つける可能性があります。したがって、@ Drew Bakerのソリューションに続くコードであるAngularJSユーザーに貼り付けることをお勧めします。

同じコードのAngularJsの方法

1. HTML:HTMLファイルで次のタグを使用します。

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

2.ディレクティブ:これは、タグを認識するために必要なディレクティブになります。

'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. karma-jasmineを使用した単体テスト

'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
あなたの解決策はうまくいかないかもしれません<div ng-include="/icons/my.svg" class="any-class-you-wish"></div>
Guillaume Vincent

あなたがそれを使用したい場合は@guillaumevincent ng-includeそしてちょうどこの行を変更var imgURL = element.attr('src');するvar imgURL = element.attr('ng-include');
最大

これは非常に便利な解決策ですが、パフォーマンスに非常に大きな影響を与える可能性があるため、使いすぎには注意してください。
skxc 2015年

1
IEのコードに問題があります。if (typeof(imgClass) !== 'undefined') { $svg.setAttribute("class", imgClass); }splitとforループの代わりに使用できます。
Robert Bokori 2015年

2
お見事!ただし、特定の画像については、svg(angular.element(data)[0];)の最初の要素を取得して、IEで使用できるようにする必要がありますif ($svg.getAttribute('class')) { $svg.setAttribute('class', $svg.getAttribute('class') + ' ' + imgClass); } else { $svg.setAttribute('class', imgClass); }。またcache: true、オプションを追加すると、$http.getページが非常に遅くなる場合があります。
レオ

16

CSSでこれを実現したいのですが、それが小さくてシンプルな画像である場合は、リマインダーです。いつでもNotepad ++で開いてパス/ whateverelementの塗りつぶしを変更できます。

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

醜いスクリプトを大量に保存できます。基準を外れている場合は申し訳ありませんが、簡単な解決策を見落とす場合があります。

...複数のsvg画像を入れ替えても、この質問の一部のコードスニペットよりサイズが小さくなる場合があります。


7

AngularJSでこの問題を解決するためのディレクティブを作成しました。ここから入手できます-ngReusableSvg

レンダリング後にSVG要素を置き換え、それを内部に配置します divて、CSSを簡単に変更できるようにします。これは、異なるサイズ/色を使用する異なる場所で同じSVGファイルを使用するのに役立ちます。

使い方は簡単です:

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

その後、簡単に次のことができます。

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

こんにちは、このソリューションを提供してくれてありがとう。私は試してみましたが、次の結果が得られます。<div ng-click = "eventHandler()" ng-class = "classEventHandler()" style = "height:30px; width:30px; float:left;" class = "svg-class" id = "my-svg" height = "30" width = "30"> [[object SVGSVGElement]] </ div> htmlには、[[object SVGSVGElement]]を配置するだけです。何が問題なのか知っていますか?別の質問、それはパフォーマンスに大きな影響を与えますか、それともページ上の多くのsvgで使用できますか?そして最後に、それはまだ角度1.3(バウアー)です。
2016年

どのバージョンのangularを使用していますか?問題が発生していません。SVGの問題でしょうか。パフォーマンスに関しては、スイッチは比較的重く、私は10くらいで自分で使用しましたが、問題ありませんでした。それは量/サイズに依存するので、試行錯誤してください。バウアーの何が問題なのですか?別のバージョンを使用していて、競合がありますか?
Omri Aharon 2016年

5

TL / DR:GO here-> https://codepen.io/sosuke/pen/Pjoqqp

説明:

私はあなたがこのようなhtmlを持っていると仮定しています:

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

間違いなくフィルタールートに行く、すなわち。SVGはおそらく黒または白です。フィルターを適用して、好きな色にすることができます。たとえば、私はミントグリーンが欲しい黒のsvgを持っています。私は最初にそれを白に反転します(これは技術的にはすべてのRGBカラーです)、次に色相の彩度などを試します。それを正しくするには:

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

さらに良いのは、ツールを使用して、必要な16進数をフィルターに変換できることです。https//codepen.io/sosuke/pen/Pjoqqp


これはCSSのみの優れたソリューションであり、さらに16進数からフィルターまでのコードペンは素晴らしいです。
RichiGonzález

4

ここにバージョンがあります knockout.js承認された回答に基づくは次のとおりです。

重要:置き換えるために実際にはjQueryも必要ですが、一部のユーザーにとっては役立つと思いました。

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

        }
    };

次に適用するだけです data-bind="svgConvert: true"、imgタグにします。

このソリューションはimgタグをSVGに完全に置き換え、追加のバインディングは考慮されません。


2
これは素晴らしい!それを次のレベルに引き上げたい場合は、キャッシュを含む更新バージョンがあるため、同じSVGが2回要求されることはありません。github.com/funkhaus/style-guide/blob/master/template/js/...
ドリューベーカー

少し心配でしたが、自分で調べる時間はありませんでした。簡単なものが必要
Simon_Weaver

1
@DrewBakerは実際には、imgタグがファイルを要求し、getそれが再度要求することを心配していました。タグの属性に変更するsrcことを検討しましたが、最新のブラウザはおそらくファイルをキャッシュするのに十分スマートであると結論しましたdata-srcimg
Simon_Weaver

3

これはフレームワークのないコードで、純粋なjsのみです:

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

onload属性を使用してインジェクションをトリガーするSVGInjectと呼ばれるオープンソースライブラリがあります。GitHubプロジェクトは次の場所にあります https://github.com/iconfu/svg-injectにあります。

SVGInjectを使用した最小限の例を次に示します。

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

画像が読み込まれた後、onload="SVGInject(this)はインジェクションをトリガーし、<img>要素はで提供されるSVGファイルのコンテンツに置き換えられますsrc属性でます。

SVGインジェクションに関するいくつかの問題を解決します。

  1. インジェクションが完了するまでSVGを非表示にできます。これは、ロード時にスタイルがすでに適用されている場合に重要です。そうしないと、短い「スタイルのないコンテンツがフラッシュ」します。

  2. <img>自動的themselved注入要素。SVGを動的に追加する場合、インジェクション関数を再度呼び出すことを心配する必要はありません。

  3. SVGが複数回挿入された場合にドキュメントで同じIDが複数回使用されるのを防ぐために、ランダムな文字列がSVGの各IDに追加されます。

SVGInjectはプレーンJavascriptであり、SVGをサポートするすべてのブラウザーで動作します。

免責事項:私はSVGInjectの共著者です


1
動的に追加されたSVGを処理するため、このソリューションが最も気に入っています。
VickyB

2

そのようなsvg画像の数が多い場合は、フォントファイルを利用することもできます。https://glyphter.com/の
ようなサイトでは、svgからフォントファイルを取得できます。


例えば

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

5
私は個人的に「フォントとしての画像」テクニックが嫌いです。画像の追加/編集が難しくなり、無意味なマークアップがたくさん追加されます。フォントのフォントである必要があり、画像は画像などでなければなりません
ドリューベーカー

同意した。また、キャラクターに割り当てられた画像を記憶/参照する必要があります。しかし、画像がアイコン/ボタン/箇条書きとして使用され、メディアよりもテキストとして機能する特定のケースでは、フォントファイルも代替となります
Abhishek Borar

githubでもアイコンのフォントをもう使用しないgithub.com/blog/2112-delivering-octicons-with-svg
gagarine

2

そのためにdata-imageを使用できます。data-image(data-URI)を使用すると、インラインのようにSVGにアクセスできます。

これは、純粋なCSSとSVGを使用したロールオーバー効果です。

私はそれが乱雑であることを知っていますが、あなたはこのようにすることができます。

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

ここでsvgをデータURLに変換できます

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

これは、特定のパス/ポリゴンなどをホバーしたときに変更するだけの複雑なSVGでは機能しませんか?
Drew Baker、

いいえ、できませんが、非常に複雑です
パテラーパン

それはアイコンのソリューションにすぎません
パテルパン

一部のアイコンで動作する場合。その後、それは素晴らしいです。ブートストラップ4もこのテクニックを使用しています
パテラーパン2018年

2

SVGは基本的にコードなので、コンテンツだけで十分です。私はPHPを使用してコンテンツを取得しましたが、好きなように使用できます。

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

次に、divコンテナー内にコンテンツを「そのまま」印刷しました

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

CSSでコンテナのSVG子に最終的にルールを設定するには

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

マテリアルアイコンSVGでこの結果を得ました。

  1. Mozilla Firefox 59.0.2(64ビット)Linux

ここに画像の説明を入力してください

  1. Google Chrome66.0.3359.181(公式ビルド)(64ビット)Linux

ここに画像の説明を入力してください

  1. Opera 53.0.2907.37 Linux

ここに画像の説明を入力してください


1

選択したソリューションは、jQueryがDOM内のすべてのsvg要素を処理し、DOMが適切なサイズである場合は問題ありません。ただし、DOMが大きく、DOMの一部を動的にロードする場合、svg要素を更新するためだけにDOM全体を再スキャンする必要はありません。代わりに、jQueryプラグインを使用してこれを行います。

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

HTMLで、次のようにsvg要素を指定します。

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

そしてプラグインを適用します:

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

確かに、私が提供したコードを使用するより効率的な方法があります。これが実際に生産現場で使用する方法です。SVGをキャッシュします!github.com/funkhaus/style-guide/blob/master/template/js/...
ドリューベーカー

1

:hoverイベントアニメーションの場合、スタイルをsvgファイル内に残すことができます。

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

svgshareでこれを確認してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.