CSSでインラインSVG定義を使用することは可能ですか?
私は次のようなものを意味します:
.my-class {
background-image: <svg>...</svg>;
}
<img>
SVGは、いくつかの画像が混在している場合(埋め込まれた場合を除き)を参照してください、タグ、その他の場合に動作していない外部の画像を使用したマスクと背景画像SVGを、具体的には、SVGに制限がとして使用画像。
CSSでインラインSVG定義を使用することは可能ですか?
私は次のようなものを意味します:
.my-class {
background-image: <svg>...</svg>;
}
<img>
SVGは、いくつかの画像が混在している場合(埋め込まれた場合を除き)を参照してください、タグ、その他の場合に動作していない外部の画像を使用したマスクと背景画像SVGを、具体的には、SVGに制限がとして使用画像。
回答:
はい、可能です。これを試して:
body { background-image:
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='%23F00'/><stop offset='90%' stop-color='%23fcc'/> </linearGradient><rect fill='url(%23gradient)' x='0' y='0' width='100%' height='100%'/></svg>");
}
(これを機能させるには、SVGコンテンツをURLエスケープする必要があることに注意してください。たとえば、#
に置き換えられ%23
ます。)
これはIE 9(SVGをサポート)で動作します。データURLは古いバージョンのIEでも(制限付きで)機能しますが、SVGをネイティブでサポートしていません。
url()
必要があります。Opera、Firefox、Safariで正常に機能する例については、jsfiddle.net / 6WAtQを参照してください。
少し遅れますが、インラインSVGをバックグラウンドとして使用しようとして頭がおかしくなっている場合、上記のエスケープの提案はうまく機能しません。1つは、IEでは機能せず、SVGのコンテンツによっては、このテクニックがFFなどの他のブラウザーで問題を引き起こす場合があるためです。
svgをbase64エンコードする場合(URL全体ではなく、svgタグとそのコンテンツのみ!)、すべてのブラウザーで機能します。ここではBASE64で同じjsfiddle例は次のとおりです。http://jsfiddle.net/vPA9z/3/
CSSは次のようになります。
body { background-image:
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+PGxpbmVhckdyYWRpZW50IGlkPSdncmFkaWVudCc+PHN0b3Agb2Zmc2V0PScxMCUnIHN0b3AtY29sb3I9JyNGMDAnLz48c3RvcCBvZmZzZXQ9JzkwJScgc3RvcC1jb2xvcj0nI2ZjYycvPiA8L2xpbmVhckdyYWRpZW50PjxyZWN0IGZpbGw9J3VybCgjZ3JhZGllbnQpJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJy8+PC9zdmc+");
base64に変換する前に、URLエスケープをすべて削除してください。つまり、上の例ではcolor = '#fcc'がcolor = '%23fcc'に変換されていることを示しているため、#に戻る必要があります。
base64がより適切に機能する理由は、一重引用符と二重引用符、およびURLエスケープに関するすべての問題が排除されるためです
JSを使用window.btoa()
している場合は、を使用してbase64 svgを作成できます。そして、それが機能しない場合(文字列内の無効な文字について文句を言うかもしれません)、単にhttps://www.base64encode.org/を使用できます。
div背景を設定する例:
var mySVG = "<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><linearGradient id='gradient'><stop offset='10%' stop-color='#F00'/><stop offset='90%' stop-color='#fcc'/> </linearGradient><rect fill='url(#gradient)' x='0' y='0' width='100%' height='100%'/></svg>";
var mySVG64 = window.btoa(mySVG);
document.getElementById('myDiv').style.backgroundImage = "url('data:image/svg+xml;base64," + mySVG64 + "')";
html, body, #myDiv {
width: 100%;
height: 100%;
margin: 0;
}
<div id="myDiv"></div>
JSを使用すると、パラメーターを変更する場合でも、SVGをその場で生成できます。
SVGの使用に関する優れた記事の1つはこちらです:http : //dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/
お役に立てれば
マイク
xmlns
属性をsvg
element に設定していることを確認してください<svg xmlns="http://www.w3.org/2000/svg">...</svg>
まだ苦労している人のために、私はこれをすべての最新のブラウザーIE11以降で動作させることができました。
SASSを使用して、指定された色に基づいてSVGアイコンを生成したかったため、base64は私にとってオプションではありませんでした。例:@include svg_icon(heart, #FF0000);
このようにして、特定のアイコンを任意の色で作成でき、CSSにSVG形状を1回埋め込むだけで済みます。(base64では、使用するすべての単色でSVGを埋め込む必要があります)
次の3つの点に注意してください。
SVG
をURLエンコードする他の人が示唆しているように、IE11で動作させるには、SVG文字列全体をURLエンコードする必要があります。私の場合、私は以下のような分野でのカラー値を除外fill="#00FF00"
し、stroke="#FF0000"
かつSASS変数とそれらを交換しfill="#{$color-rgb}"
、これらは私が欲しい色で置き換えることができるようにします。任意のオンラインコンバーターを使用して、残りの文字列をURLエンコードできます。次のようなSVG文字列になります。
%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20494.572%20494.572%27%20width%3D%27512%27%20height%3D %27512%27%3E%0A%20%20%3Cpath%20d%3D%27M257.063%200C127.136%200%2021.808%20105.33%2021.808%20235.266c0%2041.012%2010.535%2079.541%2028.973%20113.104L3.825 %20464.586c345%2012.797%2041.813%2012.797%2015.467%200%2029.872-4.721%2041.813-12.797v158.184z%27%20fill%3D%27#{$ color-rgb}%27%2F%3E%3C%2Fsvg% 3E
データURLのUTF8文字セットを省略するデータURLを作成するとき、IE11で機能させるには文字セットを省略する必要があります。
NOT background-image:url(data:image / svg + xml; utf-8、%3Csvg%2 ....)
BUT background-image:url(data:image / svg + xml、%3Csvg%2 ... 。)
RGB()INSTEAD OF HEXの色を使用する FirefoxはSVGコードの#を好みません。したがって、16進数のカラー値をRGB値に置き換える必要があります。
NOT埋める= "#FF0000"
BUT塗りつぶし= "RGB(255,0,0)"
私の場合、SASSを使用して、特定の16進数を有効なRGB値に変換します。コメントで指摘されているように、RGB文字列もURLエンコードするのが最善です(そのため、カンマは%2Cになります)。
@mixin svg_icon($id, $color) {
$color-rgb: "rgb(" + red($color) + "%2C" + green($color) + "%2C" + blue($color) + ")";
@if $id == heart {
background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20494.572%20494.572%27%20width%3D%27512%27%20height%3D%27512%27%3E%0A%20%20%3Cpath%20d%3D%27M257.063%200C127.136%200%2021.808%20105.33%2021.808%20235.266c0%204%27%20fill%3D%27#{$color-rgb}%27%2F%3E%3C%2Fsvg%3E');
}
}
これは非常に複雑なSVG(その場合はインラインSVGはあり得ない)には最適な解決策ではないかもしれないことを理解していますが、2、3色しかないフラットアイコンの場合、これは本当にうまく機能します。
スプライトのビットマップ全体を省略して、CSSでインラインSVGに置き換えることができました。これは、圧縮後は約25 kbであることがわかりました。したがって、CSSファイルを肥大化させることなく、サイトが実行する必要のあるリクエストの量を制限する優れた方法です。
rgb(255,0,0)
必要がありrgb(255%2C0%2C0)
ます。
%23ff0000
て問題なく#ff0000
動作しました
Mac / Linuxでは、次の単純なbashコマンドを使用して、SVGファイルをCSS背景属性のbase64エンコード値に簡単に変換できます。
echo "background: transparent url('data:image/svg+xml;base64,"$(openssl base64 < path/to/file.svg)"') no-repeat center center;"
Mac OS Xでテストされています。これにより、URLの混乱を回避することもできます。
SVGファイルをbase64エンコードするとサイズが増加することに注意してください。css-tricks.comブログ投稿を参照してください。
インラインSVGをCSSに埋め込むことと同じ問題があるCodePenデモをフォークしました。SCSSで機能するソリューションは、単純なurl-encoding関数を作成することです。
文字列置換関数は、組み込みのstr-slice、str-index関数から作成できます(Hugo Giraudelによるcss-tricksを参照)。
すると、ちょうど置き換え%
、<
、>
、"
、'
、との
%xx
コード:
@function svg-inline($string){
$result: str-replace($string, "<svg", "<svg xmlns='http://www.w3.org/2000/svg'");
$result: str-replace($result, '%', '%25');
$result: str-replace($result, '"', '%22');
$result: str-replace($result, "'", '%27');
$result: str-replace($result, ' ', '%20');
$result: str-replace($result, '<', '%3C');
$result: str-replace($result, '>', '%3E');
@return "data:image/svg+xml;utf8," + $result;
}
$mySVG: svg-inline("<svg>...</svg>");
html {
height: 100vh;
background: url($mySVG) 50% no-repeat;
}
image-inline
Compassにはヘルパー関数も用意されていますが、CodePenではサポートされていないため、このソリューションはおそらく役立つでしょう。
CodePenのデモ:http ://codepen.io/terabaud/details/PZdaJo/
<svg><path></svg>
、トップのテキストエリアに、それが直接の出力は、パスを消毒しますurl()
値内。
サードパーティソース(Googleチャートなど)からのインラインSVGにはxmlns="http://www.w3.org/2000/svg"
、SVG要素にXML名前空間属性()が含まれていない可能性があります(またはSVGがレンダリングされると削除される可能性があります。ブラウザインスペクタもブラウザコンソールのjQueryコマンドもSVG要素に名前空間を表示しません)。
これらのsvgスニペットを他のニーズ(CSSの背景画像またはHTMLのimg要素)に再利用する必要がある場合は、欠落している名前空間に注意してください。名前空間がないと、ブラウザーは(エンコーディングutf8またはbase64に関係なく)SVGの表示を拒否する可能性があります。
SVGのソリューションが1つ見つかりました。しかし、それはWebkitでのみ機能します。回避策をあなたと共有したいだけです。私の例では、フィルターを介してDOMからのSVG要素を背景として使用する方法を示しています(background-image:url( '#glyph')が機能していません)。
このSVGアイコンのレンダリングに必要な機能:
.test {
/* background-image: url('#glyph');
background-size:100% 100%;*/
filter: url(#image);
height:100px;
width:100px;
}
.test:before {
display:block;
content:'';
color:transparent;
}
.test2{
width:100px;
height:100px;
}
.test2:before {
display:block;
content:'';
color:transparent;
filter: url(#image);
height:100px;
width:100px;
}
<svg style="height:0;width:0;" version="1.1" viewbox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="glyph">
<path id="heart" d="M100 34.976c0 8.434-3.635 16.019-9.423 21.274h0.048l-31.25 31.25c-3.125 3.125-6.25 6.25-9.375 6.25s-6.25-3.125-9.375-6.25l-31.202-31.25c-5.788-5.255-9.423-12.84-9.423-21.274 0-15.865 12.861-28.726 28.726-28.726 8.434 0 16.019 3.635 21.274 9.423 5.255-5.788 12.84-9.423 21.274-9.423 15.865 0 28.726 12.861 28.726 28.726z" fill="crimson"/>
</g>
<svg id="resized-glyph" x="0%" y="0%" width="24" height="24" viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="#glyph"></use>
</svg>
<filter id="image">
<feImage xlink:href="#resized-glyph" x="0%" y="0%" width="100%" height="100%" result="res"/>
<feComposite operator="over" in="res" in2="SourceGraphic"/>
</filter>
</defs>
</svg>
<div class="test">
</div>
<div class="test2">
</div>
もう1つの解決策は、URLエンコードを使用することです
var container = document.querySelector(".container");
var svg = document.querySelector("svg");
var svgText = (new XMLSerializer()).serializeToString(svg);
container.style.backgroundImage = `url(data:image/svg+xml;utf8,${encodeURIComponent(svgText)})`;
.container{
height:50px;
width:250px;
display:block;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
<svg height="100" width="500" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
</svg>
<div class="container"></div>