読み込み中...

HTMLにおけるフレームの使い方10選

HTMLフレームの作成例 HTML
この記事は約24分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

HTMLでフレームを扱う結論は、現在の新規制作では旧来の<frameset><frame>ではなく、埋め込みには<iframe>、画面分割にはdisplay: griddisplay: flexを使うことです。古い管理画面や教材ではフレーム構造に出会うため、読み解き方を知ると改修方針を立てやすくなります。

フレームの作り方を学ぶ目的は、旧仕様の採用ではありません。既存のcolsrowssrcnameを理解し、必要に応じて<iframe>やCSSレイアウトへ置き換える判断力を持つことです。

使い方では、コードの読み方、代替実装、SEO、セキュリティ、アクセシビリティを分けて考えます。HTMLの基本とページ内移動は、HTMLでアンカーリンクを活用する方法も関連して理解しやすい領域です。

動作確認環境
  • HTML Living Standard / CSS Grid Layout Module Level 2
  • Google Chrome 126 / Firefox 127 / Safari 17.5
  • JavaScript ECMAScript 2023 / Fetch API
📖 この記事で学べること
  • 旧来のHTMLフレーム構文と現在の扱い
  • <iframe>を使った安全な埋め込みの作り方
  • フレーム風レイアウトをCSS Gridで再現する方法
  • 表示されない場合やセキュリティ警告への対処
  • SEOとアクセシビリティを崩しにくい設計判断

HTMLフレームとは

HTMLフレームとは、ひとつの画面を複数領域に分け、各領域に別々のHTML文書を読み込ませる考え方です。旧来の<frameset>は全体を分割し、<frame>が個別文書を参照しました。

<frameset><frame><noframes>は現行HTMLでは廃止要素です。公式情報は、MDNのframe要素リファレンスと、WHATWG HTMLのiframe仕様が一次情報として参照できます。

一方、<iframe>は現在も使われる埋め込み要素で、地図、動画、外部フォーム、管理画面の一部などをページ内に読み込めます。フレームという語が旧来の<frameset>を指すのか、現在の<iframe>を指すのかを切り分けますし、ここがポイントです。

フレームの基本概念

基本構造は、外側の領域定義と内側の読み込み先に分かれますし、ここがポイントです。旧構文ではcolsで横方向、rowsで縦方向を分割し、各<frame>srcに読み込むファイルを置きました。

<frameset cols="50%,50%">
  <frame src="left.html">
  <frame src="right.html">
</frameset>

結果: 期待される表示は、画面が左右に二分割され、左側にleft.html、右側にright.htmlの内容が表示される構成です。ただし、現行ブラウザ向けの新規ページではこの作り方を採用しない判断が妥当です。

近い見た目を現代的に作る場合、外枠は<div>で構成し、CSSのgrid-template-columnsで左右比率を決めます。文書構造がまとまり、検索エンジンと支援技術に内容を伝えやすくなります。

HTMLフレームの利点と制約

フレームの利点は、メニューやヘッダーを残したまま別領域の文書だけを切り替えられる点です。その考え方は、SPAの部分更新やfetch()による非同期読み込みにも通じますが、これは押さえたい点です。

ただし旧来の分割方式は、URLが表示内容と一致しにくく、履歴管理、印刷、ブックマークと相性が悪い制約があるのが基本です。SEOでも、検索エンジンが主コンテンツと補助コンテンツの関係を判断しにくくなる場合があります。

💡 Tips: フレームの作り方は、旧構文の暗記よりも「別文書を読み込む」「画面を分割する」「一部だけ更新する」という目的に分解すると、現代的な代替へ移しやすくなるのが基本です。

HTMLフレームの基本的な使い方

HTMLフレームの使い方は、教材として読む旧構文と、現在の制作で使う構文を分けると混乱しません。古いコードでは<frameset>の意味を読み、新規実装では<iframe>かCSSレイアウトを選びます。

