The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Embed a page<iframe src="/preview" title="Document preview"> </iframe>View examples
Reserve space<iframe src="/chart" title="Sales chart" width="800" height="450"> </iframe>View examples
Fit the containeriframe { inline-size: 100%; block-size: auto; aspect-ratio: 16 / 9; }View examples
Defer off-screen loading<iframe loading="lazy" src="/map" title="Office map"> </iframe>View examples
Limit referrer data<iframe referrerpolicy="strict-origin" src="https://example.com" title="Example"> </iframe>View examples
Apply all sandbox restrictions<iframe sandbox src="/untrusted" title="Untrusted preview"> </iframe>View examples
Allow scripts only<iframe sandbox="allow-scripts" src="https://widgets.example" title="Widget"> </iframe>View examples
Allow form submission<iframe sandbox="allow-forms" src="/survey" title="Survey"> </iframe>View examples
Allow fullscreen<iframe allow="fullscreen" src="/player" title="Video player"> </iframe>View examples
Deny camera and microphone<iframe allow="camera 'none'; microphone 'none'" src="/widget" title="Widget"> </iframe>View examples
Embed inline HTML<iframe srcdoc="<p>Preview</p>" title="Inline preview"> </iframe>View examples
Name a navigation target<iframe name="report" title="Generated report"></iframe>View examples
Open a link in a frame<a href="/report" target="report">Load report</a>View examples
Send a cross-window messageframe.contentWindow.postMessage({ type: 'ready' }, 'https://widget.example')View examples
Validate a received messageif (event.origin !== 'https://widget.example') returnView examples

An iframe creates a separate nested browsing context, not just another page element. Give it an accessible title, reserve its dimensions, grant only the capabilities it needs, and treat every cross-origin message as untrusted input. Prefer a link when users do not need an embedded experience.

Step by step

Detailed examples

01

Name every embedded document

The title attribute describes the frame itself, helping screen-reader users decide whether to enter it. It is distinct from the title element inside the embedded page. Content between iframe tags is not dependable fallback content in modern HTML, so provide a separate link when access to the destination matters.

An embed with a direct alternative
<iframe
  src="/reports/quarterly"
  title="Interactive quarterly revenue report"
  width="960"
  height="540">
</iframe>
<p><a href="/reports/quarterly">Open the quarterly report directly</a></p>
Back to quick reference ↑
02

Reserve stable, responsive space

Width and height attributes establish a useful intrinsic ratio before CSS runs. CSS can then fit the iframe to its container. Choose a fixed block size for scrollable applications or aspect-ratio for media-like content; verify the embedded interface remains usable at narrow sizes.

Responsive 16:9 frame
<iframe class="video-frame" src="/player/42" title="Product walkthrough" width="1280" height="720"></iframe>
<style>
  .video-frame {
    inline-size: 100%;
    block-size: auto;
    aspect-ratio: 16 / 9;
    border: 0;
  }
</style>
Back to quick reference ↑
03

Control loading and referrer exposure

Lazy loading can save bandwidth for embeds below the fold, but critical above-the-fold content should load normally. referrerpolicy controls referrer information sent while fetching the frame and its subresources. It does not isolate the frame or replace its own privacy policy.

A deferred map with limited referrer data
<iframe
  src="https://maps.example/embed/office"
  title="Map showing the city office"
  width="800"
  height="500"
  loading="lazy"
  referrerpolicy="strict-origin-when-cross-origin">
</iframe>
Back to quick reference ↑
04

Restore sandbox capabilities one by one

An empty sandbox attribute applies the full restriction set. Add only tokens the embed actually requires. For same-origin content, combining allow-scripts and allow-same-origin can let the embedded page remove its own sandbox attribute, substantially weakening the boundary; isolate untrusted content on a separate origin.

A scriptable cross-origin widget
<iframe
  src="https://widgets.example/weather"
  title="Local weather widget"
  sandbox="allow-scripts"
  referrerpolicy="no-referrer">
</iframe>

Note: Add allow-forms, allow-popups, or other tokens only after testing a concrete requirement.

Back to quick reference ↑
05

Delegate powerful features narrowly

The allow attribute applies a permissions policy to one iframe. Features are still constrained by any response header and by browser or user decisions, so allow cannot grant more than the parent permits. Start with no sensitive capabilities and add an explicit allowlist only when a feature is essential.

A player with one delegated capability
<iframe
  src="https://media.example/player/7"
  title="Conference keynote player"
  allow="fullscreen"
  sandbox="allow-scripts">
</iframe>
Back to quick reference ↑
06

Treat srcdoc as a complete document

srcdoc supplies inline HTML and takes precedence over src when supported. The document can still run scripts or navigate unless sandboxed appropriately. Never interpolate untrusted text into srcdoc as HTML; encode it as text or render it in a separately isolated origin.

A static sandboxed preview
<iframe
  title="Message preview"
  sandbox
  srcdoc="<!doctype html><html lang='en'><body><p>Preview only</p></body></html>">
</iframe>
Back to quick reference ↑
07

Use named frames deliberately

A name creates a browsing-context target for links and forms. This can be useful for preview panes, but surprising target behavior can disorient users and complicate history. Keep an ordinary link available and avoid generic names likely to collide with other contexts.

Load reports into a named preview
<nav aria-label="Report previews">
  <a href="/reports/week" target="report-preview">Weekly</a>
  <a href="/reports/month" target="report-preview">Monthly</a>
</nav>
<iframe name="report-preview" src="/reports/week" title="Selected report preview"></iframe>
Back to quick reference ↑
08

Authenticate cross-window messages

Cross-origin frames cannot freely access each other's DOM, but postMessage provides an explicit data channel. Send to an exact target origin instead of * when the receiver is known. On receipt, validate origin, source window, message shape, and values before changing state; origin alone does not validate the payload.

Receive a validated resize request
const frame = document.querySelector('#trusted-widget');

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://widget.example') return;
  if (event.source !== frame.contentWindow) return;
  if (event.data?.type !== 'resize') return;
  if (!Number.isFinite(event.data.height)) return;

  frame.style.height = String(Math.min(event.data.height, 1000)) + 'px';
});
Back to quick reference ↑

Local code tester

Try a sandboxed inline frame

Edit a small srcdoc embed and observe how sizing and sandbox restrictions shape it.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. WHATWGHTML: The iframe elementhtml.spec.whatwg.org
  2. MDN Web DocsThe iframe elementdeveloper.mozilla.org
  3. MDN Web DocsWindow.postMessage()developer.mozilla.org
  4. World Wide Web ConsortiumPermissions Policyw3.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback