SVG を始めるためのベスト プラクティス

本記事は、マイクロソフト本社の IE チームのブログ から記事を抜粋し、翻訳したものです。 

【元記事】Best Practices for Getting Started with SVG2011/10/28 5:43 AM

SVG (スケーラブル ベクター グラフィックス) 形式の Web グラフィックスは、さまざまな大きさのデバイス上で、ビットマップ形式のグラフィックスより高品質に表示することができます。また、SVG はそもそもアクセシビリティに優れており、ユーザーが操作するグラフィックス、テキストを含むグラフィックスに最適です。

Web での SVG の使用は、増え続けています。先週の SVG Open 2011 では、実際にさまざまなアプリケーションで SVG を活用している Web 開発者に会って、話を聞くことができました。

SVG を活用しているアプリケーションとしては、データから生成されるグラフ、製図、ゲーム、ユーザーが操作可能な説明図、データの地図的表現などがあります。

SVG の仕様自体は、誕生から 10 年になろうとしていますが、HTML 5 仕様が策定されるまで、SVG を HTML のインライン要素として使用することはできませんでした。ブラウザーが HTML5 の一部として SVG をサポートするようになることで、それまでプラグインを使わなければ利用できなかった Web エクスペリエンスが、次世代の Web では SVG を使用して実現できるようになります。

SVG は、HTML マークアップ、CSS、HTML DOM、JavaScript に簡単に統合できるため、インタラクティブで統合されたエクスペリエンスを構築しようとする場合に最適な選択肢であり、さまざまなフォーム ファクターに合わせてスタイル設定したり調整したりすることが可能です。また、SVG は、HTML を使用した Windows 8 Metro スタイルのアプリケーションの構築に適した唯一の宣言型ベクター グラフィックス テクノロジでもあります。

今回は、HTML5 Web サイトで SVG を使用する際のアイデアと、これから SVG を始めようとするときに役立つベスト プラクティスをいくつか紹介します。

HTML5 の SVG が役立つ場面

HTML5 の宣言型グラフィックス形式である SVG に想定されている用途としては、拡大縮小が必要な画像、選択可能なテキストを含む画像、動的でインタラクティブな画像、CSS を使用してスタイル設定できる画像があります。(HTML5 での手続き型 2D グラフィックス要素 <canvas> と SVG との比較については、「Canvas と SVG の使い分けに関する考察」を参照してください)。

拡大縮小可能なグラフィックス

グラフィックスは、さまざまな場面で、さまざまなメディアを通して使用されます。SVG がすばらしいのは、どのような解像度でも精度を維持できる点です。これは、さまざまな種類のデバイスや高品質な印刷に対応する場合に重要です。

たとえば、次の W3C HTML5 ロゴからわかるように、SVG はロゴに最適な形式です。

HTML5 logo at different sizes
さまざまなサイズの W3C HTML5 ロゴ

選択可能なテキスト

テキストを含む画像には、ラスター画像よりも SVG の方が適しています。グラフや図表が、このカテゴリに含まれます。

拡大縮小が可能というだけではなく、グラフや図表内のテキストがテキストとして保持されます。テキストであれば、コピー、貼り付け、検索が可能で、簡単に更新ができます。

装飾文字を使う画像ヘッダーの場合も、SVG は有力な選択肢となります。WOFF フォントと、テキスト ストロークやグラデーション/パターンによる塗りつぶしを組み合わせてテキストをカスタマイズできますが、テキストは選択可能なまま維持でき、検索エンジンのインデックスとしても有効な状態に保てます。

たとえば、フローチャートは大半がテキストで構成されますが、テキストはその画像を検索するための語句としても利用できます。

次の図に示すように、SVG の図の中にあるテキストは選択できます。他のテキストと同様に、コピーすることもでき、検索エンジンのクロール対象にもなります。さらに、IE のアクセラレータと組み合わせて使用することもできます。

SVG flowchart showing selected text
テキストが選択できるフローチャート

動的でインタラクティブなグラフィックス