代表的な要素と属性を早見表で整理するのが目安です。旧構文は読解用、現行構文は新規実装向けとして扱いるのが目安です。

項目主な役割現在の扱い代替・注意点
<frameset>画面分割の外枠廃止要素display: gridへ置換
<frame>各領域の文書読込廃止要素<iframe>か通常リンク
<noframes>代替本文廃止要素本文HTMLへ統合
<iframe>別文書の埋め込み現行利用可titlesandbox
src読み込み先URL現行属性パスを確認
nameターゲット名利用場面ありtargetと対応
targetリンク表示先現行属性relも確認
title埋め込み説明推奨属性支援技術向け
sandbox権限制限現行属性許可値を絞る
allow機能許可現行属性全画面などを制御
loading遅延読込現行属性lazyを検討
referrerpolicy参照元制御現行属性外部埋め込みで確認
width埋め込み幅現行属性CSS制御も可
height埋め込み高さ現行属性aspect-ratio併用
cols旧列分割読解用grid-template-columns
rows旧行分割読解用grid-template-rows
Content-Security-Policy読み込み制御現行ヘッダーframe-ancestors
X-Frame-Options埋め込み制限互換対策SAMEORIGIN
frame-ancestors許可元制御現行CSPクリックジャッキング対策
displayレイアウト方式現行CSSgridflex
grid-template-columns列幅設計現行CSScolsの置換
grid-template-rows行高設計現行CSSrowsの置換
minmax()可変幅制御現行CSSレスポンシブ向け
clamp()範囲制御現行CSS余白や幅に使う
fetch()非同期取得現行API部分更新に使う
addEventListener()イベント登録現行API直書きを避けやすい
querySelector()要素取得現行APICSSセレクタで選ぶ
innerHTMLHTML挿入注意して利用信頼済みに限定
aria-label補助ラベル現行属性UIの意味を補う
role意味付け補助現行属性乱用を避ける

サンプルコード1:フレームセットの作成

旧来の作り方では、縦方向の分割にrowsを使います。上半分と下半分に異なるHTMLを読み込む場合、次の構文でした。

<frameset rows="50%,50%">
  <frame src="top.html">
  <frame src="bottom.html">
</frameset>

結果: 期待される表示は、上側にtop.html、下側にbottom.htmlが読み込まれる画面です。現在の作り方では、同じ視覚構造をCSS Gridで再現するほうが扱いやすいでしょう。

rows="50%,50%"grid-template-rows: 1fr 1fr;に近い発想です。割合をCSSに寄せると、HTMLは文書構造、CSSは見た目という役割分担を保てます。

サンプルコード2:フレーム内にコンテンツを表示する方法

フレーム内に別ページを表示する使い方では、読み込み先をsrcで決めます。nameを付けると、リンクのtargetから特定領域へ遷移させる設計が可能でした。

<frameset cols="30%,70%">
  <frame src="menu.html" name="menuFrame">
  <frame src="content.html" name="contentFrame">
</frameset>

結果: 期待される表示は、左側の30%にmenu.html、右側の70%にcontent.htmlが出る構成です。メニューと本文の分離は理解しやすい一方、URLと表示状態がずれやすい点に注意が必要になります。

現在のページ内で部分的な切り替えを行うなら、メニューは通常の<nav>、本文は<main>に置きます。ツリー構造は、HTMLとツリー構造を学ぶ記事と合わせると整理しやすくなるのがポイントです。

フレームの応用設定

フレームの応用設定で扱う内容は、サイズ変更、領域間の連携、読み込み元の制御です。旧構文を高度化するより、目的を現代のAPIへ写し替える発想が必要です。

リサイズはCSSのメディアクエリやminmax()、連携はpostMessage()や同一文書内の状態管理、埋め込み制御はsandboxやCSPで扱います。フレームの使い方を応用するほど、セキュリティと保守性の確認範囲も広がります。

