CSS中的内联SVG

aka*_*Rem 255 css svg

是否可以在CSS中使用内联SVG定义?

我的意思是:

.my-class {
  background-image: <svg>...</svg>;
}
Run Code Online (Sandbox Code Playgroud)

Raa*_*aab 339

对的,这是可能的.试试这个:

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>");
      }
Run Code Online (Sandbox Code Playgroud)

(请注意,SVG内容需要进行url转义才能使其正常工作,例如#替换为%23.)

这适用于IE 9(支持SVG).数据URL也适用于旧版本的IE(有限制),但它们本身不支持SVG.

  • 这里的"浏览器不兼容性"主要是缺少正确的URL转义,`url()`中的所有内容都应该被url转义.有关在Opera,Firefox和Safari中运行良好的示例,请参阅http://jsfiddle.net/6WAtQ/. (16认同)
  • 它似乎运行良好的唯一浏览器是Safari(5.1.4).在Opera 11.62中,渐变是黑色的,在IE 9和Firefox 12中它是白色的.在Chrome 19中,除非您以%为单位指定SVG的宽度/高度,否则它无效.我会说这更像是一个奇怪而非真实的特征.这是一个很酷的发现. (8认同)
  • 是的......当我向他们展示一个像这样可爱的小怪物时,我仍然急于看到我同事脸上的表情,所以再次感谢他们表示这是可能的.我只是按照标准规范说明它实际上是不可能的,结果证明这是一个错误(某种程度上) (4认同)
  • 注意,指定字符集的标准方法是使用"; charset = UTF-8"而不是"; utf8".http://tools.ietf.org/html/rfc2397 (4认同)
  • base64编码的svg与非base64之间是否存在兼容性差异?Base64膨胀了我的css文件,我正在考虑使用内联svgs .. (3认同)
  • 这是一个非常好的工具,可以将svg(源代码)直接在线转换为css属性:https://yoksel.github.io/url-encoder/ (3认同)

Mik*_*asi 221

有点晚了,但是如果你们中的任何人一直在疯狂尝试使用内联SVG作为背景,那么上面提出的逃避建议并不是很有效.首先,它在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+");
Run Code Online (Sandbox Code Playgroud)

请记住在转换为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 + "')";
Run Code Online (Sandbox Code Playgroud)
html, body, #myDiv {
  width: 100%;
  height: 100%;
  margin: 0;
}
Run Code Online (Sandbox Code Playgroud)
<div id="myDiv"></div>
Run Code Online (Sandbox Code Playgroud)

使用JS,您可以动态生成SVG,甚至可以更改其参数.

关于使用SVG的更好文章之一是:http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/

希望这可以帮助

麦克风

  • 回复“您可能不应该使用 base64 SVG”评论。如果您正在对整个 svg 库进行 Base64 编码,请重新考虑您迄今为止的决定,不要对世界进行 Base64 编码。但是,如果您正在制作模块或插件并希望嵌入非常小的 SVG 而不是包含全新文件,请这样做。对于您和使用您的小模块/插件的人来说,包含一个 base64 编码的 SVG 而不是另一个目录依赖项会更容易。 (4认同)
  • 谢啦。使用Base64的解决方案效果很好,而我在接受的答案中遇到了麻烦。 (2认同)
  • 你救了我的命。我有一个 SVG 边框图像,它可以在 chrome 中运行,但不能在 FF 中运行。现在它起作用了!:D (2认同)
  • 如果 6 年多后有人还在看这个答案:你可能不应该使用 base64 SVG https://css-tricks.com/probously-dont-base64-svg/ (2认同)

Dav*_*ert 34

对于仍在苦苦挣扎的人来说,我设法让所有现代浏览器IE11及以上版本都能正常运行.

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

您需要注意三件事:

  1. URL包含您的SVG 正如其他人所建议的那样,您需要对整个SVG字符串进行URL编码,以使其在IE11中工作.在我的情况下,我在诸如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


  1. 在数据URL中使用UTF8 CHARSET在创建数据URL时,您需要省略其在IE11中工作的字符集.

    NOT background-image:url(data:image/svg + xml; utf-8,%3Csvg%2 ....)
    但是 background-image:url(数据:image/svg + xml,%3Csvg%2 ... .)


  1. 使用RGB()INSTEAD OF HEX颜色 Firefox不喜欢SVG代码中的#.因此,您需要将RGB颜色十六进制值替换为RGB值.

    NOT fill ="#FF0000"
    但是填充="rgb(255,0,0)"

