img src SVG CSSでスタイルを変更する


374

html

<img src="logo.svg" alt="Logo" class="logo-img">

CSS

.logo-img path {
  fill: #000;
}

上記のsvgはネイティブで読み込まれますfill: #fffが、上記を使用してcssそれを黒に変更しようとしても、変更されません。これがSVGでの初めてのプレイであり、なぜ機能しないのかわかりません。


25
そのようなSVG 画像に影響を与えることはできません...インラインSVG要素のみ
Paulie_D


SVGとCSSのコンテンツを使用するには、ここで私の回答を確認してください。stackoverflow.com/questions/11978995/...
ベンジャミン

回答:


153

ロゴの色を変更することだけが目的で、CSSを使用する必要がない場合は、以前のいくつかの回答で提案されているように、javascriptまたはjqueryを使用しないでください。

元の質問に正確に答えるには、次のようにします。

  1. logo.svgテキストエディタでを開きます。

  2. 探してfill: #fffそれを置き換えるfill: #000

たとえばlogo.svg、テキストエディターで開くと、次のようになります。

<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
  <path d="M0 0h24v24H0z" fill="none"/>
  <path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z" fill="#fff"/>
</svg>

...塗りつぶしを変更して保存します。


6
...「塗りつぶし」がない場合は、pathまたはのcircleようなアイテムに追加できます<path fill="#777777" d="m129.774,74.409c-5.523,...
SaeX

1
ロゴのヘッダーの色とフッターの色が異なる場合はどうなりますか?
rubens.lopes 2017年

。@ ruben.lopes 2つの異なるファイル、または2つの異なるインラインが最も単純です
Rowe Morehouse

11
あなたも使用することができfill="currentColor"、次に使うcolor親要素の上css-tricks.com/cascading-svg-fill-color
セルジュ・

10
これは明らかに可能であり、実際に役立つ回答ではありません。
Timmmm

101

SVGをマスクとして設定できます。このように、背景色を設定すると、塗りつぶし色として機能します。

HTML

<div class="logo"></div>

CSS

.logo {
    background-color: red;
    -webkit-mask: url(logo.svg) no-repeat center;
    mask: url(logo.svg) no-repeat center;
}

JSFiddle: https
: //jsfiddle.net/KuhlTime/2j8exgcb/ MDN:https ://developer.mozilla.org/en-US/docs/Web/CSS/mask

ブラウザがこの機能をサポートしているかどうかを確認してください:https : //caniuse.com/#search=mask


3
したがって、内部Webサイト以外は使用できません。
Henrik Vendelbo 2017年

9
2016
。– Gajus

1
これは、ここで説明されているような状況での素晴らしいソリューションです。CSSでデータURI以外のものを使用するのは少し面倒です。ありがとう!
Gark Garcia、

3
動いていない。それは言うmaskですinvalid property value。私はこれをクロムでテストしています。
Eren555

1
@MadMac同じバージョンのChromeを実行していますが、その動作を再現できませんでした。あなたが試したJSFiddleですか、それともコードですか?
アンドレ・KUHLMANN

78

純粋なCSSを試してください:

.logo-img {
  // to black
  filter: invert(1);
  // or to blue
  // filter: invert(1) sepia(1) saturate(5) hue-rotate(175deg);
}

この記事の詳細https://blog.union.io/code/2017/08/10/img-svg-fill/


最近、私の試みの1つで、他のブラウザーとは異なる色をEdgeで取得していました。
Julix

4
これはほとんどのブラウザーで機能しますが、IOS-Safariブラウザーでいくつかの問題がありました。
Simon Ludwig

30

2018:動的な色が必要で、JavaScriptを使用したくない場合、およびインラインSVGを使用したくない場合は、CSS変数を使用します。Chrome、Firefox、Safariで動作します。編集:エッジ

<svg>
    <use xlink:href="logo.svg" style="--color_fill: #000;"></use>
</svg>

あなたのSVGでは、任意のインスタンスを置き換えるstyle="fill: #000"としますstyle="fill: var(--color_fill)"


1
これに対するブラウザのサポートは
どうですか

@KevinGoedecke Chrome、Firefox、Safari、およびEdge
北アメリカ

4
SVG 2で非推奨と思われる
vsync 2018

5
@northamerican-「証明」としての他のスタックオーバーフローの回答へのリンクは無関係です。誰でもこのプラットフォームで何でも書くことができます。MDN:"This feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped"
vsync

8
と思われるxlink:hrefの賛成で廃止されましたhref。したがって、これはまだ機能する可能性があります。
Benjamin Intal 2018年

20

まず、SVGをHTML DOMに挿入する必要があります。

これを行うSVGInjectと呼ばれるオープンソースライブラリがあります。onload属性を使用して注入をトリガーします。

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>要素はsrc属性で提供されるSVGファイルのコンテンツに置き換えられます。

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

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

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

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

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

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


