将 SVG 指定为背景图像并在 CSS 中设置 SVG 样式?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7360723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 01:33:36  来源:igfitidea点击:

Specify an SVG as a background image and ALSO style the SVG in CSS?

csssvg

提问by JSDBroughton

Is it possible to specify an SVG as a background image and ALSO style the SVG in the same CSS file?

是否可以将 SVG 指定为背景图像并在同一个 CSS 文件中设置 SVG 样式?

I'm very comfortable placing, scaling and clipping SVG images as either single files or sprites, but I haven't been able to work out if it possible to style the SVG within the same CSS file as sets it as a background image.

我很乐意将 SVG 图像作为单个文件或精灵放置、缩放和剪裁,但我无法确定是否可以在同一个 CSS 文件中设置 SVG 样式并将其设置为背景图像。

In pseudo CSS i'd like to do the following to vary the colour of simple shape based on the class of the parent element:

在伪 CSS 中,我想执行以下操作以根据父元素的类来改变简单形状的颜色:

element1 {
 background-image(icon.svg);
}

element1.black .svg-pathclass {
 fill: #000000;
}

element1.white .svg-pathclass {
 fill: #ffffff;
}

obviously this assumes a path in the SVG having class .svg-pathclass

显然,这假定 SVG 中的路径具有类 .svg-pathclass

is this possible?

这可能吗?

采纳答案by Phrogz

No, this is not possible. The SVG has to be prepared in one document (which may be a data URIor an externally referenced file) and thenused as a background in another file.

不,这是不可能的。SVG 必须在一个文档(可能是数据 URI或外部引用文件)中准备好,然后在另一个文件中用作背景。

回答by Hugo Scott-Slade

You can use SVGand CSSmasks to recreate this effect, then use normal CSSto style the inside of the SVG, even background-image

您可以使用SVGCSS蒙版来重新创建此效果,然后使用正常CSS来设置 内部的样式SVG,甚至background-image

-webkit-mask:   url(filename.svg) 50% 50% / 100px 50px no-repeat;
    -o-mask:    url(filename.svg) 50% 50% / 100px 50px no-repeat;
    -ms-mask:   url(filename.svg) 50% 50% / 100px 50px no-repeat;

background-color: red;
background-image: url(animated.gif);

/* Filename, Position / Size, Repeat */
/* Modernizr.cssmask is the test needed to pass - snippet below */

You can use this to create drop shadows by appending an elementto the DOMand styling that, with a lower z-index and setting an opacity.

您可以使用它来创建阴影,方法是将 附加elementDOM和 样式,使用较低的 z-index 并设置不透明度。

Hope that helps!

希望有帮助!

Edit: Links

编辑:链接

回答by robjez

It's actually possible for those who can use preprocessors in production, by "inlining" background SVG, and bit of SASS mixins, which "slice" whole svggibberish, to get access to parts you want to manipulate via SASS variables.

对于那些可以在生产中使用预处理器的人来说,实际上可以通过“内联”背景 SVG 和 SASSmixins来“切片”整个svg胡言乱语,从而访问您想要通过SASS variables.

In your original scenario you have an element
<div class="element1"></div>,

在您的原始场景中,您有一个元素
<div class="element1"></div>

so you need a mixin/functionwhich will inline SVG for you. Let's say you want to control of the fill, so:

所以你需要一个mixin/function可以为你内联 SVG 的。假设您想控制fill,因此:

@mixin inline-svg($color, $svg-content) {
  $start: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>path { fill:#{$color}; }</style>';
  $end:   '</svg>';

  background-image: url('data:image/svg+xml;utf8, #{$start}#{$svg-content}#{$end}');
}

where $svg-contentvariable is your <svg>stuff excluding <style>element (which you want to access from inside of the mixin) and wrapping svgtag,, ie: $svg-content = "<path .... />"

其中$svg-content变量是你的<svg>东西,不包括<style>元素(你想从 内部访问mixin)和包装svg标签,即: $svg-content = "<path .... />"

This just need to be included with values passed inside:
@include inline-svg(salmon, $svg-content);

这只需要包含在内部传递的值中:
@include inline-svg(salmon, $svg-content);

To sum whole thing up, this is an example SASScode:

总而言之,这是一个示例SASS代码:

$svg-content = "<path .... />"

@mixin inline-svg($color, $svg-content) {
    $start: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><style>path { fill:#{$color}; }</style>';
    $end:   '</svg>';

    background-image: url('data:image/svg+xml;utf8, #{$start}#{$svg-content}#{$end}');
}  

.element1 {
    @include inline-svg(rgba(0,0,0,0.6), $svg-content);
}

I think possibilities here are quite big (there are also limitations here to that approach). I actually pass a SASS mapto my mixinwith cssstyles defined as key, valuepair, to inject whole bunch of cssstyles to the <style>part of svg.

我认为这里的可能性很大(这种方法也有局限性)。其实我传递一个SASS map对我mixincss定义的样式keyvalue对,注入一大堆css风格的<style>一部分svg

So it's technically possible, but require more compexity, but once you get this done, you'll get benefits of reusing this mixinthroughout your project(s), which is cool .

所以这在技术上是可行的,但需要更多的复杂性,但是一旦你完成了这项工作,你将获得mixin在整个项目中重复使用它的好处,这很酷。

回答by S..

Styling the SVG via a separate CSS class didn't work for me, but inline styling did:

通过单独的 CSS 类对 SVG 进行样式设置对我不起作用,但内联样式确实适用:

&::after {
      content: url("data:image/svg+xml;charset=UTF-8, <svg viewBox='0 0 14 24' xmlns='http://www.w3.org/2000/svg' width='12px' height='18px'><path fill='rgb(13, 132, 254)' d='M2.1.1L0 2.2l8.3 8.3L9.8 12l-1.5 1.5L0 21.8l2.1 2.1L14 12z' /></svg>");
    }

Note: specifying the fillprop as a hexcode colour didn't work, even though it did if in a 'normal' SVG, that's why I converted it to RGB and styled it that way.

注意:将fill道具指定为十六进制颜色不起作用,即使它在“正常”SVG 中起作用,这也是我将其转换为 RGB 并以这种方式设置样式的原因。

回答by ghiscoding

Reading all of these answers made me come up with this nice way of dealing with SVG in SASS (.scss), which compiles CSS, for my styling theme and also get the colorworking. For my use case, I want (need) to use content: url(..svg)since my lib supports Font and now SVG by using content: $my-icon;in a pseudo :beforethat is the only thing that works with both Font/SVG.

阅读所有这些答案让我想出了这种在 SASS (.scss) 中处理 SVG 的好方法,它编译 CSS,用于我的样式主题并开始color工作。对于我的用例,我想(需要)使用,content: url(..svg)因为我的库支持 Font,现在 SVG 通过content: $my-icon;在伪代码:before中使用,这是唯一适用于 Font/SVG 的东西。

First is to create a SASS function to deal with urlencodeof the color (since content: url()needs to be encoded, #needs to become %23). For reference, I copied this function from someone else Gist. For example this will take #fafafaand return %23fafafathat I can then use in fillof the SVG. You could also go without it, just remember to change #to %23in the fillproperty.

首先是创建一个SASS函数来处理urlencode颜色的(因为content: url()需要编码,所以#需要变成%23)。作为参考,我从其他人Gist复制了这个函数。例如,这将获取#fafafa并返回%23fafafa,然后我可以fill在 SVG 中使用它。您也可以不使用它,只需记住在属性中更改#为。%23fill

/* sass-utilities.scss */
@function encodecolor($string) {
    @if type-of($string) == 'color' {
        $hex: str-slice(ie-hex-str($string), 4);
        $string:unquote("#{$hex}");
    }
    $string: '%23' + $string;
    @return $string;
}

My lib has a few SASS variables defined for theme styling so this is what I got working with both Font and/or SVG (I added widthand displaybut it might work without too).

我的库有一些为主题样式定义的 SASS 变量,所以这就是我使用 Font 和/或 SVG 的工作(我添加了widthdisplay但它也可能没有工作)。

.sort-indicator-desc:before {
    content: $icon-sort-desc;
    display: inline-block;
    width: $icon-sort-font-size;    
    font-size: $icon-sort-font-size;
}

and finally the end user can still use it with a Font Family (like Font Awesome 4)

最后,最终用户仍然可以将它与 Font Family 一起使用(例如 Font Awesome 4)

/* with a Font */
$icon-font-family:     "FontAwesome"; //  Font Awesome 4 
$icon-sort-color:      #0070d2;
$icon-sort-font-size:  13px;
$icon-sort-asc:        "\f0d8";       // unicode value of the icon
$icon-sort-desc:       "\f0d7";
// this compiles to => `content: "\f0d8";

or with SVG (like Font Awesome 5)

或使用 SVG(如 Font Awesome 5)

@import './sass-utilities'; // sass helper

/* with SVG */
$icon-sort-color:     #0070d2;
$icon-sort-font-size: 13px;
$icon-sort-asc:       url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="#{encodecolor($icon-sort-color)}" viewBox="0 0 24 24" id="arrowdown"><path d="M19.1 9.7c.4-.4.4-.9 0-1.3l-6.9-6.7c-.4-.4-.9-.4-1.3 0L4 8.4c-.4.4-.4.9 0 1.3l1.3 1.2c.3.4.9.4 1.3 0l2.1-2.1c.4-.4 1-.1 1 .4v12.5c0 .5.5.9 1 .9h1.8c.5 0 .9-.5.9-.9V9.2c0-.5.7-.8 1-.4l2.2 2.1c.4.4.9.4 1.3 0l1.2-1.2z"></path></svg>');
$icon-sort-desc:      url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" fill="#{encodecolor($icon-sort-color)}" viewBox="0 0 24 24" id="arrowdown"><path d="M4.4 14.3c-.3.4-.3.9 0 1.3l7 6.7c.3.4.9.4 1.2 0l7-6.7c.4-.4.4-.9 0-1.3l-1.3-1.2c-.3-.4-.9-.4-1.3 0l-2.1 2.1c-.4.4-1.1.1-1.1-.4V2.3c0-.5-.4-.9-.9-.9h-1.8c-.5 0-.9.5-.9.9v12.5c0 .5-.7.8-1.1.4L7 13.1c-.4-.4-1-.4-1.3 0l-1.3 1.2z"></path></svg>');
// this compiles to => `content: url('data:image/svg+xml,<svg>...');

So at the end, I got both the Font & SVG working with SASS variables and that is great because that means that any users of my lib (Angular-Slickgrid) can still use Font Awesome 4 icons (font) while others could also use SVGs (like Font Awesome 5) without having to install the Font Family (.eof, .woff, ...) which tend to be large depending on the lib. The end result is still a compiled CSS file with contentto load the SVG with an extra fillproperty for the SVG color.

所以最后,我让 Font 和 SVG 与 SASS 变量一起工作,这很棒,因为这意味着我的库(Angular-Slickgrid)的任何用户仍然可以使用 Font Awesome 4 图标(字体),而其他人也可以使用 SVG (如 Font Awesome 5),而无需安装 Font Family ( .eof, .woff, ...) 这取决于 lib。最终结果仍然是一个编译的 CSS 文件,content用于加载具有fillSVG 颜色的额外属性的 SVG。

and voilà!!! I get the best of both :)

瞧!!!我两全其美:)