サンプルコード3:フレームのリサイズ設定

古い教材では、画面幅を見てframesetcolsを書き換える例があるのが一般的です。仕組みの理解には役立ちますが、新規実装ではCSSに任せるほうが自然です。

<frameset cols="*,300" onload="resizeFrames()">
  <frame src="sidebar.html" name="sidebarFrame">
  <frame src="main.html" name="mainFrame">
</frameset>
<script>
function resizeFrames() {
  if (window.innerWidth < 500) {
    document.getElementsByTagName('frameset')[0].cols = '100,*';
  }
}
</script>

結果: 期待される表示は、幅が狭いときに左領域が100px相当へ変化する動きです。ただし、onload属性で関数を呼ぶ作り方はHTMLとJavaScriptが混ざりやすく、現代的な保守には向きません。

代替としてCSSの@mediaで列幅を切り替えると、HTMLを書き換えずにレスポンシブ対応できます。レイアウトの作り方をCSS側へ寄せると、デザイン変更時の影響範囲を読みやすくできます。

.layout {
  display: grid;
  grid-template-columns: minmax(180px, 280px) 1fr;
  min-height: 100vh;
}
@media (max-width: 700px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

結果: 期待される表示は、広い画面ではサイドバーと本文が横並びになり、狭い画面では1列に並ぶレイアウトです。旧フレームの分割思想を保ちながら、URLや本文構造はひとつのHTMLに集約できると理解できるのが現実的です。

サンプルコード4:フレーム間の通信方法

フレーム間の通信は、同一オリジンか別オリジンかで扱いが変わります。同一オリジンならDOMへアクセスできる場合がありますが、別オリジンでは同一オリジンポリシーにより直接操作できません。

<iframe id="preview" src="preview.html" title="プレビュー"></iframe>
<script>
const preview = document.querySelector('#preview');
preview.addEventListener('load', () => {
  preview.contentWindow.postMessage({ type: 'update', text: 'Hello' }, location.origin);
});
</script>

結果: 期待される動作は、preview.html側がmessageイベントを受け取れる状態であれば、親ページからデータを渡せることです。外部ドメインへ送る場合は、location.originではなく許可する送信先オリジンを明示します。

受信側でevent.originを確認しない作り方は避けます。受け取った文字列をinnerHTMLへ直接入れる場合も、信頼できるデータだけに限定し、必要ならテキストとして扱いると整理できるのがポイントです。

⚠️ 注意: 外部ページを<iframe>で読み込むときは、相手先の利用規約、埋め込み可否、クリックジャッキング対策、Cookie制限を確認します。表示できることと利用してよいことは同じではありません。

よくあるエラーと対処法

つまずきやすいのは、読み込み先のパス、ブラウザのセキュリティ制限、レスポンシブ時の高さ崩れです。フレームは別文書を扱うため、通常のHTMLより確認する境界が増えます。

画面が空白になった場合は、HTML構文より先にネットワークとコンソールを確認すると理解できるのが一般的です。404403Refused to displayCORSContent-Security-Policyの警告があれば、配置やヘッダー設定が原因候補です。

フレームが表示されない場合の対処法

表示されない原因の多くは、srcのパス違い、ファイル名の大文字小文字の不一致、サーバー上にファイルがない状態です。ローカルでは動いても本番で失敗する場合、Linux系サーバーのファイル名判定が影響することがあります。

<iframe
  src="/pages/help.html"
  title="ヘルプページ"
  width="100%"
  height="420"
  loading="lazy">
</iframe>

結果: 期待される表示は、/pages/help.htmlの内容が高さ420pxの埋め込み領域に読み込まれる状態です。空白になる場合は、ブラウザで/pages/help.htmlを直接開き、ステータスコードを確認します。

直接表示できるのに埋め込みだけ失敗する場合、サーバー側が埋め込みを拒否している可能性があると覚えるとよいでしょう。X-Frame-OptionsContent-Security-Policyの設定を確認すると、原因を絞り込めますが、これは押さえたい点です。

セキュリティに関するエラーとその解決策

セキュリティ関連のエラーは、サイトを守るための制限として出る場合があります。外部サイトを<iframe>に入れてRefused to displayが出る場合、相手側が埋め込みを許可していない可能性が高いです。

Content-Security-Policy: frame-ancestors 'self' https://partner.example

結果: 期待される挙動は、自サイトとhttps://partner.exampleからの埋め込みだけが許可される状態です。許可していないサイトから読み込まれた場合、ブラウザが表示を拒否するのが基本です。

X-Frame-Options: SAMEORIGIN

結果: 期待される挙動は、同一オリジンのページだけが対象ページをフレーム内に表示できる状態です。古い環境も考慮する場合の互換策として使われますが、現代的な制御はCSPのframe-ancestorsを軸に考えます。

フォームを埋め込む場合は、個人情報を扱う画面で送信元やCookieの扱いが絡みます。フォーム設計は、HTMLで問い合わせフォームを作成する方法も確認すると流れをつかみやすいでしょう。

フレームを用いたデザイン例

フレームを用いたデザイン例では、固定ナビゲーション、サイドバー付き本文、プレビュー付き編集画面が理解しやすい構成です。いずれも「常に見える領域」と「切り替わる領域」を組み合わせますし、これが一つの目安です。

現代的に作るなら、見た目の分割はCSS、外部コンテンツの埋め込みは<iframe>、部分更新はfetch()で担うと役割が明確です。画像やスライドを組み込むページでは、HTMLとCSSで作るスライドショーの考え方も近い領域です。

サンプルコード5:フレームを利用したナビゲーションバー

旧フレームでナビゲーションバーを固定する作り方は、上部にメニュー、下部に本文を置く構成でした。読み解く場合は、rowsの比率と各srcの関係を見ます。

<frameset rows="10%,90%">
  <frame src="navbar.html" name="navbarFrame">
  <frame src="content.html" name="contentFrame">
</frameset>

結果: 期待される表示は、上部10%にnavbar.html、下部90%にcontent.htmlが入る構成です。現在はposition: stickyや通常の<header><nav>で同じ目的を達成できます。

ナビゲーションを同じHTML内に置けば、リンクテキスト、見出し、本文の関係が検索エンジンにも伝わりやすくなります。ページ内の移動先が多い場合は、アンカーリンクと組み合わせる使い方が向いていると考えられますし、これが一つの目安です。

サンプルコード6:フレームを使ったレスポンシブデザイン

レスポンシブ対応では、フレームを直接伸縮させるより、CSS Gridで列の数と幅を切り替えます。HTMLは<aside><main>で意味を分け、CSSで見た目を制御します。

<div class="app-layout">
  <aside class="app-menu">メニュー</aside>
  <main class="app-main">本文</main>
</div>

結果: 期待される表示は、メニューと本文を同じ文書内に持つレイアウトの土台です。CSSを加えるまでは通常のブロック要素として縦に並びますが、覚えておくと役立つでしょう。

.app-layout {
  display: grid;
  grid-template-columns: clamp(180px, 24vw, 280px) 1fr;
  gap: 24px;
}
@media (max-width: 768px) {
  .app-layout {
    grid-template-columns: 1fr;
  }
}

結果: 期待される表示は、768pxを超える画面では横並び、768px以下では縦並びになるレイアウトです。旧来のフレームよりも、印刷、拡大表示、モバイル表示に対応しやすくなるのが一般的です。

ℹ️ 補足: CSS Gridの仕様はMDNのCSS Grid Layoutで確認できます。旧フレームの作り方を置き換える際は、行列の比率をCSSのトラック定義へ対応させると移行しやすくなります。

HTMLフレームのSEO対策

HTMLフレームのSEO対策では、検索エンジンに主要コンテンツ、ページタイトル、リンク関係、正規URLを正しく伝えることが中心です。旧フレームは文書が分断されやすく、ひとつのページとしての意味が弱くなりがちです。

新規制作では主要本文を親ページ内に置き、埋め込みは補助情報に限定する構成が扱いやすいです。別ページを読み込む場合でも、title、代替リンク、canonical、サイトマップの整合を確認すると言えるでしょう。

フレーム使用時の検索エンジン最適化の考え方

旧教材では<noframes>に代替コンテンツを書く例がありますが、現行HTMLでは廃止要素です。現在は本文を通常のHTMLに置き、必要な補助コンテンツだけを<iframe>で埋め込む設計へ寄せます。

<main>
  <h1>サービス概要</h1>
  <p>主要な説明文は親ページ内に配置すると整理できます。</p>
  <p><a href="/map/">地図ページを別画面で開く</a></p>
  <iframe src="/map/embed/" title="店舗周辺の地図" loading="lazy"></iframe>
</main>

結果: 期待される表示は、主要な説明文が親ページにあり、地図だけが埋め込みで表示される構成です。検索エンジンが読み取るべき本文を埋め込み内部へ閉じ込めない点が、この作り方の要点になるのが基本です。

<meta name="robots">robots.txtは、インデックス対象を整理するために使います。埋め込み専用ページを検索結果に出したくない場合は、親ページとの関係を見てnoindexを検討します。

<head>
  <link rel="canonical" href="https://example.com/service/">
  <meta name="robots" content="index, follow">
</head>

結果: 期待される解釈は、正規URLがhttps://example.com/service/であり、検索エンジンにインデックスとリンク追跡を許可する状態です。埋め込み用ページ側では、必要に応じて別の指示を置きますし、ここを基本と考えるとよいでしょう。

これらの設定は、単独で順位を上げる仕組みではありません。主コンテンツを親HTMLに置き、内部リンクで関連ページへ自然につなぐことがSEOの前提です。

現代のウェブデザインにおけるフレームの位置付け

現代のウェブデザインでは、旧来のフレームは過去のコードを読むための知識に近い位置付けです。現在の作り方では、画面分割はCSS、状態変化はJavaScript、外部埋め込みは<iframe>という分担が一般的です。

ただし、フレームの発想そのものが消えたわけではありません。管理画面、プレビュー画面、動画埋め込み、外部決済、ドキュメントビューアなど、別コンテキストをページ内に置く要件は現在もあります。

モダンウェブデザインにおけるフレームの代替技術

代替技術の中心は、CSS Grid、Flexbox、JavaScriptの非同期読み込みです。旧フレームが担っていた「分割」と「更新」を分けて設計すると、保守しやすいページになります。

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}
.sidebar {
  grid-column: 1;
}
.main-content {
  grid-column: 2;
}

