作为背景图像时,修改SVG填充颜色
将SVG输出直接与页面代码内联,我可以简单地用CSS修改填充颜色,如下所示:
polygon.mystar { fill: blue; } circle.mycircle { fill: green; }
这很好,但是我正在寻找一种方法来修改SVG的“填充”属性,当它被用作一个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。 简单地创build一个资源服务器端,根据GET参数输出你的svg,并在特定的URL上提供它。
那么你只是在你的CSS中使用该url。
因为作为背景img,它不是DOM的一部分,你不能操纵它。 另一种可能是定期使用它,以正常的方式将其embedded到页面中,但将其绝对定位,使其成为页面的完整宽度和高度,然后使用z-index css属性将其放在所有其他DOM元素的后面在一个页面上。
我需要类似的东西,并希望坚持使用CSS。 这里是LESS和SCSS mixin以及简单的CSS,可以帮助你做到这一点。 不幸的是,它的浏览器支持有点松懈。 请参阅下面的浏览器支持细节。
LESS mixin:
.element-color(@color) { background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="@{color}" ... /></g></svg>'); }
使用量less
.element-color(#fff);
SCSS mixin:
@mixin element-color($color) { background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="#{$color}" ... /></g></svg>'); }
SCSS用法:
@include element-color(#fff);
CSS:
// color: red background-image: url('data:image/svg+xml;utf8,<svg ...><g stroke="red" ... /></g></svg>');
这里有更多关于将完整的SVG代码embedded到CSS文件的信息。 它也提到浏览器的兼容性,这是一个有点太小的select。
另一种方法是使用掩码。 然后,您更改蒙面元素的背景颜色。 这与改变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; }
你会在这里find一个完整的教程: http : //codepen.io/noahblon/blog/coloring-svgs-in-css-background-images (不是我自己的)。 它提出了多种方法(不限于掩码)。
下载您的svg文本。
修改你的svg文本使用JavaScript来改变涂料/笔画/填充颜色[s]。
然后将修改后的svgstringembedded到您的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+")";
在这里拨弄!
这可能与萨斯! 你唯一需要做的就是对你的svg代码进行url编码。 这可以在Sass中使用辅助函数。 我为此做了一个codepen。 看这个:
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存储在一个variables中。 然后根据您的需要操作SVGstring(即设置宽度,高度,颜色等)。 然后使用结果设置背景,例如
$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 />
元素没有现有的填充颜色,也没有设置宽度或高度属性。 由于input在SCSS文档中是硬编码的,因此执行这些约束是相当容易的。
不要担心代码重复。 gzip压缩使差异可以忽略不计。
您可以为此创build自己的SCSSfunction。 将以下内容添加到您的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}”replace标记中的所有填充属性
图标path总是与相同的config.rb文件中的images_dir参数相关。
类似于其他解决scheme,但这是相当干净,并保持您的SCSS文件整洁!
.icon { width: 48px; height: 48px; display: inline-block; background: url(s.cdpn.io/18515/heart.svg) no-repeat 50% 50%; background-size: cover; } .icon-orange { -webkit-filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); filter: hue-rotate(40deg) saturate(0.5) brightness(390%) saturate(4); } .icon-yellow { -webkit-filter: hue-rotate(70deg) saturate(100); filter: hue-rotate(70deg) saturate(100); }
codeben文章和演示
但是,我可以在SVG多边形中添加一个填充颜色,如果你能够直接编辑SVG代码,例如下面的svg呈现红色,而不是默认的黑色。 我还没有在Chrome之外进行testing:
<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="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve"> <polygon fill="red" fill-rule="evenodd" clip-rule="evenodd" points="452.5,233.85 452.5,264.55 110.15,264.2 250.05,390.3 229.3,413.35 47.5,250.7 229.3,86.7 250.05,109.75 112.5,233.5 "/> </svg>
在一些(非常具体的)情况下,这可以通过使用filter来实现。 例如,您可以使用filter: hue-rotate(45deg);
将色相旋转45度,将蓝色SVG图像更改为紫色filter: hue-rotate(45deg);
。 浏览器的支持是最小的,但它仍然是一个有趣的技术。
演示
您可以使用CSS遮罩,使用'mask'属性创build应用于元素的遮罩。
.icon { background-color: red; -webkit-mask-image: url(icon.svg); mask-image: url(icon.svg); }
欲了解更多信息,请参阅这篇文章: https : //codepen.io/noahblon/post/coloring-svgs-in-css-background-images
很多IF,但是如果你的base64编码SVG开始:
<svg fill="#000000
然后base64编码的string将开始:
PHN2ZyBmaWxsPSIjMDAwMDAw
如果预编码的string开始:
<svg fill="#bfa76e
那么这编码为:
PHN2ZyBmaWxsPSIjYmZhNzZl
两个编码的string都是相同的:
PHN2ZyBmaWxsPSIj
base64编码的怪癖是每3个input字符变成4个输出字符。 SVG以这种方式开始,然后6个字符的hex填充颜色正好在编码块的“边界”上开始。 所以你可以轻松的做一个跨浏览器的JSreplace:
output = input.replace(/MDAwMDAw/, "YmZhNzZl");
但上面的tnt-rox答案是前进的道路。
这是我最喜欢的方法,但是您的浏览器支持必须非常进步。 使用mask属性可以创build应用于元素的遮罩。 掩码不透明或固体的地方,底层的图像显示出来。 在透明的地方,底层的图像被遮盖或隐藏。 CSS掩码图像的语法与background-image类似。 看看codepen mask