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.
-
HTML Basics
- What is HTML: The Structure Layer of Every Web Page
- HTML Document Structure: DOCTYPE, html, head and body
- Elements, Tags and Attributes: The Vocabulary of HTML
- HTML Comments: Notes That Ship With Your Code
- Block Level and Inline Elements
- Writing and Running Your First HTML Page
- How a Browser Turns Markup Into a Page
- Text and Formatting
- Links and Navigation
- Images and Media
- Lists
- Tables
-
Forms
- Form Structure: form, action and method
- Input Types: Text, Email, Number, Date and the Rest
- Labels: The Most Important Element in a Form
- Checkboxes, Radio Buttons and Grouping
- select, option, optgroup and datalist
- textarea, File Uploads and Hidden Fields
- Buttons: submit, reset and button
- Built In Form Validation
- GET or POST: What Happens When a Form Is Submitted
- Semantic HTML
- HTML5 Features
- Head and Metadata
- HTML with CSS
- HTML with JavaScript
- Accessibility
-
HTML SEO
- How Google Works: Crawling, Indexing and Ranking
- SEO Friendly HTML Structure
- Titles and Descriptions That Earn Clicks
- Headings and Content Structure for Search
- Internal Linking and Anchor Text
- robots.txt and XML Sitemaps
- Canonical URLs and Duplicate Content
- Structured Data and JSON-LD
- Image SEO
- Core Web Vitals and Mobile Friendliness
- DevTools and Debugging
- Editor Productivity
- HTML Best Practices
- HTML Projects
- Advanced Projects
- Practice and Exams
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>| Token | Grants |
|---|---|
allow-scripts | Run JavaScript |
allow-same-origin | Treat the content as its own origin, so it can read its own storage |
allow-forms | Submit forms |
allow-popups | Open new windows |
allow-top-navigation | Navigate the page containing the frame |
allow-downloads | Start 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
iframeneeds atitle. - An
iframeis 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-ancestorsrefusal.
Common mistakes
- Omitting
title, leaving screen reader users with an unlabelled frame. - Fixed
widthandheighton 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:
videofor 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-ancestorson your own sensitive pages.
Practice
- Embed a video in a responsive sixteen by nine wrapper and confirm it keeps its shape from three hundred to fifteen hundred pixels wide.
- Measure a page with three eager embeds, then add
loading="lazy"and measure again. - Sandbox an embedded page so it can display but cannot run scripts or submit forms.
- Explain what
frame-ancestorsprotects against, and which of your pages need it.