tl;dr
- chromeのfaviconはsecure static mode
概要
こちらの記事を読んで、Google Chrome 80以降でfaviconにsvgが使えるようになったことを知りました。
svgといえばベクタ画像なので拡大縮小しても画像が劣化しないというのが大きな特徴ですが、個人的にはアニメーションを記述できる点も楽しいのでsvgのfaviconでanimationが動くかどうか確認しました。実際に使う機会は無さそうですが。
方式
svgをanimationさせる方法は、svg自身に記述するもので3種類あります。
https://ics.media/entry/15970/
- css animation
- SMIL
- javascript
index.html
次のhtmlファイルからfavicon.svgを読み込みます。
bodyでも読み込んでいるのは、favicon特有の問題かどうかを区別するためです。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>favicon test</title>
<link rel="icon" href="/favicon.svg">
</head>
<body>
<img src="/favicon.svg" width="200px" />
</body>
</html>
CSS animation
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<polygon class="square" points="40,40 40,160 160,160 160,40" style="fill:yellow;" />
<style>
.square {
animation: rotation 3s linear infinite;
transform-origin: center;
}
@keyframes rotation {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
</style>
</svg>
SMIL
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<polygon class="square" points="40,40 40,160 160,160 160,40" style="fill:yellow;">
<animateTransform type="rotate" attributeName="transform" attributeType="XML" values="0 100,100;360 100,100" dur="3s" repeatCount="indefinite" />
</polygon>
</svg>
javascript
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200">
<polygon id="square" points="40,40 40,160 160,160 160,40" style="fill:yellow; transform-origin: center;" />
<script type="text/javascript">
let time = 0;
const square = document.querySelector('#square');
function animate() {
requestAnimationFrame(() => {
const deg = 2 * time // 360;
square.style.transform = `rotate(${deg}deg)`;
time += 1;
animate();
});
}
animate();
</script>
</svg>
imgタグで読みこむsvgはsecure animated modeとなるので、javascriptが効きません。
An SVG embedded within an ‘image’ element must be processed in secure animated mode
(snip)
The same processing modes are expected to be used for other cases where SVG is used in place of a raster image, such as an HTML ‘img’ element or in any CSS property that takes an data type.
https://svgwg.org/svg2-draft/conform.html#referencing-modes
こちらを参考にhtml側はobjectで埋め込むよう変更します。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>favicon test</title>
<link rel="icon" href="/favicon.svg">
</head>
<body>
<object data="/favicon.svg" width="200px" type="image/svg+xml"></object>
</body>
</html>
その他
こちらの記事では4番目の方法としてAfterEffectなどのソフトを利用する方法が紹介されていますが、最終的にはjavascriptで動かすようです。
またfaviconをanimationさせる方法は他に外からjavascriptでfavicon画像そのものを差し替える方法がありますが、こちらは省略。
環境
MacOSのChromeとFirefoxで表示してみます。
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.15.3
BuildVersion: 19D76
Google Chrome バージョン: 80.0.3987.106(Official Build) (64 ビット)
Firefox 69.0.1 (64-bit)
結果
Firefox & CSS
bodyもfaviconも回っています。
Firefox & SMIL
bodyもfaviconも回っています。
Firefox & javascript
bodyは回っていますがfaviconは回っていません。
Chrome & CSS
bodyは回っていますがfaviconは回っていません。
Chrome & SMIL
bodyは回っていますがfaviconは回っていません。
Chrome & javascript
bodyは回っていますがfaviconは回っていません。
結果まとめ
Google Chrome | Firefox | |
---|---|---|
CSS | x | o |
SMIL | x | o |
javascript | x | x |
faviconをanimationさせようとした結果表のようになりました。
それぞれのブラウザのsvg faviconのモードは次のように推測されます。
- Firefoxは
declarative animation
が可能でscript execution
が不可能なのでAnimated modeまたはSecure Animated mode - Chromeは
declarative animation
もscript execution
も不可能なのでここに書いてある通りsecure static mode
Chromeについてはdeclarative animation
が不可能である一方次の記述があるためSMILアニメーションは動くと思ったのですが動きませんでした。読み間違いでしょうか…?
Chrome serves the SVG in secure static mode, but does apply SMIL animations using the document start time (0).
まとめ
- Chrome 80以降でfaviconにsvg形式利用可能になりましたがアニメーションはできません。残念。
- Firefoxでは以前からfaviconにsvgが利用可能で、アニメーションも動きます。
- ChromeでSMILアニメーションが動かない点が公式情報と異なるので、何か誤りがあれば教えて下さい。
参考
https://caniuse.com/#search=svg%20favicon
https://www.chromestatus.com/feature/5180316371124224
https://ics.media/entry/15970/
https://animated-svg-favicon.glitch.me/