web-dev-qa-db-ja.com

外部CSSでSVGをスタイルする方法は?

各SVGファイル内ではなく、外部スタイルシートを介して色を変更したいSVGグラフィックがいくつかあります。グラフィックをインラインに配置するのではなく、画像フォルダーに保存してそれらを指すようにします。

ツールチップを機能させるためにこの方法で実装し、リンクを許可するためにそれぞれを<a>タグでラップしました。

<a href='http://youtube.com/...' target='_blank'><img class='socIcon' src='images/socYouTube.svg' title='View my videos on YouTube' alt='YouTube' /></a>

そして、SVGグラフィックのコードは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path d="M28.44......./>
</g>
</svg>

私は外部CSSファイル(main.css)に以下を入れました:

.socIcon g {fill:red;}

それでも、グラフィックには影響しません。 .socIcon g path {}と.socIcon path {}も試しました。

何かが正しくない、おそらく私の実装では外部CSSの変更が許可されていないのか、それともステップを逃したのか?あなたの助けに本当に感謝します!外部スタイルシートを介してSVGグラフィックの色を変更する機能が必要なだけですが、ツールチップとリンク機能を失うことはできません。 (ただし、ツールチップなしで生きることができるかもしれません。)ありがとう!

79
Jordan H

SVGファイルがHTMLにインラインで含まれている場合、main.cssファイルはSVGのコンテンツにのみ影響します。

https://developer.mozilla.org/en/docs/SVG_In_HTML_Introduction

<html>
  <body>
  <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
      <path d="M28.44......./>
    </g>
  </svg>
</html>

SVGをファイルに保存する場合は、SVGファイル内でCSSを定義する必要があります。

スタイルタグでそれを行うことができます:

http://www.w3.org/TR/SVG/styling.html#StyleElementExample

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
     width="50px" height="50px" viewBox="0 0 50 50">
  <defs>
    <style type="text/css"><![CDATA[
      .socIcon g {
        fill:red;
      }
    ]]></style>
  </defs>
  <g>
    <path d="M28.44......./>
  </g>
</svg>

サーバーサイドのツールを使用して、アクティブなスタイルに応じてスタイルタグを更新できます。 Rubyでは、Nokogiriでこれを実現できます。 SVGは単なるXMLです。そのため、おそらくこれを達成できるXMLライブラリが多数あります。

それができない場合は、PNGであるかのように使用する必要があります。各スタイルのセットを作成し、スタイルをインラインで保存します。

76
RGB

必要なことを1つ(重要な)警告で行うことができます:シンボル内のパスは、外部CSSを介して独立してスタイルを設定することはできません-このメソッドでは、シンボル全体のプロパティのみを設定できます。したがって、シンボルに2つのパスがあり、それらに異なる塗りつぶしの色を持たせたい場合、これは機能しませんが、すべてのパスを同じにしたい場合、これは機能するはずです。

Htmlファイルには、次のようなものが必要です。

<style>
  .fill-red { fill: red; }
  .fill-blue { fill: blue; }
</style>

<a href="//www.example.com/">
  <svg class="fill-red">
    <use xlink:href="images/icons.svg#example"></use>
  </svg>
</a>

外部SVGファイルでは、次のようなものが必要です。

<svg xmlns="http://www.w3.org/2000/svg">
   <symbol id="example" viewBox="0 0 256 256">
    <path d="M120.... />
  </symbol>
</svg>

svgタグ(html内)のクラスをfill-redからfill-blueおよびta-daに交換します...赤ではなく青になります。

インラインCSSが優先されるため、特定のパス上のいくつかのインラインCSSと外部CSSを組み合わせて一致させることにより、外部CSSで個別にパスをターゲットにできるという制限を部分的に回避できます。このアプローチは、色付きの背景に対して白いアイコンのようなことをしている場合に機能します。外部CSSを介して背景の色を変更したいが、アイコン自体は常に白です(またはその逆)。したがって、以前と同じHTMLとこのsvgコードのようなものを使用すると、赤い背景と白い前景パスが得られます。

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="example" viewBox="0 0 256 256">
    <path class="background" d="M120..." />
    <path class="icon" style="fill: white;" d="M20..." />
  </symbol>
</svg>
39
Adam Korman

1つのアプローチとして、CSSフィルターを使用してブラウザーのSVGグラフィックスの外観を変更する方法があります。

たとえば、SVGコード内で赤の塗りつぶし色を使用するSVGグラフィックがある場合、180度の色相回転設定で紫色に変えることができます。

#theIdOfTheImgTagWithTheSVGInIt {
    filter: hue-rotate(180deg);
    -webkit-filter: hue-rotate(180deg);
    -moz-filter: hue-rotate(180deg);
    -o-filter: hue-rotate(180deg);
    -ms-filter: hue-rotate(180deg);
}

他の色相回転設定を試して、必要な色を見つけてください。

明確にするために、上記のCSSは、HTMLドキュメントに適用されるCSSに入ります。 SVGのコードをスタイル設定するのではなく、HTMLコードのimgタグをスタイル設定します。

また、これは黒または白または灰色で塗りつぶされたグラフィックスでは機能しないことに注意してください。その色の色相を回転させるには、そこに実際の色が必要です。

6
Simon White

JavaScriptでスタイル要素を動的に作成し、SVG要素に追加することにより、SVGのスタイルを設定できます。ハッキーですが、動作します。

<object id="dynamic-svg" type="image/svg+xml" data="your-svg.svg">
    Your browser does not support SVG