3
これが最も簡単な答えです。私はそれをChrome、Firefox、Edgeでテストしましたが、完全に機能します。
セバスチャンロリオン

15

@Praveenからの答えは確かです。

私の仕事ではそれを応答させることができなかったので、jqueryのホバー関数を作成しました。

CSS

.svg path {
   transition:0.3s all !important;
}

JS / JQuery

// code from above wrapped into a function
replaceSVG();

// hover function
// hover over an element, and find the SVG that you want to change
$('.element').hover(function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#CCC');
}, function() {
    var el = $(this);
    var svg = el.find('svg path');
    svg.attr('fill', '#3A3A3A');
});

1
これは、SVGが最初にインラインであった場合にのみ機能しませんか?
Daniel Thompson

はい。ただし、多数のSVGファイルで作業している場合や定期的に更新している場合は、管理が面倒です。
Matt Wujek 2017年

15

svg画像でwebfontを作成し、cssにwebfontをインポートして、css color属性を使用してグリフの色を変更してみませんか?JavaScriptは必要ありません


5
svgに異なる色の要素がいくつかある場合、このソリューションは非常にハッキングされます(いくつかの要素が挿入されます)。
カカジャ2017

1
@kakajaこれは、1色のベクター画像専用のソリューションです。詳細については、bpulecioの回答を参照してください
gringo

1
アイコンはテキストではないためです。フォントはテキスト用です。Svgはアイコン用です。
LazarLjubenović18年

2
@LazarLjubenović-技術的にはテキストは記号である文字で構成され、アイコンは記号でもあるので、アイコンフォントを使用しても問題が生じないのはこのためです。「別の」テキスト言語を作成するのと同じです。マンダリンは文字ではなく「アイコン」を使用します。アイコンを「テキスト」として使用することは人類では珍しくありません
vsync

1
これは興味深い解決策のように聞こえますが、答えを「なぜしない」ではなく「どうやって」のようなものに詳しく説明することをお勧めします
YakovL

15

この回答は回答に基づいていますhttps://stackoverflow.com/a/24933495/3890888が、そこで使用されているスクリプトのプレーンJavaScriptバージョンを使用しています。

SVGをインラインSVGにする必要がありますsvg画像にクラスを追加することにより、このスクリプトを利用できます。

/*
 * Replace all SVG images with inline SVG
 */
document.querySelectorAll('img.svg').forEach(function(img){
    var imgID = img.id;
    var imgClass = img.className;
    var imgURL = img.src;

    fetch(imgURL).then(function(response) {
        return response.text();
    }).then(function(text){

        var parser = new DOMParser();
        var xmlDoc = parser.parseFromString(text, "text/xml");

        // Get the SVG tag, ignore the rest
        var svg = xmlDoc.getElementsByTagName('svg')[0];

        // Add replaced image's ID to the new SVG
        if(typeof imgID !== 'undefined') {
            svg.setAttribute('id', imgID);
        }
        // Add replaced image's classes to the new SVG
        if(typeof imgClass !== 'undefined') {
            svg.setAttribute('class', imgClass+' replaced-svg');
        }

        // Remove any invalid XML tags as per http://validator.w3.org
        svg.removeAttribute('xmlns:a');

        // Check if the viewport is set, if the viewport is not set the SVG wont't scale.
        if(!svg.getAttribute('viewBox') && svg.getAttribute('height') && svg.getAttribute('width')) {
            svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
        }

        // Replace image with new SVG
        img.parentNode.replaceChild(svg, img);

    });

});

そして今、あなたがするなら:

.logo-img path {
  fill: #000;
}

または多分:

.logo-img path {
  background-color: #000;
}

JSFiddle:http ://jsfiddle.net/erxu0dzz/1/


1
素晴らしい..動作します。さらに、ページに複数のsvgがある場合は、フェッチブロックをIIFEに配置する必要があります。
Sandeep Sharma

1
すごい!ES6で正常に動作します。あなたはIE 9気にしないのであればあなたも使用することができます: parser.parseFromString(text, "image/svg+xml");
ChristoKiwi

iOS 9.3.5のUIWebViewでは機能しません。私は考えてそれがの使用に起因するかもしれないfetch10.1(中のSafariに追加されたdeveloper.mozilla.org/en-US/docs/Web/API/Fetch_API)。上記のjQueryバージョンは機能します。
マリアイネスカレラ

7

フィルターを使用して任意の色に変換します。

私は最近この解決策を見つけました。誰かがそれを使用できるようになることを願っています。ソリューションはフィルターを使用するため、あらゆるタイプの画像で使用できます。SVGだけではありません。

