在CSS中内联SVG
有没有可能在CSS中使用内联SVG定义?
我的意思是这样的:
.my-class { background-image: <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转义才能正常工作,例如#
被replace为%23
。
这适用于IE 9(支持SVG) 。 数据URL也可以在IE的旧版本中使用(有限制),但是它们本身不支持SVG。
有点晚了,但是如果你们中的任何一个人都试图用内联的SVG作为背景 ,那么上面的转义build议就不起作用了。 首先,它在IE中不起作用,根据你的SVG的内容,这个技术会在其他浏览器(如FF)中造成麻烦。
如果你base64编码svg(不是整个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; 如果它不起作用(它可能会抱怨string中的字符无效),您可以简单地使用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>
对于那些还在挣扎的人来说,我设法在IE11以上的所有现代浏览器上运行。
因为我想使用SASS来生成基于任何给定颜色的SVG图标,所以base64不适合我。 例如: @include svg_icon(heart, #FF0000);
这样我就可以创build任何颜色的图标,只需要在CSS中embedded一次SVGgraphics。 (使用base64,你必须将SVGembedded到你想要使用的每种颜色中)
有三件事情需要注意:
-
URL编码你的SVG正如其他人所build议的,你需要对整个SVGstring进行URL编码,使其在IE11中工作。 在我的情况下,我省略了
fill="#00FF00"
和stroke="#FF0000"
等字段中的颜色值,并将其replace为SASSvariablesfill="#{$color-rgb}"
以便replace用我想要的颜色。 您可以使用任何在线转换器对string的其余部分进行URL编码。 你最终会得到一个像这样的SVGstring:%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
-
OMIT数据URL中的UTF8字符集创build数据URL时,您需要省略字符集,以便在IE11中工作。
NOT background-image:url(data:image / svg + xml; utf-8,%3Csvg%2 ….)
但是 background-image:url(data:image / svg + xml,%3Csvg%2 ….)
-
使用RGB()INSTEAD HEX颜色 Firefox不喜欢SVG代码中的#号。 所以你需要用RGB代替你的颜色hex值。
NOT fill =“#FF0000”
但是 fill =“rgb(255,0,0)”
在我的情况下,我使用SASS将给定的hex转换为有效的rgb值。 正如在评论中指出的那样,最好也是对你的RGBstring进行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的解决scheme(内联SVG从来没有在这种情况下),但对于只有一些颜色的平面图标,这真的很好。
我能够忽略整个精灵位图,并用我的CSS中的内联SVGreplace它,结果只能在压缩后大约25kb。 所以这是一个很好的方法来限制你的网站要做的请求数量,而不会膨胀你的CSS文件。
在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上testing。这样你也避免了URL转义的混乱。
请记住,base64编码的SVG文件增加了它的大小,请参阅css-tricks.com博客文章 。
我已经分叉了一个CodePen演示,将embedded式SVGembedded到CSS中也有同样的问题。 与SCSS一起工作的解决scheme是构build一个简单的URL编码function。
一个stringreplace函数可以通过内置的str-slice,str-index函数创build(参见css-tricks ,感谢Hugo Giraudel)。
然后,只要将%
, <
, >
, "
, '
用
%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; }
Compass中还有一个image-inline
帮助函数,但由于CodePen不支持,所以此解决scheme可能会有用。
在CodePen上演示: http ://codepen.io/terabaud/details/PZdaJo/
来自第三方来源(如Google图表)的内联SVG在SVG元素中可能不包含XML名称空间属性( xmlns="http://www.w3.org/2000/svg"
)(或者一旦SVG被渲染,浏览器控制台中的浏览器检查器和jQuery命令都不显示SVG元素中的名称空间)。
当你需要重新使用这些svg代码片段来满足你的其他需求(CSS中的background-image或HTML中的img元素)时,请注意缺less的名称空间。 没有命名空间的浏览器可能会拒绝显示SVG(无论编码utf8或base64)。
我发现了一个SVG的解决scheme。 但是这仅仅是Webkit的工作,我只是想与你分享我的解决方法。 在我的例子中显示了如何通过filter(背景图像:url('#glyph')不工作)使用DOM中的SVG元素作为背景。
这个SVG图标渲染所需的function:
- 将SVG滤镜效果应用于使用CSS的HTML元素(IE和Edge不支持)
- feImage片段负载支持(firefox不支持)
.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>