動的でインタラクティブなグラフィックスとしては、ゲーム、地図、グラフ、座席表などがあります。インターネットを利用していてよく見かける SVG の利用として、Bing や Google の地図での機能があります。たとえば、ルート案内の機能では、ルートを示す SVG の青い線がラスター画像の地図上に表示されます。SVG はクライアント側のスクリプトから生成することができるので、地図上のルートのように、既存の画像に少量の追加を行う場合に適しています。SVG は DOM のサポートが充実しているため、画像の動的な変更にもきわめて適しています。データが変更されるたびに、ブラウザー内でグラフを更新することができます。DOM を変更することで、図形を移動したり、図形のサイズや色を変更したりできます。また、SVG のヒット テスト機能により、図形に対する正確な操作を実現できます。SVG 要素には、HTML 要素とほぼ同様にイベント ハンドラーを設定することができます。ただし、HTML 要素と異なる点は、マウス イベントが図形上のマウス操作だけで発生し、境界ボックスの四角形全体が対象になるわけではないということです。

Map showing SVG driving directions overlay
運転のルートを示す地図: ベースの地図はビットマップ画像で、ルートが SVG でオーバーレイされている

CSS による書式設定

CSS でコンテンツをスタイル設定できることが、SVG を採用するもう 1 つの大きな理由です。

SVG の図は 1 つ 1 つすべてが DOM に反映され、それぞれに、各図形の外観などグラフィックスに関するすべての情報が含まれています。このため、各図形のスタイル情報の更新は簡単に行えます。

UI 要素にも SVG を使用すると良い点があります。四角形以外の図形を使用することができ、外観をカスタマイズできます。

図形に対して、塗りつぶし、ストローク、不透明度を変更できますが、これには新しいスタイルシートやスクリプトを使用できるほか、:hover のような擬似セレクターを使うこともできます。

このような SVG の利点は、すべてを並行して利用できます。

たとえば次の図は、時間の経過によって変化するデータを示す地図のグラフィックスです。この図は、拡大縮小しても崩れないだけでなく、年によるデータの変化を複数のスタイルシートを使って表しています。

この地図では、州の色だけが変更されています。各州は、<path> 要素で表されており、郵便番号に対応する id が指定されています。この id の CSS セレクターを使用して、図形を塗りつぶす色がスタイルシートで指定されています。年を切り替えると、それぞれのスタイルシートが適用されます。

選挙地図では、このような色分けがデータの傾向を表すためによく使用されています。更新の激しい選挙速報を、ごくわずかなグラフィックスの変更だけで伝える、といった利用法が容易に思い浮かぶはずです。このような更新は単純で、わずかであり、他に影響を与えずに行うことができます。

年によって異なるデータを表示する、米国の区域別統計地図

これから始めるためのベスト プラクティス

SVG と HTML は似ているのですが、よくしてしまう間違いがいくつかあります。しかしこれらは簡単に回避できます。よくありがちな間違いを以下に紹介するので、問題の調査に長い時間を費やさなくても済むようにぜひ参考にしてください。

HTML5 DOCTYPE

HTML5 において SVG をインラインで使用する場合は、HTML5 DOCTYPE<!DOCTYPE html> を使用していることを確認してください。これは、HTML5 の要件です。適切な DOCTYPE を指定していない場合、IE9 または IE10 では、開発者が想定するドキュメント モードでページがレンダリングされず、結果として、SVG コンテンツが表示されなくなります。HTML5 DOCTYPE の指定を忘れないようにしてください。

オーバーフローの既定動作

<div> などの他の HTML 要素と同様、最上位のインライン <svg> 要素のオーバーフローの既定動作は visible です (これは、XHTML の <svg> 要素の既定動作とは異なります。XHTML での既定動作は、"overflow: hidden" です)。この既定動作は、<svg> 要素の境界ボックスの外にはみ出す SVG コンテンツが表示されることを意味します。場合によっては、これが予期しない動作につながることもあるでしょう。この現象に対処するには、<svg> 要素の SVG 属性で overflow="hidden" を指定するか、ドキュメントの CSS ブロックに svg { overflow: hidden; } を指定してください。

SVG element with default overflow SVG element with overflow=hidden
<svg> 既定のオーバーフローでは表示される <svg overflow="hidden"> はみ出した SVG コンテンツは表示されない
テキスト ベースラインの既定の位置

