使用 CSS 操作外部 svg 文件样式属性

问题描述 投票:0回答:5

我正在尝试通过 CSS 操作外部 .svg 文件。

HTML

<body>
    <div class="mysvg">
    <img src="decho.svg" alt="decho" width="200px"></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
来做到这一点的正确方法。

所以基本上,我的问题是,如何实现与我链接的代码相同的结果,但要能够操作填充、描边等属性,并且它必须是一个外部文件,而不仅仅是内联svg代码粘贴到 html 中。

如果有人能够向我展示正确的方法,我将不胜感激。谢谢。


编辑:

我设法通过在 .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>

您还需要将其作为

object
插入到 html 中,否则将无法工作。

<object data="decho.svg" type="image/svg+xml">

希望这对将来像我一样寻找答案的人有所帮助。这对我有帮助http://www.hongkiat.com/blog/scalable-vector-graphic-css-styling/

html css svg
5个回答
29
投票

我认为这是 svg 中最大的缺陷:沙箱

Svg 文件在其自己的文档中被沙箱化:,这就是典型的“fill:”样式不适用的原因。同样,您在 svg 中编写的 css 将不适用于网站的其余部分。

将 css 直接添加到 svg: 这不是一个好的解决方案,因为你最终会在你使用的每个 svg 中重写 css。

真正的解决方案:“图标系统”。 Svg 字体或 svg 精灵。阅读更多关于他们的信息这里

不透明度起作用的原因:不透明度适用于 svg 对象/框架本身,而不是 svg 的内容(无法访问)。

我还应该注意,无论您如何加载这些 svg,内联,通过引用,在对象中作为背景,您都将无法进入沙箱。这就是为什么需要将它们转换为字体或使用精灵才能使用悬停、焦点和其他效果/过渡。


17
投票

如果 SVG 托管在同一域上(感谢 @FabienSnauwaert)并且它本身没有定义填充颜色,并且 CSS 中不包含父选择器,则这是可能的。例如:

我有以下文件:

  • icon-sprite.svg(我的 SVG 外部精灵)
  • 按钮.scss
  • 测试.html

图标精灵.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>

测试.html

<button class="button--large">
    Large button
    <svg class="svg" width="20px" height="20px">
        <use xlink:href="icon-sprite.svg#icon-arrow-3pt-down"></use>
    </svg>
</button>

按钮.scss

.svg {
    fill: red;
}

由于影子 DOM 边界,如果我要使用 body .svg,这将

无法
工作。

请参阅 这篇 CSS 技巧文章了解更多信息


5
投票

我最近遇到了这个。虽然由于某些原因 SVG 不是 DOM 的一部分,但您可以使用一些 javascript 将它们移动到 DOM

<object type="image/svg+xml" data="illustration.svg"
onload="this.parentNode.replaceChild(this.contentDocument.documentElement, this);">
</object>

这将在加载后将

<object>
替换为内联。如果 javascript 被禁用,它会退回到
<object>
标签,并且 svg 将不会被主题化。就我而言,样式是针对 javascript 控制的深色主题,因此拥有正确的后备意味着没有主题问题。

考虑的其他选项(xlink 对于精灵来说是一个很好的选择):

  • 使用外部库在DOM中加载svgs(在我看来,上面的js很简单)
  • 使用 svg 滤镜进行色度键控。这使得 svgs 的编辑更加复杂,可能会使用更多的资源来执行过滤,并且灵活性较差。

请注意,我不确定安全隐患,最好将其保存为您控制的文件。


0
投票

不幸的是,Web 标准中没有内置功能可以实现这一点。 SVG 符号是一个选项,但不适用于 CDN 上托管的文件。此外,您需要确保正确定义 SVG 文件才能使用

<use>
标签。

我创建了一个库,svg-loader,可以更轻松地实现这一目标。它使用Javascript,但只有3kb,并且是异步加载的,因此对性能的影响可以忽略不计。它是即插即用的,因此除了包含

<script>
标签之外,您无需执行任何操作。

这是一个 Codepen 示例


0
投票

我需要这个来改变具有 svg 背景的元素的填充颜色,在悬停时并给定不同的条件。我不想为每个需要的背景颜色添加一个新的 svg。在这种情况下,我需要一个六边形背景图像。

所以我创建了两个 svgs,一个用于遮罩,另一个用于正常背景颜色。

这是 svg(感谢维基媒体):hexagon.svg

<svg xmlns="http://www.w3.org/2000/svg" height="628" width="726">
   <polygon points="723,314 543,625.769145 183,625.769145 3,314 183,2.230855 543,2.230855 723,314" fill="none" stroke="black" stroke-width="4"/>
</svg>

我将此 svg 复制到另一张,完全相同,只是使用 fill="#fff" (hexagon-masked.svg)

对于我使用的CSS(scss)

.cel {
 background-image: url("/assets/img/hexagon.svg");
 background-size: 100% 100%;
 background-repeat: no-repeat;
 //mask the background
mask-image: url("/assets/img/hexagon-mask.svg");
mask-size: 100% 100%;
mask-repeat: no-repeat;

background-color: white;

 &:hover {
  background-color: red;
  color: white
 }
}

这样,只有 .cel div 的遮罩部分获得背景颜色,即不透明的“hexagon-masked.svg”六边形的 insade。需要正常的背景图片来设置笔画。

所以,我仍然需要 svgs,但仅此而已。

© www.soinside.com 2019 - 2024. All rights reserved.