</object>
<script>
    var svgHolder = document.querySelector('object#dynamic-svg');
    svgHolder.onload = function () {
        var svgDocument = svgHolder.contentDocument;
        var style = svgDocument.createElementNS("http://www.w3.org/2000/svg", "style");

        // Now (ab)use the @import directive to load make the browser load our css
        style.textContent = '@import url("/css/your-dynamic-css.css");';

        var svgElem = svgDocument.querySelector('svg');
        svgElem.insertBefore(style, svgElem.firstChild);
    };
</script>

必要に応じて、PHPでJavaScriptを動的に生成できます-これがJavaScriptで可能であるという事実は、無数の可能性を開きます。

6
Pete

最初に外部svg画像をインライン化することで可能になるはずです。例としてここを見てください:

すべてのSvg画像をインラインSvgに置き換える| JAVASCRIPT | Jess Frazelleによるコードスニペットライブラリ

3
Leo

"ユーザーが自分のサイトに選択した配色に基づいて、これらの画像の色を実際に変更します。"- Jordan10時間前

これにはPHPを使用することをお勧めします。アイコンフォントなしでこれを行うより良い方法は本当にありません、そして、それらを使用することに抵抗があれば、これを試すことができます:

<?php

    header('Content-Type: image/svg+xml');
    echo '<?xml version="1.0" encoding="utf-8"?>';
    $color = $_GET['color'];

?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path fill="<?php echo $color; ?>" d="M28.44..."/>
    </g>
</svg>

そして、後でこのファイルをfilename.php?color=#ffffffとして使用して、svgファイルを目的の色で取得できます。

2
SeinopSys

<image>タグで使用する場合、プライバシー上の理由から、SVGを単一のファイルに含める必要があります。この bugzilla bug には、これがなぜそうなのかについての詳細があります。残念ながら、<iframe>などの別のタグを使用することはできません。これはリンクとして機能しないため、ファイル内の<style>タグにCSSを埋め込む必要があるためです。

これを行うもう1つの方法は、メインのhtmlファイルにSVGデータを含めることです。

<a href='http://youtube.com/...' target='_blank'>
  <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
    <g>
        <path d="M28.44......./>
    </g>
  </svg>
</a>

HTML <link>タグを使用して、外部CSSファイルでスタイルを設定できます。

2
Robert Longson

<object>タグを使用してsvgを埋め込む場合に、外部cssスタイルシートで動的スタイルを使用する非常に迅速なソリューション。

この例では、親要素をクリックしたときにルート<svg>タグにクラスを追加します。

file.svg:

<?xml-stylesheet type="text/css" href="../svg.css"?>
 <svg xmlns="http://www.w3.org/2000/svg" viewBox="">
  <g>
   <path/>
  </g>
 </svg>

html:

<a class="parent">
  <object data="file.svg"></object>
</a>

Jquery:

$(function() {
  $(document).on('click', '.parent', function(){
    $(this).find('object').contents().find('svg').attr("class","selected");
  }
});

親要素をクリックすると:

 <svg xmlns="http://www.w3.org/2000/svg" viewBox="" class="selected">

その後、CSSを管理できます

svg.css:

path {
 fill:none;
 stroke:#000;
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}

.selected path {
 fill:none;
 stroke:rgb(64, 136, 209);
 stroke-miterlimit:1.41;
 stroke-width:0.7px;
}
2
vhanahrni

私は古い投稿を知っていますが、この問題を解決するために...間違った場所でクラスを使用しています:D

まず最初に使用できます

svg { fill: red; }

main.cssで赤くします。これには効果があります。適切にノードセレクターを使用して、特定のパスを取得することもできます。

次に、クラスをimg- Tagに宣言しました。

<img class='socIcon'....

実際には、SVG内で宣言する必要があります。異なるパスがある場合は、もちろんさらに定義できます。

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="stylesheets/main.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">
<g>
    <path class="myClassForMyPath" d="M28.44......./>
</g>
</svg>

main.cssの色を変更できるようになりました

.myClassForMyPath {
    fill: yellow;
}
1
Dwza

私のために働くもの:@importルールを持つスタイルタグ

<defs>
    <style type="text/css">
        @import url("svg-common.css");
    </style>
</defs>
0
Fordi
  1. 外部スタイルの場合
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
        @import url(main.css);
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>
  1. 内部スタイル用
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 56.69 56.69">

  <style>
            .socIcon g {fill:red;}
  </style>

  <g>
    <path d="M28.44......./>
  </g>
</svg>

注:<img>タグ内にSVGを含めると、外部スタイルは機能しません。 <div>タグ内で完全に機能します

0
Yuvraj Patil

@leoはangularJSバージョンです、ありがとう

G.directive ( 'imgInlineSvg', function () {

return {
    restrict : 'C',
    scope : true,
    link : function ( scope, elem, attrs ) {

        if ( attrs.src ) {

            $ ( attrs ).each ( function () {
                var imgID    = attrs.class;
                var imgClass = attrs.class;
                var imgURL   = attrs.src;

                $.get ( imgURL, function ( data ) {

                    var $svg = $ ( data ).find ( 'svg' );
                    if ( typeof imgID !== 'undefined' ) {
                        $svg = $svg.attr ( 'id', imgID );
                    }

                    if ( typeof imgClass !== 'undefined' ) {
                        $svg = $svg.attr ( 'class', imgClass + ' replaced-svg' );
                    }

                    $svg = $svg.removeAttr ( 'xmlns:a' );

                    elem.replaceWith ( $svg );

                } );

            } );
        }

    }

}

} );