问题描述
将 SVG 输出直接放置在页面代码中我可以像 CSS 那样简单地修改填充颜色:
polygon.mystar {
fill: blue;
}
circle.mycircle {
fill: green;
}
这是非常好的,但是我正在寻找一种方法来修改 SVG 的”fill” 属性作为一个 BACKGROUND-IMAGE 。
html {
background-image: url(../img/bg.svg);
}
现在如何改变颜色?甚至有可能吗
作为参考,以下是我的外部 SVG 文件的内容:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve">
<polygon class="mystar" fill="#3CB54A" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679
118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/>
<circle class="mycircle" fill="#ED1F24" cx="202.028" cy="58.342" r="12.26"/>
</svg>
最佳解决方案
我认为你这样做的唯一方法是从一些服务器端机制来服务你的 svg 。只需创建一个资源服务器端,根据 GET 参数输出您的 svg,并且您在某个 URL 上提供它。
那么你只需要在你的 css 中使用这个 url 。
因为作为一个背景 img,它不是 DOM 的一部分,你不能操纵它。另一种可能性是定期使用它,以正常方式将其嵌入页面,但绝对定位,使其全宽页面的高度,然后使用 z-index css 属性将其放在页面上的所有其他 DOM 元素之后。
次佳解决方案
我需要类似的东西,并希望坚持使用 CSS 。我想出了一个完成这项工作的 LESS mixin 。不幸的是,它的浏览器支持有点松了一口气。见下文。
.element-color(@color) {
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="@{color}" ... /></g></svg>');
}
流行,混合到你的规则,更新颜色,whammo 。您也可以根据需要添加更多变量。
.element-color(#fff);
更新:如果您不使用预处理器 (LESS /SASS),则可以执行此操作。
// color: red
background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');
Here is more info 将完整的 SVG 代码嵌入到您的 CSS 文件中。它还提到浏览器兼容性,这是一个有点太小,这是一个可行的选择。
第三种解决方案
另一种方法是使用面膜。然后,您可以更改蒙版元素的背景颜色。这与更改 svg 的 fill 属性具有相同的效果。
HTML:
<glyph class="star"/>
<glyph class="heart" />
<glyph class="heart" style="background-color: green"/>
<glyph class="heart" style="background-color: blue"/>
CSS:
glyph {
display: inline-block;
width: 24px;
height: 24px;
}
glyph.star {
-webkit-mask: url(star.svg) no-repeat 100% 100%;
mask: url(star.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: yellow;
}
glyph.heart {
-webkit-mask: url(heart.svg) no-repeat 100% 100%;
mask: url(heart.svg) no-repeat 100% 100%;
-webkit-mask-size: cover;
mask-size: cover;
background-color: red;
}
你会在这里找到一个完整的教程:http://codepen.io/noahblon/blog/coloring-svgs-in-css-background-images(不是我自己的) 。它提出了各种方法 (不限于掩模) 。
第四种方案
下载您的 svg 作为文本。
使用 javascript 修改您的 svg 文本以更改 paint /stroke /fill color [s] 。
然后按照 here 所述将修改后的 svg 字符串嵌入到 css 中。
第五种方案
现在你可以在客户端这样做:
var green = '3CB54A';
var red = 'ED1F24';
var svg = '<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="320px" height="100px" viewBox="0 0 320 100" enable-background="new 0 0 320 100" xml:space="preserve"> <polygon class="mystar" fill="#'+green+'" points="134.973,14.204 143.295,31.066 161.903,33.77 148.438,46.896 151.617,65.43 134.973,56.679 118.329,65.43 121.507,46.896 108.042,33.77 126.65,31.066 "/><circle class="mycircle" fill="#'+red+'" cx="202.028" cy="58.342" r="12.26"/></svg>';
var encoded = window.btoa(svg);
document.body.style.background = "url(data:image/svg+xml;base64,"+encoded+")";
第六种方案
有可能与 Sass!你唯一要做的就是 url-encode 你的 svg 代码。这可以在 Sass 中使用辅助功能。我为此做了一个代号。看这个:
http://codepen.io/philippkuehn/pen/zGEjxB
// choose a color
$icon-color: #F84830;
// functions to urlencode the svg string
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function url-encode($string) {
$map: (
"%": "%25",
"<": "%3C",
">": "%3E",
" ": "%20",
"!": "%21",
"*": "%2A",
"'": "%27",
'"': "%22",
"(": "%28",
")": "%29",
";": "%3B",
":": "%3A",
"@": "%40",
"&": "%26",
"=": "%3D",
"+": "%2B",
"$": "%24",
",": "%2C",
"/": "%2F",
"?": "%3F",
"#": "%23",
"[": "%5B",
"]": "%5D"
);
$new: $string;
@each $search, $replace in $map {
$new: str-replace($new, $search, $replace);
}
@return $new;
}
@function inline-svg($string) {
@return url('data:image/svg+xml;utf8,#{url-encode($string)}');
}
// icon styles
// note the fill="' + $icon-color + '"
.icon {
display: inline-block;
width: 50px;
height: 50px;
background: inline-svg('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 30 30" enable-background="new 0 0 30 30" xml:space="preserve">
<path fill="' + $icon-color + '" d="M18.7,10.1c-0.6,0.7-1,1.6-0.9,2.6c0,0.7-0.6,0.8-0.9,0.3c-1.1-2.1-0.4-5.1,0.7-7.2c0.2-0.4,0-0.8-0.5-0.7
c-5.8,0.8-9,6.4-6.4,12c0.1,0.3-0.2,0.6-0.5,0.5c-0.6-0.3-1.1-0.7-1.6-1.3c-0.2-0.3-0.4-0.5-0.6-0.8c-0.2-0.4-0.7-0.3-0.8,0.3
c-0.5,2.5,0.3,5.3,2.1,7.1c4.4,4.5,13.9,1.7,13.4-5.1c-0.2-2.9-3.2-4.2-3.3-7.1C19.6,10,19.1,9.6,18.7,10.1z"/>
</svg>');
}
第七种方案
您可以将 SVG 存储在变量中。然后根据您的需要 (即设置宽度,高度,颜色等) 操作 SVG 字符串。然后使用结果设置背景,例如
$circle-icon-svg: '<svg xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="10" /></svg>';
$icon-color: #f00;
$icon-color-hover: #00f;
@function str-replace($string, $search, $replace: '') {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
@function svg-fill ($svg, $color) {
@return str-replace($svg, '<svg', '<svg fill="#{$color}"');
}
@function svg-size ($svg, $width, $height) {
$svg: str-replace($svg, '<svg', '<svg width="#{$width}"');
$svg: str-replace($svg, '<svg', '<svg height="#{$height}"');
@return $svg;
}
.icon {
$icon-svg: svg-size($circle-icon-svg, 20, 20);
width: 20px; height: 20px; background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color)}');
&:hover {
background: url('data:image/svg+xml;utf8,#{svg-fill($icon-svg, $icon-color-hover)}');
}
}
我也做了演示,http://sassmeister.com/gist/4cf0265c5d0143a9e734 。
该代码对 SVG 做了一些假设,例如<svg />
元素不具有现有的填充颜色,并且不设置 width 或 height 属性。由于输入在 SCSS 文档中是硬编码的,所以执行这些约束是非常容易的。
不要担心代码重复。 gzip 压缩使差异可以忽略不计。
第八种方案
您可以为此创建自己的 SCSS 功能。将以下内容添加到 config.rb 文件中。
require 'sass'
require 'cgi'
module Sass::Script::Functions
def inline_svg_image(path, fill)
real_path = File.join(Compass.configuration.images_path, path.value)
svg = data(real_path)
svg.gsub! '{color}', fill.value
encoded_svg = CGI::escape(svg).gsub('+', '%20')
data_url = "url('data:image/svg+xml;charset=utf-8," + encoded_svg + "')"
Sass::Script::String.new(data_url)
end
private
def data(real_path)
if File.readable?(real_path)
File.open(real_path, "rb") {|io| io.read}
else
raise Compass::Error, "File not found or cannot be read: #{real_path}"
end
end
end
那么你可以在你的 CSS 中使用它:
.icon {
background-image: inline-svg-image('icons/icon.svg', '#555');
}
您将需要编辑 SVG 文件,并用 fill = “{color}” 替换标记中的任何填充属性
图标路径始终与相同 config.rb 文件中的 images_dir 参数相关。
类似于其他一些解决方案,但这是非常干净,保持您的 SCSS 文件整洁!
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。