SVG を手動で作成している場合、<text> 要素および <tspan> 要素の y 属性がテキストのベースライン (文字の底部) を参照していることに気付いていないことがあります。y 属性を指定しない場合、テキストは、そのテキストが含まれる画像に対して y=0 の位置に配置されます。これは、テキストのベースラインを SVG コンテナーの最上部に配置することを意味するので、上記の overflow="hidden" を指定していると、テキストが表示されません。テキストが表示されない場合は、y 属性に正の数値が指定されているかどうかを確認してください。

SVG text element default y attribute SVG text positioning with the y attribute specified
<text> (default y=0) <text y="25">
アクセシビリティ

グラフィックスに完全なアクセシビリティを確保するのは困難ですが、SVG では個々の SVG グラフィックス要素や要素のグループに対して説明テキストとタイトルを追加できます。

このため、SVG では、HTML の <img> 要素に alt テキストを指定するよりも、アクセシビリティをはるかに強化することができます。

テキスト コンテンツは、マークアップを追加しなくてもそのままスクリーン リーダーで読み上げることができます。

グラフィックス要素の場合は、その図形やグループの子要素として <title> タグと <desc> タグを追加しておくことで、スクリーン リーダーはその説明テキストにアクセスできます。HTML <img> 要素の title 属性と同様、SVG の title 要素も、その図形にマウスを合わせると、ヒントとして表示されます。

次の例は、単純な図形の <title> 要素を示しています。

<?xml version="1.0" encoding="UTF-8"?>

<svg xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" width="500" height="300" viewBox="0 0 500 300">

<title>Abstract Art</title>

<style type="text/css">

/*<![CDATA[*/

.c0, .c1, .c2 { fill-opacity: 1; fill-rule: evenodd; stroke-dasharray: none; stroke-linecap: round; stroke-linejoin: round; stroke-miterlimit: 4; stroke-opacity: 1; stroke-width: 10px; }