在我的例子中,我使用SASS将给定的十六进制转换为有效的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');
   }
}
Run Code Online (Sandbox Code Playgroud)

我意识到这可能不是非常复杂的SVG的最佳解决方案(在这种情况下内联SVG永远不会),但对于只有几种颜色的平面图标,这真的很棒.

我能够省略一个完整的精灵位图,并在我的CSS中用内联SVG替换它,压缩后结果只有25kb左右.因此,这是限制网站必须执行的请求数量的好方法,而不会使CSS文件膨胀.

  • 我的意思是我不对 RGB 字符串进行编码,但它仍然有效。但按照您提到的方式对其进行编码可能会更好。 (2认同)
  • 好吧,实际上,我刚刚测试过,“%23ff0000”在 Firefox 中对于“#ff0000”工作得很好 (2认同)
  • 需要较少编码的方法(包括SCSS代码):https://codepen.io/jakob-e/pen/doMoML (2认同)

ara*_*aks 24

在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;"
Run Code Online (Sandbox Code Playgroud)

在Mac OS X上测试过.这样你也可以避免URL转移混乱.

请记住,编码SVG文件的base64会增加其大小,请参阅css-tricks.com博客文章.

  • 致读者:请评论您的意见,而不只是投下反对票,以便您的合作可以改善此答案!在这样的问答站点中,协作至关重要。谢谢! (2认同)
  • @LorDex你在评论中提供的链接与我的答案相同:) (2认同)

Ann*_*nko 20

我的解决方案是https://yoksel.github.io/url-encoder/ 你只需简单地插入你的 svg 并取回背景图像代码

  • 这有效。快速,超级简单,而且非常干净。 (2认同)

Lea*_*ema 10

我已经分叉了一个CodePen演示,它将嵌入式SVG嵌入到CSS中会遇到同样的问题.与SCSS一起使用的解决方案是构建一个简单的url编码函数.

可以从内置的str-slice,str-index函数创建字符串替换函数(感谢Hugo Giraudel,请参阅css-tricks).

然后,只需更换%,<,>,",', with the %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;
}
Run Code Online (Sandbox Code Playgroud)

image-inlineCompass中还有一个辅助函数,但由于CodePen不支持它,因此该解决方案可能很有用.

CodePen上的演示:http://codepen.io/terabaud/details/PZdaJo/


mp3*_*415 6

来自第 3 方来源(例如 Google 图表)的内联 SVG 可能不包含 XML 命名空间属性 (xmlns="http://www.w3.org/2000/svg"SVG 元素中的 XML 命名空间属性 ( )(或者可能在 SVG 渲染后将其删除 - 浏览器检查器和浏览器控制台中的 jQuery 命令都不会显示 SVG 元素中的命名空间)。

当您需要重新利用这些 svg 片段以满足其他需求(CSS 中的背景图像或 HTML 中的 img 元素)时,请注意缺少的命名空间。如果没有命名空间,浏览器可能会拒绝显示 SVG(无论编码是 utf8 还是 base64)。


Dr *_*Nic 6

如果您使用 postcss,您可以尝试该postcss-inline-svg插件https://www.npmjs.com/package/postcss-inline-svg

.up {
    background: svg-load('img/arrow-up.svg', fill: #000, stroke: #fff);
}
.down {
    background: svg-load('img/arrow-down.svg', fill=#000, stroke=#fff);
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*lin 5

我找到了一种 SVG 解决方案。但它仅适用于 Webkit,我只想与您分享我的解决方法。在我的示例中,展示了如何通过过滤器将 DOM 中的 SVG 元素用作背景(background-image: url('#glyph') 不起作用)。

此 SVG 图标渲染所需的功能:

  1. 使用 CSS 将 SVG 滤镜效果应用于 HTML 元素(不支持 IE 和 Edge)
  2. 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;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是使用 url encode

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)})`;
Run Code Online (Sandbox Code Playgroud)
.container{
  height:50px;
  width:250px;
  display:block;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)