| 説明 | リンクをグループ化する |
|---|---|
| 語源 | client-side image MAP |
| 所属モジュール | Client-side Image Map |
| 所属コンテントセット | Inline, InlineFormattable |
| 内容 | Heading, Block, area |
| 内容の書式 | ( Heading | Block | area )+ |
| 関連項目 | object, input, img |
| 公式な実装 | DTD |
| 属性 | 属性値の型 | 説明 |
|---|---|---|
| xmlns | URI (CDATA) |
XMLネームスペースを指定します。XHTML 1.1では、常にhttp://www.w3.org/1999/xhtmlです。 |
| id [必須] | ID |
この要素を識別する為の識別子を指定します。識別子は同一文書中で重複する事は許されません。 |
| class | NMTOKENS |
XHTMLに用意された要素では表しきれないものを分別する為に指定します。普通のユーザーエージェントはこの属性によって要素の意味を分別する事はできませんが、スタイルシートなどは処理する事ができるものもあります。 |
| title | Text (CDATA) |
タイトルを付けたり、補足説明を加えたりします。要素やブラウザによっては、ポイントされるとこの属性がツールチップなどとして表示される事もあります。 |
| I18N | [属性コレクション] |
国際化(Internationalization)に関する属性を集めたコレクションです。 |
| Events | [属性コレクション] |
基本的な組み込みイベントを処理する為の属性を集めたコレクションです。 |
固有属性はありません。
map要素は、リンクをグループ化します。特に、クライアントサイドイメージマップのリンクをグループ化します。クライアントサイドイメージマップ (クリックされた画像の座標から、リンク先をクライアント側で判断してジャンプする機構)に似たような機構にサーバーサイドイメージマップ (クリックされた画像の座標を送信し、リンク先をサーバ側で判断してジャンプする機構)がありますが、その詳細はServer-side Image Mapモジュールを参照して下さい。
クライアントサイドイメージマップは、サーバーサイドイメージマップよりも好まれます。理由は少なくとも二つ挙げる事ができます。
ジャンプ先をクライアント側で判断できないというサーバーサイドイメージマップの欠点は、必ずしも欠点であるとは限りませんが、ジャンプ先を意図的に隠す理由が無いのであれば、クライアントサイドイメージマップを使った方が良いでしょう。
クライアントサイドイメージマップを実現するには、幾つか手段がありますが、最もスマートに実現するのがこれです。object要素の子にmap要素を持たせ、map要素はa要素を孫に持つ事で領域を定義するというものです。
[プログラムコード開始]
[プログラムコード終了]
順を追って説明しましょう。まず、イメージマップとして使う画像はobject要素で表します。そして、その内容としてイメージマップのリンクを内包するmap要素を書きます。map要素は直接a要素を持てないので、Blockコンテントセットなどの要素(上記の例ではdiv要素)を使って一枚噛ませます。map要素の孫のa要素は、内容でラベル、href属性でリンク先を指定する他、 shape属性で領域の形状を、coords属性でその座標を指定します。map要素をobject要素の子にしただけではクライアントイメージマップとみなされないので、最後に usemap属性でmap要素のid属性値を参照します(つまり、必要があればmap要素をobject要素の外に出しても構いません)。
この方法は、アクセシビリティに関する問題を同時に解決します。
IE7がスマートな方法に対応していないのは、恐らく比較的新しい方法だからです。と言っても初出はHTML 4.0で、1998年に既に勧告になっているものです。
では(IEを重視してきた場合)従来はどうしていたかと言うと、HTML 3.2時代からあるimg要素とarea要素を使って領域を指定する方法を用いていました。下記は、それをXHTML 1.1の文法に則って書き直してみたものです。
[プログラムコード開始]
[プログラムコード終了]
大体同じですが、map要素の子のarea要素はalt属性でラベルを提供します。しかし、この方法にはアクセシビリティに問題があります。非グラフィカルブラウザには、等価な内容を提供できないのです。尤も、area要素のhref属性とalt属性から等価な内容のテキストアンカーをユーザーエージェントが自動的に生成できればいいのですが、今の所、文書の記述側がユーザーエージェントの開発側にそこまで求める事は難しいようです。
[プログラムコード開始]
[プログラムコード終了]
ただ、このような書き方をするくらいなら折衷案を採るべきでしょう。
将来的にはスマートな方法に移行するのが望ましいでしょう。下方互換性もいいですし、冗長にもなりません。しかしシェアの大半はスマートな方法を解さないIEによって占められていますので、それだけにすると大半の人がクライアントサイドイメージマップにアクセスできません。
こういう過渡的な段階を想定してか、map要素の内容には両者を混在させる事ができます。
[プログラムコード開始]
[プログラムコード終了]
map要素の内容にBlockコンテントセットなどの要素とarea要素を混在させた場合、area要素は全て無視されます。
この方法は、アクセシビリティを高め、同時にIE7などの古い (実際に古いもしくは対応が遅い)グラフィカルブラウザでも正しく解釈できるようにします。area要素が不要になれば、その行を消すだけで済むので、自動化も容易でしょう。
クライアントサイドイメージマップの領域が被った場合、文書中で先に現れた方が優先されます。
[プログラムコード開始]
[プログラムコード終了]
上記の例では、まずW3C precededが( 0, 0 )から( 340, 120 )までの矩形(長方形)を占めます。XHTML™ 1.1 recededは( 100, 35 )から( 440, 155 )までの矩形を占めようとしますが、その中で( 100, 35 )から( 340, 120 )までの矩形は既にW3C precededが占有しているので、XHTML™ 1.1 recededが取れるのは残りの部分(窪んだ六角形)となります。
href属性を持たないa要素や、代わりにnohref属性を持つarea要素は非アクティブ領域 (Inactive Zone)を作ります。非アクティブ領域はリンクを持たず、ポインタが上に乗っている状態でクリックなどをされても反応しません。
非アクティブ領域は、優先順位を考えて他のリンク領域に被せないと意味がありません。
[プログラムコード開始]
[プログラムコード終了]
まず、画像の中心に半径20ピクセルのリンク領域があります。その周りに半径100ピクセルの非アクティブ領域があり、更に画像全体を含むリンク領域があります。
順番に気を付けて下さい。優先順位は先に現れた方が高くなります。つまり、画像の中心から距離が20ピクセルまでの領域と、100ピクセル以上の領域はそれぞれ「中心」「外」というリンク領域になり、20ピクセルから100ピクセルまでの領域は「無効」という非アクティブ領域になります。
前述の通り、Windows Internet Explorer 7.0はスマートな方法をサポートしていないので、折衷案を使うのが現実的です。しかし、The page author is responsible for implementing the functionality defined in HTML 4.0 for a objects, if desired.(Quoted from
coords
)
なんて言ってますが、Microsoft側で実装する気は無いんでしょうか。
また、画像を表すobject要素が無視されます。代わりに中身は描画してくれるので、img要素で代用します。この時、map要素の内容はarea要素だけにするといいかも知れません。
しかも、object要素をBlockコンテントセットを内包できない要素の子にすると、そのobject要素がブロックレベル(Headingコンテントセット、Blockコンテントセット、Listコンテントセット)の要素を子孫に持った場合、内容の描画すら失敗します。回避するには、Flowコンテントセットを内包できる要素の子にするといいようです。
そして、恐らく全てをHTML 4.01 Transitionalと見なしているのだろうと思いますが、usemap属性の値の型がURIデータタイプでないとクライアントサイドイメージマップが有効になりません。という事は#に続けて断片識別子を書かなければならないのですが、 IDREFデータタイプでは文字'#'は許されません。つまり、XHTML 1.1の文法に違反します。
その他、coords="default"などにも対応していません。
Opera 9でも全てHTML 4.01 Transitionalと見なしているのか、usemap属性の値の型がURIデータタイプでないとクライアントサイドイメージマップが有効になりません。やはり#に続けて断片識別子を書かなければならないのですが、勿論 IDREFデータタイプでは文字'#'は許されません。そしてXHTML 1.1の文法に違反します。
また、map要素の内容にBlockコンテントセットなどとarea要素を混在させると、area要素を無視するのではなく、現れたのが遅いものを無視します(先に現れたものを優先しているとも言えます)。
Mozilla Firefox 2では、殆ど問題ありません。
が、Opera 9と同じように、map要素の内容にBlockコンテントセットなどとarea要素を混在させると、area要素を無視するのではなく、現れたのが遅いものを無視します。
完全にXHTML 1.1に適合した文書を書きたいなら、XHTML 1.1でクライアントサイドイメージマップはやるべきではありません。それでもXHTML 1.1を使って、IEやOperaなどでも認識されるクライアントサイドイメージマップを作りたいなら、文法違反を自覚しながら次のようなコードを書くと良いでしょう。
[プログラムコード開始]
[プログラムコード終了]
[プログラムコード開始]
[プログラムコード終了]
としてやれば良いのです。これを使うと、同時にobject要素の親がFlowコンテントセットを内包できない要素になっても描画が失敗しなくなります。尤も、サーバーサイドでもXSLTプロセッサを用意しなければならないでしょう。
ちなみに、XSLTも使えず、どうしてもobject要素の親をFlowコンテントセットを内包できない要素にしなければならない時、しかもIE7の面倒を見てやらないといけない時は、map要素の子として、BlockコンテントセットにもInlineコンテントセットにも所属し、なおかつ他の要素を内包できる要素──即ちnoscript要素を噛ませるという奥の手もあります……。
[プログラムコード開始]
[プログラムコード終了]
どうやらIE7は、親がInlineコンテントセットしか持てない要素でも、自分の子がInlineコンテントセットとして評価できれば満足するようです。つまりこのnoscript要素はIE7にしてみればInlineコンテントセットに見えているのです。勿論正しいユーザーエージェントはこれをBlockコンテントセットに評価する(map要素の内容にはInlineコンテントセットは無い)ので、Validatorでもエラーになりません。
しかし、これは本当に文法違反でないだけという感じです。自分で調べておいて何ですが、小手先の技巧です。こんな事をするくらいなら、area要素だけにするなり、テキストアンカーは別に用意するなりした方がいいでしょう。
解説を参照して下さい。
| [map] | ||
|---|---|---|
| Published | : | 2006-03-26T09:00:00+09:00 |
| Last Modified | : | 2007-07-27T17:40:27+09:00 |
| Table of Contents | : | 要素目次 |
| Index | : | 要素索引 |
| Verified with | : |
|