色を変更したい単色画像がある場合は、いくつかのフィルターを使用してこれを行うことができます。もちろんマルチカラー画像でも機能しますが、特定の色をターゲットにすることはできません。画像全体のみ。

フィルターは、CSSフィルターのみを使用して黒を特定の色に変換する方法で提案されたスクリプトからのもの です。白を任意の色に変更する場合は、各フィルターの反転値を調整できます。

.startAsBlack{
  display: inline-block;
  width: 50px;
  height: 50px;
  background: black;
}

.black-green{
  filter: invert(43%) sepia(96%) saturate(1237%) hue-rotate(88deg) brightness(128%) contrast(119%);
}

.black-red{
  filter: invert(37%) sepia(93%) saturate(7471%) hue-rotate(356deg) brightness(91%) contrast(135%);
}

.black-blue{
  filter: invert(12%) sepia(83%) saturate(5841%) hue-rotate(244deg) brightness(87%) contrast(153%);
}

.black-purple{
  filter: invert(18%) sepia(98%) saturate(2657%) hue-rotate(289deg) brightness(121%) contrast(140%);
}
Black to any color: <br/>
<div class="startAsBlack black-green"></div>
<div class="startAsBlack black-red"></div>
<div class="startAsBlack black-blue"></div>
<div class="startAsBlack black-purple"></div>


4

@gringoの回答を拡張するには、他の回答で説明されているJavaScriptメソッドが機能しますが、ユーザーが不要な画像ファイルをダウンロードする必要があり、IMOはコードを膨らませます。

1色のすべてのベクターグラフィックスをwebfontファイルに移行することをお勧めします。私はフォートオーサムを使いました過去にしたことがあります。SVG形式のカスタムアイコン/画像と、使用しているサードパーティのアイコン(Font Awesome、Bootstrapアイコンなど)を1つのWebフォントファイルに組み合わせると効果的です。ユーザーがダウンロードする必要があります。また、カスタマイズして、使用しているサードパーティのアイコンのみを含めることもできます。これにより、ページが行う要求の数が減り、特にサードパーティのアイコンライブラリを既に組み込んでいる場合は、ページ全体の重みになります。

より開発指向のオプションを希望する場合は、Googleの「npm svg webfont」を使用できます。を使用して、環境に最も適したノードモジュールの1つを使用できます。

これらの2つのオプションのいずれかを実行すると、CSSを介して色を簡単に変更できます。おそらく、その過程でサイトを高速化しました。


SVGスプライトを試してみてください。私の経験では、Webフォントにはブラウザーのリリース間でランダムな問題があります。これを試してください:fontastic.me-しかし、SVGスプライトバージョンを使用してください-そして、あなたの考えを見てください。:)
シェリフデレク2018

4

画像を実際の色と白黒の間で単に切り替える場合は、1つのセレクターを次のように設定できます。

{filter:none;}

そして別のものとして:

{filter:grayscale(100%);}

3

シンプルな

次のコードを使用できます。

<svg class="logo">
  <use xlink:href="../../static/icons/logo.svg#Capa_1"></use>
</svg>

最初にsvgのパスを指定してから、そのIDを書き込みます。この場合は「Capa_1」です。svgのIDは、任意のエディターで開くことで取得できます。

CSS:

.logo {
  fill: red;
}

kabrice、このコードを使用できます codepen.io/hmzajmal/pen/ZEGvWYa
Hamza Jamal

2

あなたの場合の主な問題は<img>、SVG構造を隠すタグからsvgをインポートしていることです。

希望の効果を得るには、<svg>とともにタグを使用する必要があり<use>ます。これを機能させるにidは、SVGファイルで使用するパスにを指定<path id='myName'...>して、<use xlink:href="#myName"/>タグからそれらを取得できるようにする必要があります。以下の抜粋を試してください。

#SVGを外部ソースからロードする(HTMLに埋め込まない)場合は、フラグメントの前に任意のURLを置くことができます。また、通常、CSSへの塗りつぶしは指定しません。fill:"currentColor"SVG内での使用を検討することをお勧めします。対応する要素のCSSカラー値がそのまま使用されます。


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でこの結果を得ました。

Mozilla Firefox 59.0.2(64ビット)Linux

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

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

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

Opera 53.0.2907.37 Linux

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


私は反対投票することはできませんが、決してこれをしないでください。
サンダー

5
理由は?代替案?
ベンジャミン

これを行わない理由は、これが原因でブラウザーがSVGをキャッシュできないためです。別の方法は、ここで他のいくつかの回答で言及されているSVGインジェクターを使用することです。SVGファイルは引き続きブラウザによってキャッシュされ、挿入されたSVGはCSSでスタイル設定できます。しかし、私はあなたに反対票を投じません。
息子TRAN-グエン

