Embedding External Content with iframe

An iframe puts another page inside yours. Learn the YouTube and maps patterns, the title attribute screen readers need, and the sandbox and loading attributes that keep it safe and fast.

Concept

An iframe - an inline frame - embeds another complete HTML document inside the current one. Videos from a hosting service, maps, payment forms, comment systems and analytics dashboards are almost always delivered this way.

Everything inside the frame is a separate document with its own URL, its own stylesheet, its own scripts and its own security origin. Your CSS cannot reach into it and its CSS cannot leak out.

Syntax

<iframe src="https://example.com/widget"
        title="Live bus arrivals for Sadar Bazaar"
        width="600" height="400"
        loading="lazy"></iframe>

The title attribute is not decoration. It is the accessible name of the frame, and screen reader users navigate a page by frame just as they navigate by heading. A frame with no title is announced as frame, which tells the reader nothing about whether it is worth entering.

Embedding a video

<div class="embed-16x9">
  <iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
          title="Campus tour, 2026 intake"
          loading="lazy"
          allow="accelerometer; clipboard-write; encrypted-media; picture-in-picture"
          allowfullscreen></iframe>
</div>
.embed-16x9 {
  position: relative;
  aspect-ratio: 16 / 9;
}
.embed-16x9 iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

Three details worth copying. The nocookie host avoids setting tracking cookies until the reader actually plays something. loading="lazy" matters more here than on an image, because an embedded player pulls in a page of its own worth several hundred kilobytes. And the aspect ratio wrapper keeps the video the right shape at every width, which a fixed width and height cannot do.

Embedding a map

<iframe src="https://www.openstreetmap.org/export/embed.html?bbox=73.85,18.51,73.87,18.53"
        title="Map showing the college main gate on Sadar Bazaar Road"
        width="100%" height="360"
        loading="lazy"
        style="border:0"></iframe>

<p><a href="https://www.openstreetmap.org/?mlat=18.52&mlon=73.86">Open a larger map</a></p>

Always provide a text alternative next to a map: the address in writing, and a link out to a full map application. A map inside a frame is difficult to use with a keyboard and impossible to read aloud.

The sandbox attribute

By default a framed page can run scripts, submit forms, open pop ups and navigate the top level window. sandbox switches all of that off, and you then grant back only what is needed.

<!-- everything blocked -->
<iframe src="/preview" title="Document preview" sandbox></iframe>

<!-- scripts and same origin data allowed, nothing else -->
<iframe src="/preview" title="Document preview"
        sandbox="allow-scripts allow-same-origin"></iframe>
TokenGrants
allow-scriptsRun JavaScript
allow-same-originTreat the content as its own origin, so it can read its own storage
allow-formsSubmit forms
allow-popupsOpen new windows
allow-top-navigationNavigate the page containing the frame
allow-downloadsStart a download

Granting allow-scripts together with allow-same-origin to content from your own origin effectively removes the sandbox, because the framed page can then rewrite its own attributes. That combination is only safe for content you fully control.

Preventing your own pages being framed

Clickjacking is the attack where a hostile site loads your page invisibly over its own and tricks a reader into clicking your buttons. The defence is a response header, not markup:

Content-Security-Policy: frame-ancestors 'self'

X-Frame-Options: SAMEORIGIN        (older header, still widely honoured)

Any page with a login form, a payment step or a destructive action should send one of these.

Important rules

  • Every iframe needs a title.
  • An iframe is a full document load. Three embeds on a page can easily triple its weight.
  • Cross origin frames are isolated: no script on either side can reach the other except through the messaging API.
  • Content in a frame is another origin for cookie and privacy purposes, and often a tracking vector.
  • loading="lazy" works on iframes and should be the default for anything below the fold.
  • Some sites refuse to be framed. If a frame renders blank, check the console for a frame-ancestors refusal.

Common mistakes

  • Omitting title, leaving screen reader users with an unlabelled frame.
  • Fixed width and height on a video embed, which then overflows the viewport on a phone.
  • Loading five embedded players eagerly at the top of an article.
  • Embedding a map with no address in text beside it.
  • Using sandbox="allow-scripts allow-same-origin" on untrusted content and assuming it is contained.
  • Framing another site without checking whether you are permitted to.

Best practices

  • Prefer a native element when one exists: video for a self hosted clip beats an embedded player.
  • Wrap video embeds in an aspect ratio container.
  • Add loading="lazy" to everything below the fold.
  • Use privacy respecting embed hosts where they exist.
  • Consider a facade: show a poster image and load the real embed only when the reader clicks. It can save hundreds of kilobytes on a page nobody plays.
  • Send frame-ancestors on your own sensitive pages.

Practice

  1. Embed a video in a responsive sixteen by nine wrapper and confirm it keeps its shape from three hundred to fifteen hundred pixels wide.
  2. Measure a page with three eager embeds, then add loading="lazy" and measure again.
  3. Sandbox an embedded page so it can display but cannot run scripts or submit forms.
  4. Explain what frame-ancestors protects against, and which of your pages need it.

Useful resources

Hand picked references for this topic
Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All HTML notes →
HTML

Audio and Video in HTML

Native media playback with no plugin. Learn the controls, the source fallback pattern, autoplay rules that will catch you out, and why captions are no...

Read more

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.