プレゼンテーションとマルチメディア - 仕様書に見るHTML(3)

テーブルや画像、マルチメディアは現在のウェブづくりには欠かせない手段ですが、これらがHTMLに取り入れられたのは比較的最近です。実装状況にばらつきがあったりして正確な用法がいまひとつ分かりにくいこれらの要素タイプを、導入の背景も含めて少し詳しく紹介してみましょう。

1 HTMLのテーブルモデル

1.1 初期のHTMLとテーブル

WWWが誕生してからしばらくの間、HTMLにはテーブルは存在せず、データを「表」の形で示したいときには、pre要素などを利用して、空白文字でテキストを揃えるという方法が採られていました。テーブルモデルをHTMLに導入する試みは、初期のHTML拡張であるHTML+に遡ります。

This specification provides a superset of the simpler model presented in earlier work on HTML+. (B.5.1)

HTML+の1993年の草案では、基本的なテーブル要素が定義され、「表」が使えるHTMLの準備は整ったかに見えました。しかし、まず1995年にテーブルを持たないシンプルなHTML 2.0がRFC 1866として公開され、HTML+は正式な規格とならないままHTML3に向けての検討に引き継がれます。

HTML3のテーブルは、初期ドラフトの仕様がNetscape 1.1に採用されたりしますが、さらに検討を重ねて機能を追加したうえで、1996年にRFC 1942 "HTML Tables"として発行されました。しかし、HTML 3.0は規格自体が見送りとなり、当時の実状をまとめた形のHTML3.2が1997年1月にW3C勧告となります。ここでは、テーブルは結局Netscapeの実装と同等のシンプルなものが採用されました。

1997年12月に勧告されたHTML 4.0では、改めてRFC 1942をベースにした高機能なテーブルが導入されます。仕様書に

The HTML table model has evolved from studies of existing SGML tables models, the treatment of tables in common word processing packages, and a wide range of tabular layout techniques in magazines, books and other paper-based documents.(B.5.1)

と記されているように、文書システムとして実用になるレベルの表現力を備え、さらにアクセシビリティに配慮した機能が加えられているため、かなり複雑なものとなっています。

1.2 行、列のグループ化

テーブルの基本モデルは、お馴染みのtable, caption, tr, th, td要素を用いてセルと行を単位に構成するものですが、HTML4ではこれに行、列のグループという概念が追加されます。

Following the CALS table model, this specification allows table rows to be grouped into head and body and foot sections. This simplifies the representation of rendering information and can be used to repeat table head and foot rows when breaking tables across page boundaries, or to provide fixed headers above a scrollable body panel. (B.5.1)

CALSは一時日本でもビジネス用語として流行しましたが、ここでは1990年代初めに米国防総省で定められたSGML文書のテーブル書式を指しています。HTMLでの行のグループ化は、thead, tbody, tfootの3つの要素タイプを用いて行います。theadtfootが表計算やワープロでいうヘッダ、フッタに相当し、表の本体にはデータのグループごとにtbodyを設定するというものです。

次の例に示すように、tbody要素を用いることで都道府県(tr要素)を地方ごとにグループ化することができます。データ構造が明確になる上に、スタイルシートで背景色などを変えて視覚的な区別を付けることもできるので、大きなデータをテーブルで表現するときにはとても有益です。

HTML4のテーブルでは、CALSの仕様に倣い、フッタであるtfoot要素をtbody要素の前に記述します。長いテーブルのデータを全部読み込まなくてもウインドウの下部にフッタを表示できるようにするという機能が想定されているわけです。

しかし、tfoot要素を理解しない古いブラウザでは、この行がtbodyの前にレンダリングされてしまうため、この要素を使うのはなかなか勇気が要ります。CALSでもほとんど実装されずに非互換性が問題となったtfootが、HTMLで普通に使われるようになるには、まだ時間がかかりそうです。

(例)

<table>
 <caption>都道府県別人口などの統計</caption>
 <thead>
  <tr><th>都道府県</th><th>人口</th>...</tr>
 </thead>
 <tfoot>
  <tr><td>合計</td><td>126,686</td>...</tr>
 </tfoot>
 <tbody>
  <tr><td>北海道</td><td>5,695</td>...</tr>
 </tbody>
 <tbody>
  <tr><td>青森</td><td>1,475</td>...</tr>
  <tr><td>岩手</td><td>1,414</td>...</tr>
  ...
 </tbody>
</table>

1.3 列を示す要素と逐次表示

CALSやHTMLのテーブルは行を単位として記述するので、列という要素を直接マークアップすることはできません。しかし実際の表では、行揃えなどの情報を列単位で指定できないととても不便です。

この列情報を示すために、HTML4ではcol要素タイプが導入され、テーブル本体のデータの前に置くことで列に関するフォーマットなどを指定できるようになりました(CALSではCOLSPECという要素を用いていました)。

col要素にはidclass属性を与えてスタイルを設定することができますから、テーブルの表現力は一層高まります。さらに、小数点などの文字を基準にした位置揃えも指定できるようになり、他の文書アプリケーションの「表」により近づいています(ただし、文字揃えを示すalign="char"をまともに実装しているブラウザはほとんどないようです)。

複数列に同じ情報を与えるためには、span属性で列数を示します。また、colgroup要素を用いて列をグループ化することもできます(colgroup要素内にcol要素を含めるか、空の要素としてspan属性でグループ化する列数を示します)。どちらも複数列の情報を示すことができますが、col要素は構造上の意味を持ちません。

The COL does not group columns together structurally -- that is the role of the COLGROUP element. (11.2.4)

これらの要素は、列単位の情報を与えると同時に、テーブルを逐次表示させるためにも重要な役割を果たします。データ全体が届くのを空白状態で待つのではなく、転送されたところから順次表示してくのは、前回も紹介したとおり、HTML4の主要な狙いの一つです。

The HTML table model has been designed so that, with author assistance, user agents may render tables incrementally (i.e., as table rows arrive) rather than having to wait for all the data before beginning to render. (11.2.1)

テーブルは、列の数とそれぞれの幅があらかじめ分かれば逐次表示を行うことができます。そのため、colcolgroup要素(とそのspan属性)から列数を計算し、それぞれに指定されるwidth属性(もしくはスタイルシートのwidthプロパティ)で幅を確認できるようにすることが望ましいわけです。

もちろん、colcolgroup要素によって示す列数は、実際の列数と異なっていてはいけません。また、widthはブラウザによって実装が違ったりして扱いにくい属性(プロパティ)ですが、大きなテーブルの場合はできるだけ指定しましょう(ただし、ピクセル数などを絶対指定すると横スクロールを生じることがあるので、基本的に相対指定で)。

1.4 テーブルと罫線

HTML4のテーブルでは、表としての基本的な表現力をある程度充実させ、罫線の表示方法を属性で指定できるようになっています。

罫線を示す属性はframeborderrulesの三種類があります。それぞれの役割は、テーブルの外枠の表示方法、その太さ、およびセルを区切る罫線についての指定です。

rules="groups"という指定は、前の節で取り上げた行、列のグループ化に対応するもので、thead, tbody, colgroupなどの境目に罫線を引きます(仕様書ではcol要素単位でも罫線を引くとされていますが、これはgroupsの考え方として理解しにくく、ブラウザでも実装されていません)。

過去との互換性のために、これらの属性には次のような注釈が加えられています。

  • Setting border="0" implies frame="void" and, unless otherwise specified, rules="none".
  • Other values of border imply frame="border" and, unless otherwise specified, rules="all".
  • The value "border" in the start tag of the TABLE element should be interpreted as the value of the frame attribute. It implies rules="all" and some default (non-zero) value for the border attribute.

(11.3.1)

