本項では図形の表示に関わる属性と,ポインティングデバイスによるイベントの発生について説明する.htmlよりも事細やかな設定が可能である.
本項では図形の表示に関わる属性と,ポインティングデバイスによるイベントの発生について説明する.htmlよりも事細やかな設定が可能である.
htmlでのcssと同様に要素の表示・非表示に関わる属性が提供されている.display属性及びvisibility属性がこれにあたるが,意味合いとしてはhtmlと同様である.display="none"
が要素そのものが(描画上)存在しないものとして扱われるのに対し,visibility="hidden"
は描画されないだけで描画領域は確保される.tspan要素においてその違いを確認できるだろう.どちらも似たような効果を持つが,カーソルイベント(click,mouseover,mousemove,mouseout等)の発生可能性に決定的な違いある.display="none"
の場合はカーソルイベントが一切発生せず,visibility="hidden"
ではpointer-events属性によるイベント発生条件が有効となる.
仕様をよく見るとdisplay属性の値にtable-row等のhtmlでの値が定義されていることに気がつくだろう.これはhtml5等による埋め込みsvgを考慮しているためで,スタンドアロンのsvgファイルにおいてはそれほど意味を持たないが,「none」を打ち消す値として「inline」が規定値として定められている.
htmlの同名のcssプロパティに慣れていると,この属性は図形の表示に関わる要素のみに有効と考えがちだが,svgにおいては直接図形を定義するわけではないlinearGradient要素やfilter要素などにも設定できる.この場合はその要素の持つ機能が無効化されてしまうので,思うような効果が得られない場合は祖先にdisplay:none
が設定された要素が存在しないか確認する必要がある.
htmlにsvgを挿入する場合,この文書のように複数箇所にグラフィックを挿入するケースはよく有ることだ.すると,文書の構造を分かりやすくするために,それぞれのsvg図形が共通的に用いる要素(例えばlinearGradientやpattern等)を一箇所にまとめたくなる.このような定義情報だけを格納したsvg要素はスクリーンに表示させる必要がないので,画面レイアウトへの影響を避けるために非表示としたいところである.が,ここで不用意にdisplay:none
を指定してしまうと困ったこととなる.実際に試してみよう.
この例ではdisplay="none"
で非表示としたsvg要素でグラデーション定義を行い,それを二つ目のsvg要素から参照している.
このようにグラデーションが無効化されていることが判る.linearGradient要素の機能をdisplay="none"
が打ち消してしまっているのだ.同様のことを今度はvisibility="hidden"
で行なってみよう.
visibility="hidden"
では要素の見た目が存在しないだけなので,問題なくグラデーションが表示されている.しかし,本来svgが存在している領域の分レイアウトにすきまが発生してしまう.ではどのようにするのがベストなのだろうか?例えばこのようにsvg図形のサイズを0としてしまう方法がある.
このように意図した通りの動作となった.この他にも位置を画面外に追い出してしまうとか,目に見える要素の背後に隠してしまうとか様々な方法が考えられる.また,svg要素のどれか一つに共通要素を詰め込んでしまうのも一つの手だ.但しこの場合はそのsvg要素が常に表示されていることが条件となる.display属性はhtml要素とsvg要素とを透過的に適用されるので,svg要素を含むdiv要素等にdisplay:none
が設定された場合に同様の問題が発生する.
この動作はインラインsvgがhtmlと同じdomツリー上に展開されることに依る現象であり,svgを使いこなす上での勘所なので是非憶えておこう.
cursor要素はカーソルを定義する要素であり,xlink:href属性でカーソルとしたい図形を指定する.一般に画像ファイルをカーソルとすることは可能だが,cursor要素を介することで通常画像の左上が基準となるポインターの位置を調整することが可能となる.現状chromeでのみ動作する.
cursor要素で定義したカーソルは図形要素のcursor属性から参照する.
カーソル画像が有効となる環境は限られているため,クロスブラウザでの動作が求められている場合は使わないほうが良いだろう.
カーソルの描画位置の調整例を示す.
インラインsvgで定義したcursor要素はhtmlから参照することもできるが,現状cursor要素で定義されたカーソル画像の描画位置の調整は無視されるようだ.
svgではpointer-events属性を指定することでポインターイベントを図形のどの部分で発生させるか制御できる.a要素におけるクリック可能判定,マウスイベントの発生条件に影響する.例えばfill=noneの場合,本プロパティを設定しないケースではイベントが発生しないが,pointer-events=all/fillを追加することで塗りつぶされていない領域でもイベントが発生するようになる.またvisibilityの状態によってイベントを発生させるかどうかを指定できる.chromeではイベントを発生させる領域の扱いが若干おかしい.
例を示す.pointer-eventsの設定により,カーソルをfill領域とstroke領域に乗せた際のhoverスタイルの適用が異なっていることが判る.
fill=noneの例.このように塗りつぶされていなくてもイベントを発生させることができる.
pointer-events=noneの使い方として重要なものに,キャプション文字列のイベント発生を回避するというものがある.下を例に取ると,「イベント発生」の部分にカーソルを合わせると,スタイルが変化してしまう.これはrect要素の描画領域が上に重ねられたtext要素によって隠されてしまっているためであり,このままではどこがクリック可能なのか判らず非常に使いにくい.この問題を回避するにはa要素内部にtext要素を挿入する方法もあるが,svgの構成上無理なケースもある.このような場合,text要素にpointer-events=noneを指定することで,描画内容を損なうこと無く下のrect要素にクリックイベントを伝達することが可能となる.