私は理解していますが、とにかく、キャッシュについては触れられていません。ベストアンサーには、ヘッダーの有効期限の操作によって毎回リロード(またはリロードできない)できるJavaScriptコードがあるか、ファイル名のリンクの後にハッシュを強制することができます。
ベンジャミン

2

これは、CSSで操作したい画像とPHP組み合わせて使用する場合に役立ちます.svg

CSSでimgタグ内のプロパティを上書きすることはできません。しかし、svgソースコードがHTMLに埋め込まれている場合は、確実にできます。ファイルrequire_onceをインクルードする機能でこの問題を解決したいと思い.svg.phpます。画像のインポートに似ていますが、CSSでスタイルを上書きできます。

最初にsvgファイルを含めます:

<?php require_once( '/assets/images/my-icon.svg.php' ); ?>

そしてそれは例えばこのアイコンが含まれています:

<svg xmlns="http://www.w3.org/2000/svg" width="20.666" height="59.084" viewBox="0 0 20.666 59.084"><g transform="translate(-639.749 -3139)"><path d="M648.536,3173.876c0-2.875-1.725-3.8-3.471-3.8-1.683,0-3.49.9-3.49,3.8,0,3,1.786,3.8,3.49,3.8C646.811,3177.676,648.536,3176.769,648.536,3173.876Zm-3.471,2.341c-.883,0-1.437-.513-1.437-2.341,0-1.971.615-2.381,1.437-2.381.862,0,1.438.349,1.438,2.381,0,1.907-.616,2.339-1.438,2.339Z" fill="#142312"/><path d="M653.471,3170.076a1.565,1.565,0,0,0-1.416.9l-6.558,13.888h1.2a1.565,1.565,0,0,0,1.416-.9l6.559-13.887Z" fill="#142312"/><path d="M655.107,3177.263c-1.684,0-3.471.9-3.471,3.8,0,3,1.766,3.8,3.471,3.8,1.745,0,3.49-.9,3.49-3.8C658.6,3178.186,656.851,3177.263,655.107,3177.263Zm0,6.139c-.884,0-1.438-.514-1.438-2.34,0-1.972.617-2.381,1.438-2.381.862,0,1.437.349,1.437,2.381,0,1.909-.616,2.34-1.437,2.34Z" fill="#142312"/><path d="M656.263,3159.023l-1.49-14.063a1.35,1.35,0,0,0,.329-.293,1.319,1.319,0,0,0,.268-1.123l-.753-3.49a1.328,1.328,0,0,0-1.306-1.054h-6.448a1.336,1.336,0,0,0-1.311,1.068l-.71,3.493a1.344,1.344,0,0,0,.276,1.112,1.532,1.532,0,0,0,.283.262l-1.489,14.087c-1.7,1.727-4.153,4.871-4.153,8.638v28.924a1.339,1.339,0,0,0,1.168,1.49,1.357,1.357,0,0,0,.17.01h17.981a1.366,1.366,0,0,0,1.337-1.366v-29.059C660.414,3163.893,657.963,3160.749,656.263,3159.023Zm-8.307-17.349h4.274l.176.815H647.79Zm9.785,43.634v10.1H642.434v-17.253a4.728,4.728,0,0,1-2.028-4.284,4.661,4.661,0,0,1,2.028-4.215v-2c0-3.162,2.581-5.986,3.687-7.059a1.356,1.356,0,0,0,.4-.819l1.542-14.614H652.1l1.545,14.618a1.362,1.362,0,0,0,.4.819c1.109,1.072,3.688,3.9,3.688,7.059v9.153a5.457,5.457,0,0,1,0,8.5Z" fill="#142312"/></g></svg>

これで、CSSを使用して次のように塗りつぶしの色を簡単に変更できます。

svg path {
  fill: blue;
}

私は最初にこの問題を解決しようとしましたfile_get_contents()が、上記の解決策ははるかに高速です。


0

これは古い質問ですが、最近同じ問題に遭遇し、サーバー側から解決しました。これはphp固有の回答ですが、他の環境にも同様のものが存在することを確信しています。imgタグを使用する代わりに、get-goからsvgをsvgとしてレンダリングします。

public static function print_svg($file){
    $iconfile = new \DOMDocument();
    $iconfile->load($file);
    $tag = $iconfile->saveHTML($iconfile->getElementsByTagName('svg')[0]);
    return $tag;
}

ファイルをレンダリングすると、完全なインラインsvgが表示されます


0

コードエディターでsvgアイコンを開き、パスタグの後にクラスを追加します。

<path class'colorToChange' ...

クラスをsvgに追加して、次のように色を変更できます。

コードペン


-2

JQueryにアクセスできる場合は、Praveenの回答に拡張して、プログラムによってSVG内のネストされたさまざまな要素の色を次のように変更できます。

$('svg').find('path, text').css('fill', '#ffffff');

find内で、色を変更する必要があるさまざまな要素について言及できます。

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