border="0"のみが指定されていれば、外枠だけでなくセルの境界も描かれません。border1以上の値があれば、framerules属性がなくても外枠、セル境界ともに描画します。最後の注釈は、HTML 3.0の初期ドラフトではborder属性がいわゆる“ブーリアン”属性(input要素のchecked属性などと同じ)として定義され、それに準拠した実装があることに対応するものです。HTML4対応のブラウザでは、<table border>は2番目の場合と同様に解釈されます。

frame属性の値
voidいずれの辺も罫線なし(デフォルト)
above上辺のみ罫線あり
below下辺のみ罫線あり
hsides水平方向(上下辺)のみ罫線あり
vsides垂直方向(左右辺)のみ罫線あり
lhs左辺のみ罫線あり
rhs右辺のみ罫線あり
box四辺全て罫線あり
border四辺全て罫線あり
rules属性の値
noneセル境界の罫線はなし(デフォルト)
groups行列のグループの間のみ罫線あり
rows行の間のみ罫線あり
cols列の間のみ罫線あり
all行列共に罫線あり(全てのセル枠)

ところで、罫線や列幅などは“見栄えに関する情報”なので、HTML4の考え方の原則に立てば、スタイルシートに委ねるべきなのではないでしょうか。

From the purist's point of view, the alignment of text within table cells and the borders between cells is a rendering issue, not one of structure. In practice, though, it is useful to group these with the structural information, as these features are highly portable from one application to the next. (B.5.1)

現実的なレベルでは、基本的な罫線程度の情報はHTMLでも指定できる方がデータの可搬性が高いという判断で、これらの属性がHTML4の仕様に加えられました。また、11.3節のノートにも記されているように、HTML 4.0仕様が勧告された1997年末にはまだCSS1しかなく、テーブルのためのスタイルプロパティが未整備だったという背景もあります。いろいろな考え方がありますが、純粋主義の人は、CSS2のスタイルシートを使って、これらの属性に頼らず視覚フォーマットを指定できます。

1.5 テーブルとページレイアウト

スタイルシートの話が出たところで、現在(2002年)のウェブデザインではまだ避けて通れない(かも知れない)テーブルによるレイアウトについて、仕様書の考え方を確認しておきましょう。

Tables should not be used purely as a means to layout document content as this may present problems when rendering to non-visual media. Additionally, when used with graphics, these tables may force users to scroll horizontally to view a table designed on a system with a larger display. (11.1)

ここでは、テーブルによるレイアウトの難点として、(1)音声合成による読み上げなど、視覚的にテーブルを表示しないブラウザでの問題;(2)グラフィックを配置するときに、画面サイズによって横スクロールが発生してしまう問題、の2つがあげられています。レイアウトにはスタイルシートを使うのが理想ですが、そうも行かない場合は、この2点に十分注意を払うべきです。

(1)については、参照文献にあげられている「ウェブコンテンツのアクセシビリティ指針」の「Guideline 5. Create tables that transform gracefully」にいくつかのヒントが示されています。ポイントとしては、

  • テーブルの内容をHTMLに記述された順番に読み上げていって理解できるようにする(視覚的には隣合うようにレイアウトしていても、HTMLとしては入れ子テーブルなどで全然無関係な位置に書かれることが多い)
  • レイアウト目的にテーブルの「意味的要素」を利用しない。たとえば中央寄せや太字というだけの目的でth要素を用いないということ

を頭に入れておきましょう。

(2)の横スクロールは、非常によく見かける問題です。たとえモニタは大きなサイズを使っていても、ブラウザのウインドウは画面いっぱいに最大化されているとは限りません。ミニノートやPDAの場合は言わずもがなです。widthには相対指定を用い、大きな画像と本文はテーブルを分けるなどして、「最悪!」といわれないデザインを工夫してください。

1.6 アクセシビリティとテーブル

非視覚系ブラウザでも理解できる「アクセシビリティ」の高いテーブルも、HTML4の重要な目標の一つです。アクセシビリティを高める機能としては

  1. tableタグのsummaryでテーブル全体を説明する
  2. セル(td要素)に対して対応するヘッダ(th要素)を示す情報を与える
  3. セルをカテゴリ化してヘッダと結びつける