結果: 期待される表示は、.sidebarが左列、.main-contentが右列に配置される2カラムレイアウトです。旧colsのような割合指定をCSSで管理できると覚えるとよいでしょう。

<div class="container">
  <aside class="sidebar">サイドバーの内容</aside>
  <main class="main-content">メインコンテンツの内容</main>
</div>

結果: 期待される表示は、意味のあるHTML要素でサイドバーと本文を分けた構造です。CSSが読み込まれない場合でも、文書の順序は保たれます。

本文の一部だけを差し替える場合はfetch()を使う設計が考えられます。カレンダーのように日付や状態の更新が絡むUIでは、HTMLとJSでカレンダーを作成する方法のような動的更新の発想が参考になるのが目安です。

<button id="loadButton" type="button">コンテンツをロード</button>
<div id="content" aria-live="polite"></div>

結果: 期待される表示は、ボタンと更新先の空領域が画面に出る状態です。aria-liveを置くと、更新された内容を支援技術へ伝えやすくなります。

document.querySelector('#loadButton').addEventListener('click', async () => {
  const response = await fetch('/parts/content.html');
  const html = await response.text();
  document.querySelector('#content').innerHTML = html;
});

結果: 期待される動作は、ボタン操作で/parts/content.htmlを取得し、#contentへ挿入する流れです。外部入力を含むHTMLを挿入する場合は、サニタイズやテンプレート化を検討します。

