问题描述

是否可以在 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-escaped 才能正常工作,例如 #%23 替代。)

This works in IE 9 (which supports SVG)。 Data-URLs 在旧版本的 IE 中工作 (有限制),但是它们本身不支持 SVG 。

次佳解决方案

有点迟了,但是如果你们中的任何一个人都疯狂地尝试使用内置 SVG 作为背景,上面的转义建议并不会奏效。一个,它在 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 。换句话说,上面的例子显示颜色= ‘#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 的更好的文章之一是:http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/

希望这可以帮助

麦克风

第三种解决方案

对于仍在努力的人们,我设法让所有现代浏览器 IE11 及以上版本都能正常工作。

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

你需要注意的事情有三件事:

  1. URL ENCODE 您的 SVG 如其他人所建议的,您需要对整个 SVG 字符串进行 URL 编码,以使其在 IE11 中工作。在我的情况下,我在 fill="#00FF00"stroke="#FF0000"等字段中省略了颜色值,并用 SASS 变量 fill="#{$color-rgb}"替换,这样可以用我想要的颜色代替。您可以使用 any online converter 对字符串的其余部分进行 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. OMIT 数据 URL 中的 UTF8 CHARSET 创建数据 URL 时,需要省略其在 IE11 中工作的字符集。不是 background-image:url(data:image /svg + xml; utf-8,%3Csvg%2 ….) 但是 background-image:url(data:image /svg + xml,%3Csvg%2 ….)


  1. USE RGB() INSTEAD OF HEX 颜色 Firefox 在 SVG 代码中不喜欢#。所以你需要用 RGB 替换你的颜色十六进制值。 NOT fill = “#FF0000” BUT fill = “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');
   }
}

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

我可以省略一个完整的精灵位图,并将其替换为 CSS 中的内联 SVG,压缩之后只有 25kb 左右。所以这是一个很好的方式来限制网站的请求量,而不会使你的 CSS 文件膨胀。

第四种方案

您可以使用此简单的 bash 命令,将 SVG 文件轻松转换为 CSS background 属性的 base64 ecoded 值:

echo "background: transparent url('data:image/svg+xml;base64,"$(openssl base64 < path/to/file.svg)"') no-repeat center center;"

在 Mac OS X 上测试。这样你也可以避免 URL 转义的混乱。

请记住,base64 编码 SVG 文件会增加其大小,请参阅 css-tricks.com blog post

第五种方案

我已经分发了一个 CodePen 演示程序,将嵌入式 SVG 嵌入到 CSS 中也是一样的。与 SCSS 协同工作的解决方案是构建简单的 url-encoding 功能。

可以从内置 str-slice,str-index 功能创建字符串替换功能 (请参阅 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 中不受支持,因此该解决方案可能很有用。

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

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