はじめに
SVGでアイコンを作るのも慣れてきましたので、そろそろ動くものを作ろうかなと思い始めました。
そんな中、use要素で参照するとアニメーションが動作しないという事象が発生しました。
これをMicrosoft Copilotに聞いたところ、SVGの仕様だと言われました。
そうなんだと思い、書き留めることにしました。
今回実施する内容
SVGでuse要素を使用した時にはSVGがアニメーションしないことを確認します。
ソースコード(Git Hub)
環境
OS: Windows 11 JP (64bit)
Edge: バージョン 149.0.4022.80 (公式ビルド) (64 ビット)
参考
用語
動作するアニメーション(なし)
まずは、以下の動作するアニメーションを作ります。
- 赤い丸が拡大縮小を繰り返す
<div class="demo">
<svg viewBox="0 0 220 220" role="img" aria-label="Animated SVG sample">
<circle cx="110" cy="110" r="32" fill="#ff6b6b">
<animate attributeName="r" values="32;60;32" dur="1.4s" repeatCount="indefinite"></animate>
</circle>
</svg>
</div>
動作しないアニメーション(あり)
では、これをsvgファイルに収めてuse要素を使っていきます。
-
index.htmlは、単にuse要素でanimate.svgを参照します。
<div class="demo">
<svg>
<use href="animate.svg"></use>
</svg>
</div>
-
animate.svgには先ほどのコードを記載します。
<?xml version="1.0" standalone="no"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="110" cy="110" r="32" fill="#ff6b6b">
<animate attributeName="r" values="32;60;32" dur="1.4s" repeatCount="indefinite"></animate>
</circle>
</svg>
SVG Spec. 1.1 (Second)では
AI曰く、SVG Spec. 1.1の5.6章の以下の内容によるものだという。
5.6 The ‘use’ element
The effect of a ‘use’ element is as if the contents of the referenced element were deeply cloned into a separate non-exposed DOM tree which had the ‘use’ element as its parent and all of the ‘use’ element's ancestors as its higher-level ancestors. Because the cloned DOM tree is non-exposed, the SVG Document Object Model (DOM) only contains the ‘use’ element and its attributes. The SVG DOM does not show the referenced element's contents as children of ‘use’ element.
use要素の効果は、参照された要素が、分割された非公開DOMツリーに深くクローンされたようなものである。このDOMツリーはより高いレベルの先祖として、その親、および、すべてのuse要素の先祖use要素を持つ。クローンされたDOMツリーは非公開であるため、SVGドキュメントオブジェクトモデル(DOM)は、use要素とその属性だけを含む。SVG DOMは参照された要素の内容をuse要素の子として示されない。
ちょっと何を言っているのかわからないと思いましたが、
index.htmlのSVG DOMツリーは、
body
└div
└svg
└use
anitmate.svgのほうは、
svg
└circle
└animate
で、完全に切れているということを言っていると理解しました。
DOMが切れていても、アニメーション動作はしそうなものですが、それは動作しないようです。
object要素にすると動作はする
object要素で参照するとアニメーションします。object要素の場合は独立したDOMを構築するとAIは言っていました。
<div class="demo">
<object type="image/svg+xml" data="animate.svg" aria-label="Animated SVG sample"></object>
</div>
objectのデメリット
object要素内に記載したSVGに対して、
- CSSを反映できない
-
JavaScriptで操作できない - イベントを付与できない
- レイアウトが効かないことがある
- 読み込みが非同期で、期待とタイミングずれがおきる
- CORS制限になることがある
何か操作をしたときに動作させるようなことには向かないということですね。
img要素にすると動作はする
img要素で参照するとアニメーションします。
最初、AIに聞いたときは動作しないと答えたのですが、試してみたら動作しました。
動作報告すると、一部ブラウザでは動作すると答えが変わりました。
<div class="demo">
<object type="image/svg+xml" data="animate.svg" aria-label="Animated SVG sample"></object>
</div>
imgのデメリット
img要素内に記載したSVGに対して、
- CSSを反映できない
-
JavaScriptで操作できない - イベントを付与できない
- レイアウトが効かないことがある
- 読み込みが非同期で、期待とタイミングずれがおきる
何か操作をしたときに動作させるようなことには向かないということですね。
おわりに
今年(2026年)から、AIを使用したプログラムの作成を活用するようになりました。
前回くらいから、Qiitaで作成しているソースは、無料である程度利用できるVisual Studio Code上のGitHub Copilotを使って、「Agent」と「入力補助」で作っています。
SVGはそもそもWebで画像からSVGを作ることができますので、AIを使う必要はありません。
が、AIを使いこなしたいなという思いもあり、あえて使うようにしています。
GitHub Copilotでは入力支援をどんどんしてくれるため、どんどん作られてしまいます。自分でキャンセルして止めるくらいの状態です。
趣味でSVGなどの勉強をしているというのに、人の趣味をとるんじゃないという勢いです。
AIの進化はさらに進んでいくと思いますが、プログラムの基礎知識は引き続きつけていきたいなと思います。