⚠️ 注意: innerHTMLは信頼できない文字列に使うとXSSの原因になります。ユーザー入力を表示するだけならtextContentを使い、HTMLとして挿入する範囲を限定するのがポイントです。

フレームを使用したサイトの事例研究

フレームを使用したサイトの事例研究では、見た目だけでなく運用上の問題も観察するのが現実的です。古いポータル、管理画面、教育用コンテンツでは、メニューを固定し本文だけを切り替える構成が採用されてきました。

その構成はメニューを常に見られる一方、URL共有、検索流入、スマートフォン表示で問題が出やすくなります。現在の改修では、見た目を残しながらHTML構造を統合する方針が取りやすいでしょう。

サンプルコード7:実際のウェブサイトにおけるフレームの使用事例

ニュースサイト風の構成では、本文を広く取り、右側に補助情報を置く作り方が想定されますし、ここがポイントです。旧フレームでは、主要記事とサイドバーを別文書として読み込みます。

<frameset cols="75%,25%">
  <frame src="main_article.html" name="mainFrame">
  <frame src="sidebar.html" name="sidebarFrame">
</frameset>

結果: 期待される表示は、左側75%に主要記事、右側25%にサイドバーが表示される構成です。現在なら、記事本文を<article>、関連情報を<aside>にまとめる作り方が自然です。

