使用 CSS 操作外部 svg 文件样式属性
Posted
技术标签:
【中文标题】使用 CSS 操作外部 svg 文件样式属性【英文标题】:Manipulating external svg file style properties with CSS 【发布时间】:2014-04-10 17:41:34 【问题描述】:我正在尝试通过 CSS 操作外部 .svg 文件。
HTML
<body>
<div class="mysvg">
<img src="decho.svg" ></img>
</div>
</body>
CSS
div.mysvg img
opacity: .3;
transition: opacity 1s linear 0s;
div.mysvg img:hover
opacity: 1;
此代码适用于不透明度,但不适用于 fill
或其他 svg 特定属性,如 stroke
。我知道我不能用 img
标签做到这一点,但我一直在寻找几个小时,但我找不到使用 svg
或 object
的正确方法。
所以基本上,我的问题是,我如何获得与我链接的代码相同的结果,但要能够操纵填充、描边等属性,它必须是一个外部文件 ,而不仅仅是粘贴在 html 中的内联 svg 代码。
如果有人能告诉我正确的方法,我将不胜感激。谢谢。
编辑:
我设法通过在 .svg 文件本身中添加一个 css 来做到这一点。它必须紧跟在svg
开始标记之后。
<svg ...>
<style type="text/css" media="screen">
<![CDATA[
g
fill: yellow;
stroke: black;
stroke-width: 1;
transition: fill 1s linear 0s;
g:hover
fill: blue;
]]>
</style>
<g>
<path ...>
</g>
</svg>
还需要在html中插入object
,否则不起作用。
<object data="decho.svg" type="image/svg+xml">
希望这对将来寻找像我这样的答案的人有所帮助。这对我有帮助 http://www.hongkiat.com/blog/scalable-vector-graphic-css-styling/。
【问题讨论】:
您必须使用 javascript 获取对象文档,然后操作其 DOM,您只能使用 CSS。 感谢您的回答。我一直在阅读我可以将 CSS 直接添加到 svg 文件中,您认为这是解决我问题的好方法吗? 你有办法使用 css 来操纵 svg 的大小吗?我不确定这是否可能,因为我还没有在网上找到这样做的方法。我正在嵌入在主页中的 html 文件中使用 svg 代码。 @j4v1 如果您检查我的答案中的链接,有两种可能的方法可以使用 css 操作 svg 的内部。一种是将所有 svg 转换为字体,然后使用 font-size 和 :hover psuedo 操作它们。另一种方法是将svg作为svg defs加载到页面顶部的html中,然后将它们呈现为 【参考方案1】:这是我认为 svg 最大的缺陷:沙盒。
Svg 文件被沙盒化: 在它们自己的文档中,这就是为什么典型的“填充:”样式不适用的原因。同样,您在 svg 中编写的 css 将不适用于您网站的其余部分。
将 css 直接添加到 svg: 这不是一个好的解决方案,因为您最终会在使用的每个 svg 中重写 css。
真正的解决方案:“图标系统”。 SVG 字体或 svg 精灵。阅读更多关于他们的信息here。
不透明度起作用的原因:不透明度适用于 svg 对象/框架本身,而不是 svg 的内容(不可访问)。
我还应该注意,无论您如何将这些 svg、内联、通过引用、在对象中作为背景加载,您都无法进入沙箱。这就是为什么必须将它们转换为字体或使用精灵来使用悬停、焦点和其他效果/过渡。
【讨论】:
这实际上是可能的,只要 SVG 不包含填充,并且您不在 CSS(阴影 DOM 边界)内使用任何父选择器。 是的,如果我们想用 CSS 控制它,它会迫使我们在 HTML 中包含 SVG - 迫使我们打破内容/语义和图形或样式的分离。我想知道为什么。好的,有 Ben 的解决方案——我可能会开始使用它。但是我想到的是通过img[src]
包含 SVG 的基本方式
这个答案不再是 100% 正确的。您可以通过<symbol>
和<use>
包含和设置外部文件的样式。见Ben Crook's answer。【参考方案2】:
如果 SVG 托管在同一个域上(感谢@FabienSnauwaert),并且它本身没有定义填充颜色,并且您在 CSS 中不包含父选择器,这是可能的。例如:
我有以下文件:
icon-sprite.svg(我的 SVG 外部精灵) buttons.scss test.htmlicon-sprite.svg
为了清楚起见,我省略了其他 SVG。
<svg xmlns="http://www.w3.org/2000/svg" style="width:0;height:0;visibility:hidden;">
<symbol viewBox="0 0 1500 828" id="icon-arrow-3pt-down">
<title>arrow-3pt-down</title>
<path d="M1500 0H0l738.9 827.7z"/>
</symbol>
</svg>
test.html
<button class="button--large">
Large button
<svg class="svg" >
<use xlink:href="icon-sprite.svg#icon-arrow-3pt-down"></use>
</svg>
</button>
buttons.scss
.svg
fill: red;
如果我要使用 body .svg
,由于影子 DOM 边界,这将不起作用。
见this CSS Tricks article for more info
【讨论】:
@Rolf 我认为 SVG 片段与我上面提到的不同,这似乎是为了将一个 SVG 的一小部分用作 CSS 背景或图像标签内。 css-tricks.com/svg-fragment-identifiers-work 解释得很好,虽然我只是略读。 很棒的解决方案,适用于所有 Firefox、Chrome 和 Safari。谨防!即使 xlink:href 已被弃用,在 Safari 中,引用仍必须使用xlink:href
属性 - 仅使用 href
将导致图像无法加载。 (从 Safari 12.0.2 发布。)
虽然我在这里,但 SVG 不支持 alt
属性。另一种选择是:role="img" aria-label="[title + description]"
.
...要使其正常工作,SVG 必须与托管页面位于同一域中。 (因此,如果您的站点是 example.org 并且您在 cdn.example.org 上托管 SVG,那么您就不走运了。)Documented here:“出于安全原因,浏览器可以应用同源策略use
元素,并且可以拒绝在 href
属性中加载跨域 URL,这实际上是所有三大浏览器目前正在发生的事情。 (最终使用简单的<img>
来包含 SVG 并创建 SVG 文件的变体。)
@FabienSnauwaert 好地方,我没想到那个案子。拒绝它是有道理的,因为 SVG 可能容易受到跨站点脚本的攻击。我已将其添加到答案中,谢谢。以上是关于使用 CSS 操作外部 svg 文件样式属性的主要内容,如果未能解决你的问题,请参考以下文章