.c0 { fill: #e3caad; stroke: #4e320e; }

.c1 { fill: #bc9dc9; stroke: #4b1268; }

.c2 { fill: #2cec7d; stroke: #2c9549; stroke-linecap: butt; stroke-linejoin: miter; }

/*]]>*/

</style>

<rect class="c0" width="131.429" height="168.571" x="37.143" y="40.934">

<title>Toast</title>

</rect>

<g>

<title>Bunch of grapes</title>

<path class="c2" d="M314.286,78.076 340,15.219 428.571,26.648z">

<title>Grape Leaf</title>

</path>

<circle cx="270" cy="100" r="20" class="c1" id="grape"/>

<use xlink:href="#grape" x="40"/>

<use xlink:href="#grape" x="80"/>

<use xlink:href="#grape" x="20" y="35"/>

<use xlink:href="#grape" x="60" y="42"/>

<use xlink:href="#grape" x="38" y="80"/>

</g>

</svg>

Image fallback of toast and grapes

さらに、focusable 属性を使用すれば、これらの説明テキストにキーボードでアクセスすることも可能になります。focusable="true" を指定すると、その要素にタブ キーで移動できるようになります。これにより、キーボードを中心に使用するユーザーは、簡単に図形にフォーカスを合わせ、アクセシビリティ ツールから情報を取得することができます。また、これらの要素間をタブで移動すると、focusin イベントと focusout イベントが発生します。

MIME の種類

SVG を独立したファイルとして提供する場合、適切な MIME の種類でファイルを提供するようにサーバーが構成されていることを確認してください。SVG の正しい MIME の種類は、image/svg+xml です。image/svg-xml と混同しないようにしてください。Adobe SVG Viewer ではこの設定が受け入れられることから、既存のコンテンツの一部では、この誤った MIME の種類が使用されている場合があります。正しい MIME の種類を使用していることを確認してください。

SVGZ ファイル

上記に加えて、圧縮 SVG を使用している場合は、SVG ファイルのヘッダー応答に Content-Encoding: gzip という行を入れる必要があります。gzip でエンコードされた他のファイルと同様、このヘッダー応答行が必要です。

拡大縮小: viewBox と preserveAspectRatio

グラフィックスを自由に拡大縮小するには、最上位の <svg> 要素に viewBox 属性を指定します。viewBox が指定されている場合、グラフィックスの高さと幅を変更すると、SVG 画像は一部が切り取られるのではなく、拡大縮小されます。

preserveAspectRatio 属性も、SVG 内にある画像の拡大縮小を制御するのに使われます。この属性の構文は、preserveAspectRatio="align meetOrSlic" です。align パラメーターと、 "meet" "slice のどちらかを指定する meetOrSlic パラメーターの2 つで、画像が含まれる <image> 要素内に画像をどのように収めるかと、そのコンテナー内のどこに画像を配置するかを指定します。preserveAspectRatio="none" を指定すると、SVG の <image> 要素は次の図のように、HTML の <img> 要素と同じように動作します。

Photo of two giraffesPhoto of two giraffes scaled to fit odd container
左: 本来の縦横比の画像、右: preserveAspectRatio="none" を指定して、200 x 81 のコンテナーにサイズを合わせた同じ画像

preserveAspectRatio を "none" 以外に指定した場合に注目して説明します。"none" 以外を指定することで、縦横比が画像自体と異なるコンテナー内に、画像をどのように配置するかを制御できます。meetOrSlice パラメーターは、画像をコンテナー内に収まる大きさにする (meet) か、コンテナーを完全に埋めるまで大きくする (slice) かを指定します。align パラメーターは、コンテナー内で画像をどこに配置するかを指定します。min、mid、max の 3 つのオプションを、x、y の各方向に指定します。これらを組み合わせて、次の 9 種類の配置方法が利用できることになります。

  • xMinYMin – コンテナーの左上角に画像を配置
  • xMidYMin – コンテナーの中央上部に画像を配置
  • xMaxYMin – コンテナーの右上角に画像を配置
  • xMinYMid – コンテナーの左中央に画像を配置
  • xMidYMid – コンテナーの中央中心部に画像を配置
  • xMaxYMid – コンテナーの右中央に画像を配置
  • xMinYMax – コンテナーの左下角に画像を配置
  • xMidYMax – コンテナーの中央下部に画像を配置
  • xMaxYMax – コンテナーの右下角に画像を配置

以下の例に、各配置方法によって画像がどの位置に表示されるかを示します。align は、x か y のいずれかの方向にのみ効果があることに注意してください。もう一方の方向は、画像がコンテナーをすべて埋めているため、min、mid、max は意味がありません。

xMin Example of preserveAspectRatio=
xMid Example of preserveAspectRatio=
xMax Example of preserveAspectRatio=
YMin YMid YMax
Example of preserveAspectRatio= Example of preserveAspectRatio= Example of preserveAspectRatio=

meetOrSlice = "meet": 画像とコンテナーの縦横比が異なる場合、コンテナー内に画像全体が表示されるよう縮小され、空白が生じる

xMin xMid xMax
Example of preserveAspectRatio= Example of preserveAspectRatio= Example of preserveAspectRatio=
YMin Example of preserveAspectRatio=
YMid Example of preserveAspectRatio=
YMax Example of preserveAspectRatio=

meetOrSlice = "slice": 画像とコンテナーの縦横比が異なる場合、コンテナーを完全に埋めるように拡大され、画像が途中で途切れる

SVG の preserveAspectRatio プロパティでは、コンテナー内での画像のサイズ調整の方法と配置場所の両方を定義して制御できます。preserveAspectRatio="none" を使用すると、HTML と同じ動作になります。

スクリプト: SVG DOM と Core DOM

getAttribute() メソッドと setAttribute() メソッドは、DOM Core 仕様に由来するもので、SVG を含めて HTML にも XML にも同じように適用されます。

これらのメソッドは、要素の属性を変更する方法としてよく知られ、使いやすく、一貫性があります。変更する属性の種類にかかわらず、setAttribute(attribute, value) はいつでも使用できます。

ただし、SVG DOM を利用した方がパフォーマンスを向上できることがよくあります。

SVG は独自の DOM をサポートし、多数の属性値とメソッドを公開しています。SVG DOM の性質からして、SVG DOM の属性値を変更するには、setAttribute() を単に使用するのに比べて、多くのことを学習する必要があります。しかし、SVG DOM では属性値に直接アクセスできるので、パフォーマンスの向上と、より単純な値操作という両方を実現できます。

たとえば、次の関数は setAttribute() を使用して、円形要素の半径を 2 倍にします。

function doubleCircleRadius(circle) {

circle.setAttribute("r", 2 * parseFloat(circle.getAttribute("r")));

}

これに対し、SVG DOM では同じ効果を次のようにして実現できます。

function doubleCircleRadius(circle) {

circle.r.baseVal.value *= 2;

}

Core DOM の setAttribute() メソッドと getAttribute() メソッドでは、値を操作する際に多くの場合、値の解析が必要になります。SVG DOM を使用すると、既存の値に基づいて値を変更することが簡単になります。

SVG DOM では、文字列で操作するのではなく、属性に直接アクセスします。このため、値の型に注意する必要があり、スクリプトの作成が複雑になる場合があります。

次の表は、よく使用されるいくつかの属性にアクセスする一般的な方法を示しています。

値の "型" 属性の例 DOM アクセス
プレゼンテーション属性 fill, stroke elem.style.fill
長さ r, width, height, cx, cy, x, y elem.r.baseVal.value
オブジェクト viewBox elem.viewBox.baseVal.x elem.viewBox.baseVal.y elem.viewBox.baseVal.width elem.viewBox.baseVal.height
リスト transform, d elem.transform.baseVal.getItem(0);

SVG DOM インターフェイスについては、SVG 仕様の各章の末尾に記載されています。

ツールとライブラリ

SVG には可読性があり、手動で作成できますが、その大部分は視覚的な要素です。目に映るグラフィックを図形の数学的表現に直観的に変換できることはあまりありません。現在、既に普及しているベクター デザイン ツールを使用すると、静的な SVG 画像を簡単に作成できます。

Inkscape はその 1 つで、無料でダウンロードできます。

Adobe Illustrator は、プロの Web 開発者がベクター画像の作成によく使用するツールで、SVG 形式でファイルを保存できます。

Microsoft Visio にも SVG 形式でエクスポートする機能があります。これは、会社で使う図やフローチャートの作成に特に適しています。ただし最適化が重要視されるような場面では、これらのアプリケーションは SVG を最も単純な形式で出力するわけではないという点に注意してください。

出力にはそれぞれのアプリケーション特有の名前空間要素や属性が含まれており、データを繰り返し編集する段階では便利ですが、最終的に実稼働環境で使うグラフィックスとしては適切でない場合があります。ファイル サイズを縮小したり、スタイル設定を容易にしたりするためには、余分なマークアップの削除が必要になることがあります。

Inkscape 以外に無料で使用できる SVG エディターに SVG-edit があります。これは、JavaScript による SVG エディターで、ブラウザーを使用して SVG を作成します。最新のアルファ バージョンには優れた機能がいくつかあります。ぜひ IE9 でお試しください。

IE9 では、SVG フォントの代わりに、WOFF フォントがサポートされています。WOFF フォントは、HTML と SVG の橋渡しをするもので、SVG を学習する負担を軽くし、SVG を HTML の一部として統合します。これにより、HTML と SVG の両方のコンテンツに、同じカスタム フォントを適用することが容易になります。SVG フォントに関する知識が既にある場合、Font Squirrel を使用すると、SVG フォントを WOFF 形式に変換することができます。

よくある問題としては他に、SVG に対応していない旧バージョンの IE のサポートがあります。Web 上の各種 SVG ライブラリの多くは、旧バージョン向けのサポートを提供しているので、このための詳細な処理を開発者が行う必要はありません。RaphaelJS は、旧バージョンの IE で VML を表示できる、最もよく知られたライブラリの 1 つです。Highcharts のような、旧バージョンをサポートするグラフ作成ライブラリも、Web には多く存在しています。

これらは、SVG を始める際に役立つ基本的なリソースの一部に過ぎません。既存のツールやライブラリは、大きく 2 つに分類されます。(1) 静的で、独立した SVG コンテンツを作成するためのものと、(2) スクリプトで実行したり作成したりする動的な SVG をプログラミングするためのものです。どちらも自分のツールボックスに用意しておきたい存在です。Web 上の SVG の世界を切り開いてみましょう。そこには大きな可能性があるはずです。

今後のステップ

SVG の使用方法 (例 1例 2例 3例 4) は既に紹介されています。ここに示した利点やいくつかの実用的なヒントを使用すれば、序盤のつまずきは回避できます。SVG を実際に試し、自分の HTML5 Web サイトでどのように活用できるかをご検討ください。実際に作成したサイトや、他のライブラリへのリンクをぜひお寄せください。お待ちしております。

—Jennifer Yu (プログラム マネージャー、Internet Explorer グラフィックス)