この置き換えにより、検索エンジンはタイトル、本文、関連リンクの関係をひとつの文書として把握しやすくなります。ユーザーも、共有URLから同じ状態へ到達しやすくなります。

サンプルコード8:フレームを活用したユーザーインターフェースの改善例

管理ダッシュボードでは、ヘッダー、メニュー、作業領域を分けたい場面があるのが一般的です。旧構文では、上部にヘッダー、下部に管理機能を表示するフレームの使い方が考えられました。

<frameset rows="20%,80%">
  <frame src="header.html" name="headerFrame">
  <frame src="control_panel.html" name="controlFrame">
</frameset>

結果: 期待される表示は、上部20%にheader.html、下部80%にcontrol_panel.htmlが出る管理画面です。現在は、共通ヘッダーをテンプレート化し、メイン領域だけをルーティングや非同期取得で切り替えるほうが保守しやすくなります。

プレビュー画面のように独立したCSSやスクリプト環境を必要とする場合は、<iframe>が適することもあります。このときはsandboxで権限を絞り、allow-scriptsallow-same-originを安易に増やさない設計が必要です。

まとめ

HTMLのフレームは、旧来の<frameset>をそのまま使う技術ではなく、過去のコードを読む知識と現在の埋め込み設計を考える土台です。新規制作の作り方では、画面分割にCSS GridやFlexbox、外部コンテンツの表示に<iframe>、部分更新にfetch()を使い分けますが、これは押さえたい点です。

判断時は、見た目だけでなくURL、SEO、アクセシビリティ、セキュリティを確認します。フレーム風UIでも主要本文は親HTMLに置き、埋め込みは補助情報に限定する構成が扱いやすいでしょう。

既存ページを改修するなら、<frame>srcで読み込まれている文書を洗い出し、本文、ナビゲーション、補助コンテンツへ分類します。分類できると、CSSレイアウトへ統合する範囲と、<iframe>として残す範囲を判断できるのが現実的です。

関連記事

著者: Japanシーモア編集部

Japanシーモアは、Web/IoT/APP/SYS 分野のプログラミング情報を体系的に提供するメディアです。本記事は編集部による執筆とAI支援を組み合わせて制作し、公開前に編集部が校正しています。誤りや改善案がございましたらお問い合わせよりご連絡ください。

※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。