2023-11-18 06:00:02

CSS中的内联SVG

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

我的意思是:

.my-class {
  background-image: <svg>...</svg>;
}

当前回答

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

其他回答

对于那些仍在挣扎的人,我设法让它在所有IE11及以上的现代浏览器上工作。

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

有三件事你需要注意:

URL ENCODE YOUR SVG As others have suggested, you need to URL encode your entire SVG string for it to work in IE11. In my case, I left out the color values in fields such as fill="#00FF00" and stroke="#FF0000" and replaced them with a SASS variable fill="#{$color-rgb}" so these can be replaced with the color I want. You can use any online converter to URL encode the rest of the string. You'll end up with an SVG string like this: %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时,为了在IE11中工作,你需要省略该字符集。 NOT background-image: url(data:image/svg+xml;utf-8,%3Csvg%2....) BUT background-image: url(data:image/svg+xml,%3Csvg%2....)


使用RGB()代替十六进制颜色Firefox不喜欢在SVG代码中使用#。所以你需要用RGB替换颜色十六进制值。 不填= " # 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');
   }
}

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

我可以省略整个精灵位图,用CSS中的内联SVG替换它,压缩后只有大约25kb。所以这是一个很好的方法来限制你的网站必须做的请求数量,而不膨胀你的CSS文件。

是的,这是可能的。试试这个:

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>");
      }

http://jsfiddle.net/6WAtQ/

(注意,SVG内容需要进行url转义,例如#被%23取代。)

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

我找到了SVG的一个解决方案。但这只是Webkit的工作,我只是想与你分享我的工作方法。在我的例子中展示了如何使用SVG元素从DOM作为背景通过过滤器(background-image: url('#glyph')是不工作的)。

SVG图标渲染所需的特性:

将SVG筛选效果应用到HTML元素使用CSS (IE和 边缘不支持) 支持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>

另一个解决方案是使用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>

我在CodePen演示中也遇到了将内联SVG嵌入CSS的问题。使用SCSS的解决方案是构建一个简单的url编码函数。

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

然后,用%xxcodes替换%,<,>,",':

@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中还提供了一个图像内联助手函数,但由于CodePen不支持它,因此这个解决方案可能会有用。

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

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

当您需要为其他需要(CSS中的background-image或HTML中的img元素)重新使用这些svg片段时,请注意丢失的名称空间。如果没有名称空间,浏览器可能会拒绝显示SVG(无论编码是utf8还是base64)。