svg maniax ver.2 - mars vanilla
DESCRIPTION
「SVG MANIAX - CSS Nite After dark7」 http://www.slideshare.net/ssuser99dc16/svg-maniaxcss-nite-after-dark7-svgmatsuda を再編したものです。いろいろ追加もしました。TRANSCRIPT
SVG MANIAXScalable Vector Graphics
Ver. 2
Mars vanilla「SVGってもう使っていいの?」勉強会
松田直樹
松田直樹CCO, Web Designer
SVGってもう使っていいの?
え? みんな使ってるよ
9~ 3.2~4~ 3~ 3.0~3.2~
使った方がいい
使える環境の方がシェアがデカい
iOS
2012年時点で、CNN が
アメリカ大統領選コンテンツで SVG を使っている
http://edition.cnn.com/election/2012/ecalculator
Google Analytics のグラフも SVG
2013年末で IE8 をサポート外に
ということで
ちゃんと基礎からやってみましょう
XML 文書としての SVG
宣言と名前空間
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC
"-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 200 200">
...
</svg>
* HTML5 inline SVG の場合は不要
省略推奨
単独ファイルの場合必須
xlink使う場合必須
省略可
viewBox 属性を理解しよう
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200px" height="200px"
viewBox="0 0 200 200">
<circle cx="100" cy="100" r="100"/>
</svg>
描画領域を指定する
viewBox 属性表示する領域(viewport)を指定する属性値 Illustrator でのアートボードに相当する
width="200px" height="160px"
viewBox="0 0 200 160"
<svg viewBox="0 0 100 100" >
100 x 100
0, 0
100, 100
0,0
0,0
100 x 100
-100, -100
190, 190
<svg viewBox=“-100 -100 190 190" >
width="100px" height="80px"
viewBox="0 0 200 160"
viewBox の値は
「px」であって、「px」じゃない
width="100%" height="100%"
viewBox="0 0 200 160"
width="" height=""
viewBox="0 0 200 160"
viewBox の値は
利用空間(描画領域)における
座標と長さを変換する基準値
width="100px" height="100px" viewBox="0 0 200 200"
<circle cx="100" cy="100" r="100"/>
100px
100px円の直径は200
SVG の 1px
ブラウザの 0.5px
=
width, height が絶対値指定の場合
width="100%" height="100%" viewBox="0 0 200 200"
<circle cx="100" cy="100" r="100"/>
可変
可変円の直径は200
SVG の 1px
親要素のサイズに応じる
=
width, height が相対値指定、もしくは auto の場合
width="100px" height="100px"
<circle cx="100" cy="100" r="100"/>
円の直径は200
SVG の 1px
ブラウザの 1px
=
viewBox の指定がない場合
100px
100px
これが
viewBox 属性による「座標系変換」
viewBox 属性の指定をしないと、
いろんなバグ・不具合と出会えます
HTML への埋め方
大きく分けて
4種類
HTML <img>
HTML <object> <embed> <iframe>
CSS bacground
HTML5 inline SVG
外部ファイル参照 インライン
外部ファイル参照
img 要素, object 要素, embed 要素, iframe要素,
CSS background-image
HTML CSS </>
SVG
インラインSVG
HTML5 内に直接 SVG 要素を記述する
<!doctype html> <html> <body>
<svg viewBox="0 0 200 200"> <circle id="c" r="100" x="0" y="0"/>
</svg> </body> </html>
HTML
SVG
HTML5 に SVG の名前空間が内包されているので、xmlns の記述は必要なし
SVG Referencing modes参照モード
HTML <img>
HTML <object> <embed> <iframe>
CSS bacground
HTML5 inline SVG
top-level document
embedded document
static image document
animated image document
static image document
animated image document
font document
Web Fonts mask, pattern …
resource document
SVG Referencing modes
https://svgwg.org/specs/integration/#referencing-modes
SVG Processing modes処理モード
Dynamic Interactive
Mode
Animated Mode
Secure Animated
Mode
Static Mode
Secure Static Mode
SVG のすべての機能を表示可能
SMIL アニメーション表示可能
SMIL アニメーション表示可能
静止画として表示
静止画として表示
スクリプトの実行 ✓
外部リソース 参照 ✓ ✓ ✓SMIL
アニメーション ✓ ✓ ✓DOMイベント
発火 ✓
SVG Processing modes
https://svgwg.org/specs/integration/#processing-modes
SVG Processing modes
Dynamic Interactive
Mode
Animated Mode
Secure Animated
Mode
Static Mode
Secure Static Mode
SVG のすべての機能を表示可能
SMIL アニメーション表示可能
SMIL アニメーション表示可能
静止画として表示
静止画として表示
HTML <img>
HTML <object> <embed> <iframe>
CSS bacground
HTML5 inline SVG
HTML <img>
CSS bacground
Referencing DEMO
Processing DEMO
こんな SVG で試してみましょう
circle要素を use要素で量産
サイズと色をアニメーション
svg 内に 外部 png を配置
svg 内に png を
base64 で埋め込み
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200"> <style type="text/css"> .fillsample { fill: #44bfb7; } @media screen and (max-width: 400px) { .fillsample { stroke: #000; } } </style> <defs> <circle id="c" class="fillsample" r="30"> <animate attributeName="r" begin="0s" dur="7s" from="10" to="30" repeatCount="indefinite"/> <animate attributeName="fill" begin="0s" dur="7s" to="#FF8888" repeatCount="indefinite"/> </circle> </defs> <use xlink:href="#c" x="30" y="30"/> ...
こんなコードです
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200"> <style type="text/css"> .fillsample { fill: #44bfb7; } @media screen and (max-width: 400px) { .fillsample { stroke: #000; } } </style> <defs> <circle id="c" class="fillsample" r="30"> <animate attributeName="r" begin="0s" dur="7s" from="10" to="30" repeatCount="indefinite"/> <animate attributeName="fill" begin="0s" dur="7s" to="#FF8888" repeatCount="indefinite"/> </circle> </defs> <use xlink:href="#c" x="30" y="30"/> ...
width height 指定なし
Media Queries も あったり
SMIL アニメーション させてたり
こんなコードです
img 要素
img { width: 100%; height: atuo; }
<img src="sample.svg" alt="xxx">
<object type="image/svg+xml" data="sample.svg">
<img src="sample.png" alt="xxx">
</object>
object 要素
object { width: 100%; height: atuo; }
.bgsvg {
background: url(sample.svg) no-repeat 0 0;
background-size: auto;
}
CSS background
background: url('data:image/svg+xml;charset=utf8,
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 10 10" width="10" height="10">
<circle fill="orange" cx="5" cy="5" r="5"/>
</svg>');
こんなふうにも書けます
<!doctype html> <html> <body> <h1>inline svg</h1>
<svg viewBox="0 0 200 200"> <circle fill="#44bfb7" cx="15" cx="15" r="30"> </svg>
</body> </html>
inline SVG
Processing DEMO
ちなみに IE 11 では
img 要素でも 外部参照可
SMILアニメは まったく非対応
viewBoxの値が 拡大の最大値
width, height の指定がないと おかしい
「Referencing modes」と「Processing modes」は
まだ Working Draft なので、
各ブラウザでの表示仕様も揺れている現状
https://svgwg.org/specs/integration/#processing-modes
https://svgwg.org/specs/integration/#referencing-modes
img 要素object 要素 iframe 要素 CSS background
svg内にimage要素で埋め込んだ外部画像も表示される(第2世代まで?)
•svg 要素にwidth,heightが指定していない場合、background-position の指定を無視して縦横中央に配置される •svg 要素にwidth,heightが指定していない場合、repeat、background-size が効かない
media quer ies の適用が数値通りに適用されない
正常
ラスタライズなのでボケることあり
animete要素でのアニメーションがずれる
インラインSVG
正常 (原因不明のバグあり?)
正常
正常
svg 要素 に width, height 属性が指定してあると、CSS での width: 100%; height: auto; は無視される
正常
• svg の viewBox に指定した値までしか拡大できない • svg の子要素に transform 等が効かない
• animate要素でのアニメーションに対応していない(仕様) • CSS Animation も効かない
svg 要素 に width, height 属性が指定してあると、CSS での width: 100%; height: auto; は無視される
正常 (原因不明のバグあり?)
正常 (原因不明のバグあり?)
正常 (原因不明のバグあり?)
ちなみに、SVG のレンダリングは
IE が最も綺麗
• SVG 文書内のスクリプトは動作しない
• SVG 文書内に埋め込んだ外部ファイルは表示されない(IEを除く)
• SVG 文書内のハイパーリンクは無視される
• SVG 文書内のスクリプトも動作する
• 親 HTMLから、param 要素 や contentdocument を用いて SVG
DOM にアクセスも可能
• ただし、親である HTML 側にはイベントはバブリングしない
• SVG のすべての機能を使用できる
• 直接 SVG DOM を操作でき、親 HTML の DOM と連携可能
• 細かい表示がまだまだブラウザ間で違う点がある
img 要素
object 要素
インライン SVG
できること・できないこと
おすすめコード
img, object, iframe
• svg 要素には、viewBox 属性を必ず指定 • width, height はお好みで
CSS background
• svg 要素には、width, height, viewBox 属性が必須
inline SVG
• svg 要素には、width, height 属性を指定してはいけない
ちなみに、
Illustrator で SVGを保存時、
「レスポンシブ」をチェック
すると、svg 要素に width と
height 属性が指定されない
fallback
問題はこいつら
~8 ~2.3
object 要素で
<object type="image/svg+xml" data="sample.svg">
<img src="fallback.png" alt="xxx">
</object>
ただこの方法だと、sample.svg も fallback.png も読み込んでしまう HTTPリソースの無駄。
object 要素で
<object type="image/svg+xml" data="sample.svg">
<object data="fallback.png" type="image/png">
<p>xxx</p>
</object>
</object>
object 要素の入れ子なら解決できるけど…
インラインの image 要素で
<svg viewBox="0 0 96 96">
<image
xlink:href="sample.svg"
src="fallback.png"
width="96" height="96" />
</svg>
img 要素 + Modernizr で
if(!Modernizr.svg) {
$('img[src*="svg"]').attr('src', function() {
return $(this).attr('src').replace('.svg', '.png');
});
}
<img src="sample.svg" alt="xxx">
onerror イベントで
<img src="sample.svg"
onerror="this.src='fallback.png';">
background-image で
.element {
background-image: url(fallback.png);
background-image: url(sample.svg), none;
}
inline SVG の場合、foreignObject 要素を使う
<html>
<body>
<svg>
本来の SVG のコード …
<foreignObject display="none">
<img src="fallback.png"/>
</foreignObject>
</svg>
</body>
</html>
代替用の PNG 画像を用意するのが
そもそも面倒
svg2png
Gulp, Grunt のタスクとして、
指定したフォルダ内のSVGを
自動で PNG に変換
ただし、
svg要素に width, height の指定必須。
ないと余白が生まれる
https://github.com/akoenig/gulp-svg2png
https://github.com/dbushell/grunt-svg2png
svgstore
指定したフォルダー内の SVG を
ひとつの SVG にマージできる
SVG の CSS Sprite を自動で
生成できる
前頁の svg2png を併用すれば
CSS Sprite のフォールバックも可能
https://github.com/FWeinb/grunt-svgstore
https://github.com/w0rm/gulp-svgstore
アニメーション
大きく分けて
3種類
SMIL アニメーション
CSS アニメーション
SVG DOM アニメーション
SMIL アニメーション
<circle fill="#000" r="30">
<animate attributeName="r" begin="0s" dur="7s" from="10" to="30" repeatCount="indefinite"/> </circle>
SMIL Animation DEMO
• transition
• transform
• animation
• @keyframes
CSS アニメーション
SMIL アニメーション と CSS アニメーション
•SVG 2.0 において、SMIL アニメーションは廃止され、CSS animation、CSS transition 等と統合する方向で検討されている
• 詳細は、「W3C Scalable Vector Graphics (SVG) 2」「W3C Web Animations 1.0」にて
http://www.w3.org/TR/web-animations/
http://www.w3.org/TR/SVG2/
SVG DOM アニメーション
var logo = document.getElementById("logo");
var rot = 0;
setInterval(function(){
logo.setAttribute("transform",
"rotate(" + rot + " 100 100)");
rot = rot + 1;
}, 10);
SVG は独自の名前空間を持つため、 DOM Level 1 は使えない DOM Level 2 のメソッドを使用すること
createElement() createElementNS()
SVG DOM アニメーション
http://www.webbrowsercompatibility.com/svg/desktop/
Canvas と SVG どっち使う?
Canvas SVG
アニメーション 高速 やや低速
オブジェクト Context DOM
描画方式 ビットマップ ベクター
Web GL, Open GL ○ × (SVG 2から対応予定)
描画キャッシュ機能 ○ ×
DOM操作 × ○
SMIL アニメーション × ○ (ただし負荷高め)
アクセシビリティ × ○
SVG でのアニメーションは はっきり言って「低速」
•SMIL アニメーションは、特に Webkit で負荷が高い
• IE が SMIL・CSS のアニメーションに非対応
• よって必然的に JavaScript での DOM アニメーションになる
• DOM アニメーションでは、グラフィックアクセラレーターの恩恵を受けられない
• DOM 操作である以上、Reflow・Repaint の制約を受けるhttp://dresscording.com/blog/performance/layout_painting.html
SVG の魅力は、 Illustrator などで1枚絵を書き出したあと、 すぐに動かしたいパーツだけ動かせる
針だけ 動かせる
目だけ 動かせる
SVG の魅力は、 HTML における、SVG 以外の DOM オブジェクトや
CSS と連携できる
snap.svg を使う
http://snapsvg.io/
snap.svg DEMO
SVG と Adobe Illustrator
Illustrator CC 2014 Sketch 3Flash CC 2014
SVG(ベクター)なツールが充実してきた
やはり Illustrator が本命
Illustrator での注意点
• アートボードのサイズが、svg 要素の width, height, viewBox となる
• すべての単位は「ピクセル」で作る
• レイヤー は g要素となるが、日本語環境だと、id名が「レイヤー_1_」などと日本語そのままになるので、レイヤー名・グループ名は英数字で
• 「SVGフィルター」も同様。日本語になるので使わない
SVG 作成時の注意点
• 非表示のレイヤーなども「display: none;」で書き出される
• ブレンド、アピアランス、ブラシは、「アプアランスを分割」されて書き出される
• 画像ブラシはラスタライズされ、png ファイルが別途作られる
• 非表示にしたアピアランスは書き出されない
• アピアランスによっては、SVG のコードが XML として不正になる
• グラデーションメッシュをかけた図形は全体がラスタライズされ、png ファイルが別途作られる
• 乗算などの描画モードは無視されて書き出される
SVG 保存時の注意点
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00
Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/
1.1/DTD/svg11.dtd">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px"
width="70px" height="60px"
viewBox="0 0 70 60"
style="enable-background:new 0 0 67.7 63.5;"
xml:space="preserve">
×削除
×削除
×削除×削除
×削除
×削除
SVG 保存後のコードの修正
<g id="ハンバーガー_1_">
<path class="st0"
d="M38.1,0h-8.5C17.9,0,2.1,9.5,2.1,21.2v2.1c0,1.2,0.9,2.1,2.1,2.1h5
9.3c1.2,0,2.1-0.9,2.1-2.1v-2.1C65.6,9.5,49.8,0,38.1,0z
M2.1,59.3c0,2.3,1.9,4.2,4.2,4.2h55c2.3,0,4.2-1.9,4.2-4.2V55H2.1V59.
3z"/>
<path class="st1"
d="M4.2,46.6h59.3c2.3,0,4.2,1.9,4.2,4.2c0,2.3-1.9,4.2-4.2,4.2H4.2C1
.9,55,0,53.1,0,50.8C0,48.5,1.9,46.6,4.2,46.6z"/>
<path class="st2"
d="M4.2,38.1h59.3v8.5h-4.2l-6.4,6.4l-6.3-6.4H4.2V38.1z"/>
×要変更
日本語の id 名は修正すること
• title 要素 / desc 要素
• aria-*属性 / role属性
SVG のコードを最低限アクセシブルにする
<svg viewBox="0 0 200 200" aria-labelledby="title desc" role="img">
<title id="title">タイトルのテキスト</title>
<desc id="desc">説明テキスト</desc>
<a xlink:href="http://example.com" tabindex="0" role="link">
<rect width="75" height="50" rx="20" ry="20" fill="#90ee90"/>
<text x="35" y="30" font-size="1em">Website</text>
</a>
</svg>
Illustrator では以下のものは付与されないので自分で追加する
SVG を軽くするネタ
• 「パス → 単純化」などで、パス、アンカーの数は極力減らす
• 書き出し時の「小数点以下の桁数」を「0」や「1」くらいにする
• 同じ図形を複数回使うときは、シンボル登録してから配置する。
symbol 要素と use 要素によるモジュール化が行われる
• 逆に、1回しか使わないシンボル図形であれば
「シンボルへのリンクの解除」をしておいたほうがコードは少なくなる
• 非表示のレイヤーは削除しておく
SVG を軽くするネタ
• アピアランスの多用は、図形の要素が増えるだけなので控える
(しかも、defs や symbol によるモジュール化が行われない)
• CSSプロパティは「スタイル要素」にした方がスタイルが class 化
されるのでコードが少なくなる
(ただし、inline SVG などの場合は埋め込む先の HTML の CSS とバッ
ティングする可能であるのでこの限りではない)
• 保存時に svgz 形式にした方が軽くなるが、再編集性を考えると svg で
書き出しておき、Webサーバー側で gzip したほうがいい
(約60~80%軽量化可)
SVG を軽くするネタ
シンボルを効率的に利用する
defs, symbol, use 要素defs 要素、または symbol 要素 で実体のない図形を定義し、 それを use 要素で再利用できる
要素の再利用
<symbol id="s">
<path d="..."/>
</symbol><use xlink:href="#s" x="20"
y="10" fill="#fc0"/>
<symbol id="tw"> <path d="M64,6.2c-1.1,0.6-4.3,1.8-7.3,2.1c1.9-1,4.8-4.5,5.5-7.2c-1.9,1.2-6.1,2.9-8.2,2.9v0C51.5,1.6,48.2,0,44.4,0 c-7.3,0-13.2,5.9-13.2,13.2c0,1,0.1,2,0.3,2.9h0c-9.9-0.3-20.7-5.2-27.2-13.7c-4,6.9-0.5,14.6,4,17.4c-1.6,0.1-4.4-0.2-5.8-1.5 C2.5,23,4.7,29.1,12.7,31.3c-1.6,0.8-4.3,0.6-5.5,0.4c0.4,3.9,5.9,9,11.8,9c-2.1,2.5-10.1,6.9-19,5.5C6.1,49.9,13.2,52,20.7,52 c21.3,0,37.8-17.3,37-38.6c0,0,0,0,0-0.1c0-0.1,0-0.1,0-0.2c0-0.1,0-0.1,0-0.2C59.5,11.7,62.1,9.3,64,6.2z"/> </symbol>
<use xlink:href="#tw" x="20"
y="0" fill="#319aec"/>
<use xlink:href="#tw" x="40"
y="0" fill="#319aec"/>
<use xlink:href="#tw" x="60"
y="0" fill="#319aec"/>
<use xlink:href="#tw" x="80"
y="0" fill="#319aec"/>
defs 要素 と symbol 要素の違い
defs 要素
symbol 要素
• viewBox を定義できるため、単独での座標系を持つ
• つまり、use 要素で再利用する際にサイズを自由に変えられる
• Illustrator のシンボルは symbol 要素に変換される
• 図形要素をグルーピングして単にテンプレート化したもの
• 単独の座標系は持たず、再利用時にサイズは変更できない
松田直樹
ありがとうございました
SVG MANIAXScalable Vector Graphics
Ver. 2