:当svg在外部文件中时,悬停不在svg上工作

时间:2016-11-28 18:34:10

标签: css3 svg svg-animate

所以我正在学习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 437.1 294.4" style="enable-background:new 0 0 437.1 294.4;" xml:space="preserve">

    <style type="text/css">

        .st0:hover {
            fill: red;
         }

    </style>

    <g id="Circle">
        <path class="st0" d="M291.3,147.4c0,77-62.4,139.4-139.4,139.4S12.5,224.4,12.5,147.4C12.6,70.4,75,8,151.9,8
        C228.9,8,291.3,70.4,291.3,147.4"/>
    </g>

</svg>

当svg代码在html文件中时,这与预期完全一样。

然而,当我把它放在svg文件中并使用img标签调用它时,悬停效果不再有效。

<img class="logo" src="url/logo.svg">

有没有办法在没有将svg代码嵌入html中的情况下执行此操作?

谢谢!

2 个答案:

答案 0 :(得分:2)

无法使用<img>标记完成。见:Styling And Animating SVGs With CSS。在本文页面底部附近有一个表格,其中包含每种SVG嵌入技术(即img,object等)的优缺点。我在这里复制了表格:

|                      | CSS Interactions | CSS Animations | SVG Animations |
|:--------------------:|:----------------:|:--------------:|:--------------:|
|         <img>        |        No        |      Yes*      |       Yes      |
| CSS background image |        No        |      Yes*      |       Yes      |
|       <object>       |       Yes*       |      Yes*      |       Yes      |
|       <iframe>       |       Yes*       |      Yes*      |       Yes      |
|        <embed>       |       Yes*       |      Yes*      |       Yes      |
|    <svg> (inline)    |        Yes       |       Yes      |       Yes      |

*仅限于<svg>

答案 1 :(得分:1)

我将这个答案写成Sean's answer的一种应用版本。以下代码段显示了您可以如何利用<svg>以及它们在每种情况下的功能的各种形式。

主要的一点是,根据上下文,<svg>可能会也可能不会从顶级文档接收样式规则,可能会也可能不会从顶级文档接收交互式事件(:hover )。

我建议您查看下面的代码段以查看正在运行的应用程序:

&#13;
&#13;
const someSVG = `
<svg width="128" height="128" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
    <style>
        .interactive.from-svg {
            fill: red;
            transition: fill 200ms ease;
        }

        .interactive.from-svg:hover {
            fill: blue;
        }

        .animated.from-svg{
            animation: 3s infinite alternate changecolor;
        }

        @keyframes changecolor{
            from {
                fill: green;
            }
            to {
                fill: purple;
            }
        }
    </style>
    <circle class="interactive from-doc" cx="25" cy="25" r="25"></circle>
    <circle class="animated from-doc" cx="75" cy="25" r="25"></circle>
    <circle class="interactive from-svg" cx="25" cy="75" r="25"></circle>
    <circle class="animated from-svg" cx="75" cy="75" r="25"></circle>
</svg>
`;
const dataUri = `data:image/svg+xml;base64,${btoa(someSVG)}`;

const imgContainer = document.getElementById("img-container"),
  img = document.createElement("img");
imgContainer.appendChild(img);
img.src = dataUri;

const backgroundImageContainer = document.getElementById("background-image-container"),
  backgroundImage = document.createElement("div");
backgroundImageContainer.appendChild(backgroundImage);
backgroundImage.style.width = "128px";
backgroundImage.style.height = "128px";
backgroundImage.style.backgroundImage = `url(${dataUri})`;

const iframeContainer = document.getElementById("iframe-container"),
  iframe = document.createElement("iframe");