といったものが提供されています。2.のためにはth要素にscope属性を与えるか、th要素にid属性で名前を付けて、それぞれのtd要素から対応するヘッダをheaders属性で指定するという方法を採ります。3.は、th要素にaxis属性でカテゴリ名を与え、2.の方法でセルとヘッダを結びつけます。

これらは音声ブラウザでもまだサポートされていないため詳細には踏み込みませんが、「表」は視覚的に表現されないと理解しにくいことが多いという点を念頭に置き、そのまま読み上げても意味が通るテーブルをつくるよう心がけてください。

(※これらの属性の詳細は、当サイト「テーブルとアクセシビリティ」を参照)

2 インライン画像を扱うimg要素

2.1 MosaicとIMG要素の誕生

ウェブが爆発的に普及する重要なきっかけが、1993年のMosaicブラウザの登場でした。Mosaicのβ版を次々に発表していく中で、開発者の一人であるマーク・アンドリーセンは2月25日に、www-talkメーリングリストに次のメッセージを投稿します。

I'd like to propose a new, optional HTML tag:
        IMG 
 ...

当時のブラウザでは、画像はリンクなどを通じて別ウインドウに表示されていましたが、MosaicはIMG要素を使ってインライン(埋め込み)表示するという新機能を世に問うたのです。この提案に対しては「埋め込みか外部ウインドウかを利用者が選択できる方がいいのではないか」「画像に限定せず音声などさまざまな対象を扱う方法を考えるべきだ」など多くの意見が寄せられますが、結局Mosaicは提案通りのIMG要素を実装して公開されました。

インライン画像の表示という機能は、WWWをマルチメディアの舞台として注目させ、大きな飛躍の原動力となります。その一方で、IMG要素は空要素であったため、画像が利用できない場合の代替表現に関する問題を残し、また音声、アプレット、プラグインなどの新しい表現が登場するたびに、そのための「タグ」が導入されるという結果となりました。

2.2 イメージと代替テキスト

img要素タイプのalt属性は、HTML 4.0で必須扱いになりました。代替テキストを与える習慣は徐々に広まりつつあるようですが(ですよね?)、そこにどんな文字列を記述するべきかということは、案外理解されていません。仕様書13.8では、2つのガイドラインが示されています。

その1:

Do not specify irrelevant alternate text when including images intended to format a page, for instance, alt="red ball" would be inappropriate for an image that adds a red ball for decorating a heading or paragraph. In such cases, the alternate text should be the empty string ("").

alt属性は「画像に代わって表示/読み上げされるテキスト」ですから、レイアウト用画像を説明しても意味がありません。飾りの画像にはalt=""を指定しておきます。

その2:

Do not specify meaningless alternate text (e.g., "dummy text"). Not only will this frustrate users, it will slow down user agents that must convert text to speech or braille output.

ロゴ画像にalt="logo"と設定したり、写真にalt="picture"と書き込んだりするケースは非常によく見かけますが、これをテキストブラウザや音声ブラウザで利用したらどうなるかを考えてみましょう。代替文字列をきちんと与えるには、さまざまな利用者を思いやる想像力が必要です。よく分からなければ、Lynxなどのテキストブラウザで実際の表示を確かめるなどの努力をしなければなりません。

3 さまざまなオブジェクトを扱うobject要素

3.1 マルチメディアとHTML

IMG要素が登場したときの議論の通り、その後HTMLはさまざまなマルチメディアオブジェクトを扱うようになり、そのたびにDYNSRCEMBEDAPPLETなどのあたらしい「タグ」が導入され、混乱と互換性の問題を引き起こしてきました。これらを整理し、将来出現する新しいメディアにも対応できる仕組みの検討が、HTML 2.0の制定直後に始まります。最初INSERTと呼ばれたこの要素タイプは、のちにOBJECTと名前を変え、約2年におよぶ検討を経てHTML 4.0に組み込まれました。

ブラウザでオブジェクトを扱うには、「誰が」「何を」「どうやって」を指示する必要があります。仕様書では、object要素がこのための3つの情報を与えると説明しています。

