CSS中的内联SVG

CSS中的内联SVG,css,svg,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

是否可以在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>");
      }
body{背景图像:
url(“数据:image/svg+xml;utf8,”);
}
(请注意,需要对SVG内容进行url转义,以使其正常工作,例如,
被替换为
%23


。数据URL在旧版本的IE中也可以工作(有限制),但它们本身并不支持SVG。

有点晚了,但是如果你们中有人疯狂地尝试使用内联SVG作为背景,上面的转义建议不太管用。首先,它在IE中不起作用,并且取决于SVG的内容,该技术将在其他浏览器(如FF)中引起麻烦

如果您对svg(不是整个url,只是svg标记及其内容)进行base64编码,那么它在所有浏览器中都可以工作。下面是base64中相同的JSFIDLE示例:

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;如果它不起作用(它可能会抱怨字符串中的无效字符),您可以简单地使用

设置div背景的示例:

var mySVG=”“;
var mySVG64=window.btoa(mySVG);
document.getElementById('myDiv').style.backgroundImage=“url('data:image/svg+xml;base64,“+mySVG64+”)”
html,body,#myDiv{
宽度:100%;
身高:100%;
保证金:0;
}

在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;"
echo“背景:透明url('data:image/svg+xml;base64,”$(openssl base64
在MacOSX上测试。 这样还可以避免URL转义混乱


请记住,对SVG文件进行base64编码会增加其大小,请参阅。

来自第三方源(如谷歌图表)的内联SVG可能不包含XML名称空间属性(
xmlns=)http://www.w3.org/2000/svg“
)在SVG元素中(或者,在呈现SVG后,它可能会被删除——浏览器检查器和浏览器控制台中的jQuery命令都不会在SVG元素中显示名称空间)


当您需要将这些svg片段用于其他需要时(CSS中的背景图像或HTML中的img元素),请注意缺少的名称空间。没有名称空间,浏览器可能会拒绝显示svg(无论编码是utf8还是base64).

我制作了一个CodePen演示,它在将内嵌SVG嵌入CSS时遇到了同样的问题。与SCS一起使用的解决方案是构建一个简单的url编码函数

可以从内置的str切片、str索引函数创建字符串替换函数(请参阅,感谢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;
}
@函数svg内联($string){

$result:str replace($string,“对于仍在苦苦挣扎的人们,我设法在所有现代浏览器IE11及更高版本上实现了这一点

base64对我来说不是一个选项,因为我想使用SASS根据任何给定的颜色生成SVG图标。例如:
@include SVG_icon(heart,#FF0000);
这样我就可以创建任何颜色的特定图标,只需在CSS中嵌入SVG形状一次。(对于base64,您必须将SVG嵌入到您想要使用的每种颜色中)

您需要注意三件事:

  • URL编码您的SVG 正如其他人所建议的,您需要对整个SVG字符串进行URL编码,以使其在IE11中工作。在我的例子中,我省略了字段中的颜色值,例如
    fill=“#00FF00”
    stroke=“#FF0000”
    ,并用SASS变量
    fill=“#{$color rgb}”
    因此这些可以替换为我想要的颜色。您可以使用URL对字符串的其余部分进行编码。您将得到如下SVG字符串:

    %7.2%2%2%7%7%7%7%7%7%7%2%2%2%2%2%2%2%2%2%7%2%3%3%7%7%3%3%7%3%7%7%7%7%7%7%7%7%7%3%3%3%3%3%3%3%3%3%3%3%2%2%2%2%2%7%2%7%7%7%7%2%7%7%7%7%7%7%7%7%7%7%7%7%7%7%7%7%7%7%2 vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv7%7%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中使用

    背景图像:url(数据:图像/svg+xml;utf-8,%3Csvg%2…)
    但是背景图像:url(数据:image/svg+xml,%3Csvg%2….)


  • 使用RGB()而不是十六进制颜色Firefox不喜欢SVG代码中的#。因此,您需要将颜色十六进制值替换为RGB值

    fill=“#FF0000”
    但是fill=“rgb(255,0,0)”

  • 在我的例子中,我使用SASS将给定的十六进制转换为有效的rgb值。正如在注释中指出的,最好对rgb字符串进行URL编码(因此逗号变成%2C)


    我意识到这可能不是非常复杂的SVG的最佳解决方案(内联SVG永远不会是这种情况),但对于只有两种颜色的平面图标,这确实非常有效

    我可以省去一个完整的sprite位图,用CSS中的内联SVG替换它,结果压缩后只有25kb左右
    @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');
       }
    }