iframeContainer.appendChild(iframe);
iframe.src = dataUri;
&#13;
main {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

section {
  flex-basis: 50%;
  flex-grow: 1;
  flex-shrink: 0;
}

.interactive.from-doc {
  fill: red;
  transition: fill 200ms ease;
}

.interactive.from-doc:hover {
  fill: blue;
}

.animated.from-doc {
  animation: 3s infinite alternate changecolor;
}

@keyframes changecolor {
  from {
    fill: green;
  }
  to {
    fill: purple;
  }
}

li.pro {
  color: green;
}

li.con {
  color: red;
}
&#13;
<h1><code>&lt;svg&gt;</code> Usage Comparison</h1>
<main>
  <section id="external">
    <h2><code>&lt;img&gt;</code></h2>
    <div id="img-container"></div>
    <pre><code>&lt;img src="some.svg"&gt;</code></pre>
    <ul>
      <li class="con">Does not receive <strong>any</strong> style from top level document</li>
      <li class="con">Does not utilize CSS Interactions such as <code>:hover</code></li>
      <li class="pro">Will use CSS Animations if they are defined within the svg element's style</li>
    </ul>
  </section>
  <section>
    <h2><code>background-image</code></h2>
    <div id="background-image-container"></div>
    <pre><code>
&lt;style&gt;
.rule{
    background-image: url(some.svg);
}
&lt;/style&gt;
&lt;div class="rule"&gt;&lt;/div&gt;
</code></pre>
    <ul>
      <li class="con">Does not receive <strong>any</strong> style from top level document</li>
      <li class="con">Does not utilize CSS Interactions</li>
      <li class="pro">Will use CSS Animations if they are defined within the svg element's style</li>
    </ul>
  </section>
  <section>
    <h2><code>&lt;iframe&gt;</code></h2>
    <div id="iframe-container"></div>
    <pre><code>&lt;iframe src="some.svg"&gt;</code></pre>
    <ul>
      <li class="con">Does not receive <strong>any</strong> style from top level document</li>
      <li class="pro">Will use CSS Interactions if they are defined within the svg element's style</li>
      <li class="pro">Will use CSS Animations if they are defined within the svg element's style</li>
    </ul>
  </section>
  <section>
    <h2>Inline <code>&lt;svg&gt;</code></h2>
    <svg width="128" height="128" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
                <style>
                    .interactive.from-svg {
                        fill: red;
                        transition: fill 200ms ease;
                    }

                    .interactive.from-svg:hover {
                        fill: blue;
                    }

                    .animated.from-svg{
                        animation: 3s infinite alternate changecolor;
                    }

                    @keyframes changecolor{
                        from {
                            fill: green;
                        }
                        to {
                            fill: purple;
                        }
                    }
                </style>
                <circle class="interactive from-doc" cx="25" cy="25" r="25"></circle>
                <circle class="animated from-doc" cx="75" cy="25" r="25"></circle>
                <circle class="interactive from-svg" cx="25" cy="75" r="25"></circle>
                <circle class="animated from-svg" cx="75" cy="75" r="25"></circle>
            </svg>
    <pre><code>&lt;svg&gt;...&lt;/svg&gt;</code></pre>
    <ul>
      <li class="pro">Receives <strong>all</strong> style rules from top level document</li>
      <li class="pro">Will use CSS Interactions if they are defined within the svg element's style</li>
      <li class="pro">Will use CSS Animations if they are defined within the svg element's style</li>
    </ul>
  </section>
</main>
&#13;
&#13;
&#13;

<img>

<img src="some.svg">
  • 未从顶级文档
  • 收到任何样式
  • 不使用:hover
  • 等CSS交互
  • 如果在svg元素的样式中定义了CSS动画
  • ,则会使用CSS动画

background-image

<style>
.rule {
    background-image: url(some.svg);
}
</style>
<div class="rule"></div>
  • 未从顶级文档
  • 收到任何样式
  • 不使用CSS交互
  • 如果在svg元素的样式中定义了CSS动画
  • ,则会使用CSS动画

<iframe>

<iframe src="some.svg"></iframe>
  • 未收到顶级文档的任何样式
  • 如果在svg元素的样式
  • 中定义了CSS交互,则会使用它们
  • 如果在svg元素的样式中定义了CSS动画
  • ,则会使用CSS动画

内联<svg>

<svg>...</svg>
  • 从顶级文档
  • 接收所有样式规则
  • 如果在svg元素的样式
  • 中定义了CSS交互,则会使用它们
  • 如果在svg元素的样式中定义了CSS动画
  • ,则会使用CSS动画
相关问题