frameは本当に便利かフレームは実に多くの個人サイトで用いられています。確かにメニューなどを固定すれば利便性が高まる時もあります。しかしそれが絶対便利だと言い切れますか?どうせ使うなら正しく、デメリットも知った上で使ってみませんか?また、ここではフレームを他の技術で代替する方法も少し模索してみたいと思います。
このコンテンツの例文は全てHTML4 Framesetの例です。XHTML 1.0 Framesetを利用している方は空要素等に注意を払う必要があります。また、例文中のhead要素に記述された内容は不足気味です。
フレームを使う方は大抵次のような理由で使っているようです。
また、フレームを使う事で本来HTMLの内容としては不適なナビゲーションを本文中に書かなくて良くなります。(文書の関連性を示すのはlink要素の役割です。詳細は当サイトの「linkのススメ」をご覧下さい。)しかし、そのフレームには欠点も多くあります。例えば次のような事です。
現在W3Cで論議されているXHTML2.0にはnl要素型というナビゲーションの為のリスト(Navigation List)が導入されるかもしれません。そうなれば多少話は変わってくるでしょう。(個人的にはこの要素型自体がおかしいように思いますが。)
勿論「ナビゲーション部を1つのファイルで共有できるので維持が楽」というメリットがあるのは前述した通りです。ここで追加するのはそんな立派なナビゲーションではありません。「トップページ」へのリンクと「メニュー」へのリンクです。「メニュー」はフレームに読み込む物と兼用にしても良いでしょう。
トップページへのリンクがあれば、偶々「フレームに読み込まれるはずのページ」に来た訪問者をトップページ(すなわちフレーム付きの文書)に誘導する事が出来ます。また、メニューへのリンクがあればフレームに対応していないブラウザでも(少々不便とはいえ)閲覧する事ができます。
このように改善しても結局リンクはしにくいままです。しかし不便さを最小限に抑える事は出来るでしょう。
noframes要素は重要ださて、この要素きちんと使っていますか?「そもそもフレームに対応していない時代遅れな(?)ブラウザを使ってる奴が悪いんだ」なんて言ってはいけません。大半の検索エンジンは要約文を提供しています。閲覧者はその要約文からそのページが自分にとって有用かを判断するでしょう。が、noframes要素に「フレーム対応ブラウザでご覧下さい。」などと書かれていると全く参考にならない文になってしまいます。試しにいくつかの検索エンジンの要約文を見てみましょう。
一部の検索エンジンを除いて要約文が「フレーム対応の……」といった具合の参考にならない文になってしまっています。きちんとnoframes要素の中に代わりになる文を書けばこうはなりません。例えば次のような文書があったとします。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head><title>なんとかかんとかのページ</title></head>
<frameset cols="150,*">
<frame src="menu.html" name="left">
<frame src="main1.html" name="right">
</frameset>
<noframe>このページはフレームを使用しています。フレーム対応ブラウザでご覧下さい。</noframe>
</html>
このような記述は非常に多くのサイトで見られます。この記述には基本的な文法事項に2つ間違いがあります。まず、noframes要素はframeset要素の直下に記述するものです。しばしば先程の例のようにhtml要素の直下に書かれますが、これは間違いです。
もう1つはnoframeではなくnoframes要素だと言う事。複数に分けられたウィンドウの代替ですからnoframesは複数形です。これら2つはよく間違われますので気をつけましょう。
では本題のnoframes要素を見てみましょう。多くのサイトにはこの様に「追い返す」為の文が書かれています。果たして追い返すべきなのでしょうか。次のようにmenu.htmlへのリンクを準備するだけで、そのリンクとUAの持つ「戻る」機能を駆使する事で閲覧者は情報を得る事が出来ます。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head><title>なんとかかんとかのページ</title></head>
<frameset cols="150,*">
<frame src="menu.html" name="left">
<frame src="main1.html" name="right">
<noframes>
<body>
<h1>なんとかかんとかのページ</h1>
<ul>
<li><a href="menu.html">サイトメニュー</a></li>
<li><a href="main1.html">トップページ</a></li>
</ul>
</body>
</noframes>
</frameset>
</html>
noframes要素の中にはフレームとして読み込むページへのリンクを記述するのが普通です。そうすれば一応全てのページへアクセスする事ができますからね。
尚、「フレーム対応ブラウザの紹介」をnoframes要素の中に書いているサイトを見かけますが、既に時代遅れでしょう。紹介された物を使ってまでそのサイトにアクセスしようと思う人は少ないでしょうし、そもそもその紹介された物を使いたくても使う事ができないのかもしれません。
noframes要素noframes要素には2つの種類があります。当サイトの「ブロック要素とインライン要素の違い」での説明を以下に引用します。(実のところ解決方法はこの中に簡潔にまとめられています。)
noframes- ここではTransitionalで定義されている
noframes要素を解説します。決してnoframeではありません、複数形です。これはフレームが無効だった場合に表示される代替文書です。この中身はフレームに非対応のUAがフレーム内部に使われているページを直接表示した際に表示されます。Framesetで定義されるnoframes要素も参照してください。(一般によく使われるのはFramesetに定義されるnoframes要素です。)- この要素は
body要素の直下にのみ含まれます。フレームに記載した他コンテンツへのリンクを記述するのが良いでしょう。- ブロック要素、インライン要素の両方を含める事が出来ます。
noframes(Frameset)- frameに非対応のUAに対して表示するテキストです。HTML4 FramesetとXHTML 1.0 Framesetでのみ定義されています。この要素は
frameset要素の直下に含みます。html要素の直下に書いている人を見かけますが、間違いです。また、Transitionalで定義されているnoframes要素とは根本的に異なるものです。適宜そちらも参照してください。- この要素の中には丸ごと一つの文書が記述されます。(勿論
noframes要素を含むことは出来ませんが。)しばしば「フレーム対応ブラウザでご覧下さい」などと書かれますが、好ましくありません。まして「フレーム対応ブラウザはこちらから入手してください」なんて書いてあったら最悪です。(そんなことは知っていて使っている可能性が高いですから。)面倒かもしれませんが、きちんと代替文書となりうるテキストを含めましょう。もしメニューフレームが存在するならとりあえずメニューとなりうるリンクを羅列しておくのがいいと思います。そして各ページにもTransitionalで定義されているnoframes要素を用いてメニューを書いておけば完璧です。
要するに先ほど説明したnoframes要素というのはFramesetで定義されるnoframes要素と言う事になります。ここではTransitionalで定義されるnoframes要素について解説します。
このTransitionalで定義されるnoframes要素はframe非対応の環境だけに有して欲しい情報を記述する際に使います。例えば次のようにナビゲーションに用いる事が考えられます。
<body>
<h1>ページのタイトル</h1>
<p>このページのメインコンテンツな部分</p>
<noframes>
<p><a href="menu.html">メニュー</a>へ戻る</p>
</noframes>
</body>
しかし前述の通り、偶々「フレームに読み込まれるはずのページ」に来た訪問者にもナビゲーションを提供する必要があります。トップページへのリンクは最低限でも準備しなくてはならないでしょう。それを踏まえてもう一度書き直してみます。
<body>
<h1>ページのタイトル</h1>
<p>このページのメインコンテンツな部分<p/>
<noframes>
<p><a href="menu.html"メニュー</a>へ戻る</p>
</noframes>
<p><a href="index.html" target="_top">トップページへ戻る</a></p>
</body>
この様にしておけば行き止まりはなくなりますし、一応誰でもリンクを辿れば見る事の出来るサイトになります。但しトップへ戻るリンクにはtarget属性を指定しないと痛い目に遭います。
通常のページに「トップページ」と「メニュー」へのリンクが追加すると良い…という話でした。しかしよく考えてみて下さい。「メニュー」のリンクを使う(すなわちフレームが無効となる環境の)閲覧者が「トップページ」へのリンクを使うと「メニュー」へ誘導するメッセージが表示されます。…ということは「トップページ」に「メニュー」を書いてしまえばそもそもTransitionalで定義されるnoframesは不要になるのです。以下にその例を示します。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head><title>なんとかかんとかのページ</title></head>
<frameset cols="150,*">
<frame src="menu.html" name="left">
<frame src="top.html" name="right">
<noframes>
<body>
<!-- 以下の内容はmenu.htmlに記述されている内容だと仮定して下さい -->
<h1>なんとかかんとかのページ Contents</h1>
<ul>
<li><a href="aaa.html">1つめのコンテンツ</a></li>
<li><a href="bbb.html">続きまして2つめのコンテンツなり</a></li>
<li><a href="bbs.cgi">掲示板</a>で話しませんか</li>
<li><a href="about.html">このページについて</a></li>
</ul>
<!-- top.htmlに記述されている内容も記入しましょう -->
</body>
</noframes>
</frameset>
</html>
「メニュー」を2ヶ所に記述する事になり若干フレームを使うメリットは減ってしまいますが、それ以上の価値があるでしょう。(他の技術に頼ればフレーム同様に1つのファイルで共有できます。)
ここでポイントとなるのはframe要素のname属性とtitle属性です。例えばホームページ・リーダー(v2.5)はtitle属性の値を参照して読み上げるそうです。また、Lynxなどはname属性の値をフレームとして読み込むファイルへのリンク文字列として利用します。もしかしたら貴方の携帯電話もそう処理してくれるかもしれません。(僕の携帯電話(J-T010)はそういった処理を行ってくれます。)
従ってtitle要素とname要素には一見して内容が分かるような値を持たせる必要があります。これを元に今までに挙げた例を改善してみましょう。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<html>
<head><title>なんとかかんとかのページ</title></head>
<frameset cols="150,*">
<frame src="menu.html" title="メニュー" name="menu">
<frame src="top.html" title="メインコンテンツ" name="main">
<noframes>
<body>
<!-- 以下の内容はmenu.htmlに記述されている内容だと仮定して下さい -->
<h1>なんとかかんとかのページ Contents</h1>
<ul>
<li><a href="aaa.html">1つめのコンテンツ</a></li>
<li><a href="bbb.html">続きまして2つめのコンテンツなり</a></li>
<li><a href="bbs.cgi">掲示板</a>で話しませんか</li>
<li><a href="about.html">このページについて</a></li>
</ul>
<!-- top.htmlに記述されている内容も記入しましょう -->
</body>
</noframes>
</frameset>
</html>
name属性の値はアルファベットで始まらなくてはなりません(数字で始める事はできません)。また、XHTML 1.0に於いてname属性は非推奨とされ、id属性の利用が推奨されています。XHTML 1.0 Framesetに準じて記述する場合はname属性とid属性を併記するのが好ましいでしょう。
frame要素にはそのフレームの説明を記述した文書と関連づける為にlongdesc属性が準備されています。タイトルで伝えきれない情報をlongdesc属性を用いて関連づけましょう。尚、longdesc属性の値はフレーム枠の説明を記述した文書のURIです。
frame要素にはnoresizeという属性が準備されています。これを指定する事によってフレームの幅を変えられなくする事が出来るのです。しかし、その固定した幅が閲覧者にとって理想的とは限りません。閲覧者の画面幅なんて製作者は知り得ないのです。
もしかしたら重要でないフレームが画面を占拠してしまい、もう1つの重要なフレームが凄く細くなってしまっているかもしれません。そんな時、幅を変えられないのは不便だと思いませんか?
これこそがフレームの最も致命的な問題です。現在草案段階のXFramesではhttp://example.org/home.frm#frames(id1=uri1,id2=uri2,...)
といったURIになる予定ですからこの問題は解決する事になります。URIでフレームの中身まで指定したいのは山々ですが、それはXFramesが実用化されるまで待つ事にしましょう。だいぶ先の話になるでしょうが…。
そもそもframeはNetscapeの独自拡張規格を取り入れた規格であった為、HTML本来の「マークアップ」になっていません。そのため、フレームはHTML4 FramesetとXHTML 1.0 Framesetだけに定義され、XHTML1.1では定義されませんでした。そして今論議されているXHTML2.0にはXFramesが取り込まれる予定です。
スタイルシートを使うことで表示場所を固定する事ができます。その為には全ての場所に「メニュー」を記述する必要があります。(全てのページにメニューを記述するならフレームを用いる必要がない事は明らかです。)
SSIなどの技術を使えば、全てのファイルに同じメニューを組み込む事は簡単です。このサイトでも似たような事が行われています。……そう、実はナビゲーション部を1つのファイルで共有
する事は別にフレームを使わなくても可能なのです。
CSSでposition:fixedを使ってしまう方法が分かりやすいのですが、MSIE6が対応していないという致命的な欠点があります。その為、overflowプロパティを使うのが妥当です。詳細な方法は以下のサイトを参照して下さい。
.