The OBJECT element allows HTML authors to specify everything required by an object for its presentation by a user agent: source code, initial values, and run-time data. (13.1)

これらの情報の与え方は複数の方法がありますが、data属性でデータを示し、type属性でそのメディアタイプを指定してブラウザに処理方法(コード)を判断させるのが簡単です。

<object data="sample.svg" type="image/svg+xml">Sample vector graphic</object>

ここで指定されているメディアタイプ(MIMEタイプ)は、Windowsのレジストリやブラウザの補助アプリケーションリストに登録されており、それぞれどんなコードでデータを処理するかを知ることができるのです。

指定タイプのオブジェクトを処理できないときは、ブラウザはobject要素の内容(ここでは文字列"Sample vector graphic")を表示します。ブラウザによっては、オブジェクトのサイズをwidth, heght属性で示さないとうまく表示できないこともあります。

3.2 データ、コードのさまざまな指定方法

オブジェクトのデータは主として前項のようにdata属性で指定しますが、これを初期化引数としてparam要素で与えるプログラムもあります。実際、object要素の最もポピュラーな用例であるFlashの場合、WindowsのIEではActiveXコントロールとして実装されているために、データをparam要素で渡します。ただし、その他の環境ではFlashはNetscape型のプラグインなので、param要素は用いません。従って、Flashムービーを埋め込むには

<object width="640" height="400" data="sample.swf" type="application/x-shockwave-flash">
 <param name="movie" value="sample.swf">
 Flashプラグインを<a href="...">ダウンロード</a>してご覧ください
</object>

という具合に、データを2通りの方法で記述する必要があります。

上記の例を見て、何か違うと思われましたか? Flashを埋め込むときに一般に使われるのは、

<object classid="clsid:D27CDB6E-..." width=...>

という、classid属性によるコード指定方法でしょう。object要素は画像からプラグイン、アプレットまで多彩なオブジェクトを扱うため、コードを示す方法も複数用意されています。その一つがclassid属性で、主としてJavaアプレットやActiveXコントロールのコードを、URIを使った“ユニバーサル名”で指定します。WindowsのIEでFlashを直接指定するにはclassid属性を用いますが、レジストリにこのclsidとメディアタイプの関連づけ情報が登録されているため、type属性だけでもブラウザはコードを実行できるわけです。

〔画面〕レジストリエディタを開いて、application/x-shockwave-flashを選択すると、CLSIDの値として{D27CDB6E-AE6D-11cf-96B8-444553540000}が登録されていることが分かる。

3.3 オブジェクトと代替要素

object要素はさまざまなメディアを扱うため、img要素以上に代替内容をきちんと示すことが重要です。新しいメディアは、ブラウザや環境によって対応状況が異なり、必ず表示できるとは限らないからです。

One significant consequence of the OBJECT element's design is that it offers a mechanism for specifying alternate object renderings; each embedded OBJECT declaration may specify alternate content types. (13.3.1)

object要素は入れ子にすることができます。ブラウザは外側から順番にそのメディアを扱うことができるかどうかを調べ、最初に見つかった処理可能なオブジェクトを表示します。単一の代替テキストだけでなく、最新メディア、画像、テキストリンクといった段階的な記述ができるので、よりきめ細かに異なる環境に対応することが可能になります。

(例)

<object data="sample.svg" type="image/svg+xml">
 <object data="sample.png" type="image/png">
  サンプルを用意しました。画像が表示できない場合は、
  <a href="sample.txt">テキスト版のサンプル</a>を参照してください。
 </object>
</object>

objectは単純な画像からプラグイン、アプレットまでを一手に引き受けようとしたため、仕様が複雑になり、実装もあまりうまく進んでいるとは言えません。しかし、SVGなど次々に登場する新しいメディアを柔軟に扱うためには、このような汎用要素はどうしても必要になってきます。シンプルなところからスタートして、今後のためにもobject要素の使い方を研究していってください。