Embedding Maps and Videos with iframe
An iframe shows a piece of another website, such as a YouTube video or a map, inside your page, and a few attributes keep it accessible, fast and safe.
Journeyman · HTML · Updated
After this lesson you can
- Embed a map or a video with an iframe that has a title and loads lazily
- Limit what an embed can do with sandbox, allow and referrerpolicy
- Choose between a video or audio element, an iframe embed and a plain link
Key takeaways
- An
<iframe>is a window in your page that shows another web page. Its src is that page's address. - Every iframe needs a title that says what it shows, because that's what a screen reader announces.
- loading="lazy" waits to load an embed until the visitor scrolls near it. Leave it off one at the top of the page.
- allow and sandbox limit what the embedded page may do, and referrerpolicy limits what it learns about your page.
- An embed costs speed and privacy. When a link does the job, use a link.
A café's contact page shows a map with a pin on its door. A band's page plays its new music video from YouTube. A blog post shows a weather widget or a sign-up form from another service. None of those sites built the map, the video player or the widget: they borrowed it from another site with one element, the iframe. You'll copy embed codes like these from YouTube, Google Maps and many other sites, so it helps to know what each attribute does before you paste one in.
The Bike Shed podcast recorded episode 12, Fixing a Flat in Ten Minutes, in its workshop by the river, and the episode page should show where that is.
A window into another site
A window in a wall lets you see into the next room without being in it. An <iframe> (short for inline frame) is a window in your page that shows another web page: a whole page, with its own HTML, styles and scripts, inside a box on yours.
<iframe src="https://www.openstreetmap.org/export/embed.html?bbox=-122.6775%2C45.5165%2C-122.6645%2C45.5235&layer=mapnik&marker=45.5200%2C-122.6710"
title="Map of The Bike Shed's workshop, beside the river"
width="640" height="480"></iframe>
srcis the address of the page to show. Each&in it is written&inside an HTML attribute.titlesays what's in the window. A screen reader announces it when it reaches the frame ("Map of The Bike Shed's workshop, frame"), and accessibility checks report a frame without one. Write what it shows, not "map" or "iframe".widthandheightare in pixels and save its space, as they do for a video.
Copying a share code
You rarely write an iframe from nothing. Most sites that let you embed give you the code: on YouTube, Share, then Embed; on Google Maps, Share, then Embed a map; on OpenStreetMap, Share, then HTML. YouTube's code looks like this (VIDEO_ID stands for the video's own ID):
<iframe width="560" height="315" src="https://www.youtube.com/embed/VIDEO_ID" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
It works as it is, but it's worth two changes before you paste it in:
- Replace the title. "YouTube video player" says nothing. Write what the video is:
title="Video: fixing a flat in ten minutes". - Remove
frameborder="0". It's an old attribute that HTML no longer uses, and the validator reports it. The frame's border is a job for the stylesheet.
YouTube also has a privacy-enhanced mode (the box Enable privacy-enhanced mode under the code): the address starts https://www.youtube-nocookie.com/embed/ instead, and YouTube stores less about your visitors until they press play.
Load it only when it's needed
A map at the bottom of a long page doesn't need to load before anyone scrolls down to it. loading="lazy" tells the browser to wait until the visitor scrolls near the iframe. This is lazy loading, and it works the same way on an <img>.
<iframe src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
title="Video: fixing a flat in ten minutes"
width="560" height="315"
loading="lazy"
allow="fullscreen; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"></iframe>
Leave loading="lazy" off an iframe that's on the first screen, the part of the page a visitor sees before scrolling: the browser would wait for nothing, and it would appear later than it should. Google Maps' embed code already has loading="lazy", but no title, so you add that one yourself.
Try it. Find your own town on openstreetmap.org, open Share, choose HTML, and copy the code into a page in your media-practice folder. Give it a title and loading="lazy", put it below several paragraphs of text, and open the page with Live Server. Press F12, open the Network tab, reload, and watch the map's files arrive only when you scroll down.
What the other site may do and learn
The page in the window belongs to someone else, so you decide what you let it do, and what you tell it about your page.
allowlists the powerful features the embedded page may use, separated by semicolons:fullscreen,picture-in-picture,autoplay, and more serious ones such ascamera,microphoneandgeolocation(the visitor's location). A powerful feature that isn't listed, it can't use. A video needsfullscreen; a map has no reason to get the camera. The olderallowfullscreenattribute in YouTube's code does the same asallow="fullscreen".referrerpolicydecides how much of your page's address is sent to the other site when the frame loads. Like the return address on an envelope, this referrer tells the other site where the request came from.strict-origin-when-cross-origin, which browsers use when you don't say, sends only your site's name (https://thebikeshed.example), not the page's full address.no-referrersends nothing; some players, YouTube's among them, may refuse to play when they can't tell which site they're on, so keep the value their share code gives you.
Locking it down with sandbox
A sandbox in a park lets children play without wandering into the street. The sandbox attribute puts the page in the frame in a sandbox. With no value, it blocks almost everything: scripts, forms, pop-up windows, downloads, sending your visitor's whole tab to another address, and reading its own site's cookies. Then you add back only what it needs, by name:
<iframe src="https://quiz.example.com/which-bike-fits-you"
title="Quiz: which bike fits you?"
width="640" height="480"
loading="lazy"
sandbox="allow-scripts allow-forms"></iframe>
This quiz from another site may run its scripts and its form, but it can't open pop-ups or take your visitor away from your page. Use sandbox for content you trust less: a widget from a small site, or code that other people paste into your site. A big player such as YouTube needs so much of it back (its scripts, its own cookies, pop-ups and full screen) that sites usually embed it without sandbox and limit it with allow instead.
What an embed costs, and when a link is enough
An iframe loads a whole other page: its HTML, its styles, its scripts and its fonts. A single YouTube embed can download hundreds of kilobytes before anyone presses play, and the other site learns that someone visited your page and may set its own cookies. Some sites refuse to be shown in a frame at all; the box then says the site refused to connect.
So pick the lightest thing that does the job:
| What you have | Use |
|---|---|
| Your own video or sound file | <video> or <audio>: no other site involved |
| A video on YouTube or a map people should explore on your page | An <iframe> with a title and loading="lazy" |
| Something people only need to open, such as directions | A plain link |
<p><a href="https://www.openstreetmap.org/?mlat=45.5200&mlon=-122.6710#map=17/45.5200/-122.6710">Get directions to the workshop</a></p>
A link loads nothing until it's clicked, works on every device, and on a phone often opens the visitor's own maps app.
Check yourself
2 questions to try on the lesson page.
So what
With one <iframe> your page can show a map, a video or a widget that another site keeps working for you. A title makes it accessible, loading="lazy" keeps your page fast, and allow, sandbox and referrerpolicy keep the other site in its box.