iframe の使い方
<iframe> は、自分のページの中に別のページを表示します。src にページのアドレス、title に内容の説明、そしてサイズを指定します。
<iframe src="https://example.com/" title="Example site" width="600" height="400"></iframe>
フレームはページを、独自のスタイルとスクリプトを持つ別の文書として読み込みます。このページの例では src の代わりに srcdoc を使っています。フレームの HTML を属性に直接書くので、別のサイトを読み込まなくても動きます。
外側の段落は青い太字ですが、フレームの中の段落は違います。ページには同じ p のルールがあるのにです。スタイルはどちらの向きにもフレームの境界を越えません。初期の枠線と 300×150 の初期サイズはブラウザによるもので、width と height 属性でサイズを上書きしています。
YouTube の動画や地図を埋め込む
動画サイトや地図サービスは、すぐに使える iframe のコードを提供しています。YouTube では「共有」を押して「埋め込む」を選びます。
<iframe width="560" height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
Google マップでは、場所を開いて「共有」を押し、「地図を埋め込む」から同じように iframe をコピーします。title は残し (フレームに入るときにスクリーンリーダーが読み上げます)、固定のサイズは下のレスポンシブな CSS に置き換えましょう。allow 属性は、埋め込まれたページでは初期状態でオフになっている自動再生や全画面表示などの機能をフレームに許可します。
サイズ、枠線、レスポンシブな iframe
コピーした埋め込みコードは固定のピクセルサイズを使っているので、スマートフォンでははみ出します。width: 100% と aspect-ratio でフレームが入れ物いっぱいに広がって形を保ち、border: 0 で初期の枠線が消えます。
max-width: 480px を別の値に変えても、フレームはどの幅でも 16:9 の形を保ちます。border: 0 を消すとブラウザの初期の枠線が表示されます。古い frameborder、scrolling、marginheight 属性は廃止されているので、CSS を使いましょう。
sandbox: フレームにできることを制限する
フレームは普通のページと同じく、スクリプトを実行し、フォームを送信し、ポップアップを開けます。sandbox 属性はその力を取り上げます。空の sandbox はほぼすべてをブロックし、キーワードを 1 つ付けるごとに 1 つずつ戻します。下の 2 つのフレームには、小さなスクリプトを含む同じ HTML が入っています。
1 つ目のフレームは、スクリプトが実行されないので仮のテキストのままです (Chrome のコンソールには「Blocked script execution」のメッセージが出ます)。ユーザーが書いた HTML など、完全には信用できない内容をフレームに入れるときは必ず sandbox を使い、必要なキーワードだけを追加しましょう。
| キーワード | 許可するもの |
|---|---|
allow-scripts | JavaScript の実行 |
allow-forms | フォームの送信 |
allow-popups | window.open と target="_blank" のリンク |
allow-modals | alert()、confirm()、prompt() |
allow-same-origin | 内容を本来のオリジンのものとして扱う (Cookie、ストレージ) |
allow-top-navigation | タブ全体を自分のページから移動させる |
自分のオリジンの内容に allow-scripts と allow-same-origin を組み合わせてはいけません。フレーム内のスクリプトが自分で sandbox を外せてしまいます。
フレームとのやり取り: postMessage
外側のページとフレームは別々の文書です。オリジンが違うと互いの DOM に触れることはできませんが、メッセージは送れます。メッセージを入力してフレームに送ってみてください。
実際のコードでは、'*' ではなくフレームの正確なオリジン ('https://maps.example.com' など) を渡し、受け取る側で e.origin を確認しましょう。そうすれば、メッセージは想定したサイトとの間でだけやり取りされます。
パフォーマンスと、サイトに拒否されるとき
- 遅延読み込み。 ページの下のほうにあるフレームには
loading="lazy"を付けましょう。読者がその近くまでスクロールしたときにだけブラウザが読み込みます。iframe 1 つごとにページ全体を読み込むので、埋め込みの多いページはこれがないと遅くなります。 - 「接続が拒否されました」。 多くのサイト (銀行、ほとんどの SNS、Google 検索) は、フレーム表示を禁止する
X-Frame-Optionsやframe-ancestorsヘッダーを送り、ブラウザはフレーム内にエラーを表示します。自分のページからは上書きできません。サイトの公式の埋め込み用 URL を使うか、リンクにしましょう。 - アクセシビリティ。 必ず
titleを付けましょう。スクリーンリーダーがフレームに名前を付けるのはこれで、タイトルのないフレームがいくつもあるページは移動しにくくなります。
よくある間違い
titleがない。 スクリーンリーダーはフレームを名前のないものとして読み上げます。- コピーした埋め込みコードの固定幅。
width: 100%とaspect-ratioに置き換えましょう。 - 普通の動画ファイルをフレームで表示する。 自分の
.mp4ファイルには video 要素を使いましょう。iframe はページのためのものです。 - フレームの中の内容を信用する。 自分で書いていないものには
sandboxを付けましょう。 - 外側の CSS でフレームにスタイルを付けようとする。 フレームのページには、その中からスタイルを付けます。
よくある質問
HTML の iframe とは何ですか?
<iframe> (インラインフレーム) は、現在のページの中に別の Web ページを表示する箱です。独自の文書、スタイル、スクリプトを持つので、動画、地図、広告、コードのプレビューといった埋め込みに使われます。
iframe で YouTube の動画を埋め込むには?
YouTube で「共有」から「埋め込む」を選び、コードをコピーします。src が https://www.youtube.com/embed/ と動画の ID になった iframe です。title と allowfullscreen 属性は残し、CSS で width: 100% と aspect-ratio: 16 / 9 を指定するとレスポンシブになります。
iframe に「接続が拒否されました」と表示されるのはなぜですか?
そのサイトが、ほかのサイトによるフレーム表示を禁止する X-Frame-Options や Content-Security-Policy: frame-ancestors ヘッダーを送っています。多くのサイトがクリックジャッキングを防ぐためにそうしています。自分のページからは上書きできないので、公式の埋め込み用 URL があればそれを使いましょう。
iframe の枠線を消すには?
CSS で border: 0 を指定します。古い frameborder="0" 属性は廃止されていますが、コピーした埋め込みコードの多くにはまだ含まれています。
iframe をレスポンシブにするには?
CSS で width: 100% と aspect-ratio (動画なら aspect-ratio: 16 / 9) を指定し、固定の高さは書きません。すると iframe が入れ物に合わせて伸び縮みし、形を保ちます。
iframe の sandbox 属性は何をしますか?
空の sandbox 属性は、フレーム内のスクリプト、フォームの送信、ポップアップなどをブロックし、その内容を固有のオリジンから来たものとして扱います。そのうえで、allow-scripts や allow-forms などのキーワードで、埋め込みに必要なものだけを許可します。