HTML iframe Table
| Piece | What it does | Field note |
|---|---|---|
<iframe> | Embeds another document | Every iframe is a full browsing context - weight accordingly |
src | The embedded URL | srcdoc embeds literal HTML instead - handy for sandboxed demos |
title | Accessible name | The one attribute screen readers require; "iframe" is not a name |
loading="lazy" | Defer offscreen loads | New default-worthy attribute - saves real bandwidth on long pages |
sandbox | Capability jail | Empty = maximum restrictions; add back only what the embed needs |
allow | Permissions policy | Camera, fullscreen, clipboard - per-frame grants |
referrerpolicy | Referer control | no-referrer for privacy-sensitive embeds |
width / height | Frame size | Set both + CSS aspect-ratio to stop layout shift (CLS) |
frameborder (legacy) | Border toggle | Deprecated - use CSS border: 0 |
srcdoc | Inline HTML document | Pairs with sandbox for zero-network demos |
csp | Embedded CSP | Experimental per-frame content-security-policy |
fetchpriority | Load priority hint | high for the map embed users came for, low for the rest |
An iframe loads an entire second web page inside yours - full browsing context, own JavaScript, own cookies, own network cost. That is its power and its price. The table below is the working twelve: the attributes that control what an embedded page can do, how eagerly it loads, and how much it disturbs the page around it.
Bottom line: three attributes cover most real deployments. title, because every accessibility audit finds iframes without one; loading="lazy" plus explicit width and height, because third-party embeds are the classic layout-shift source - reserve the box with CSS aspect-ratio and the page stops jumping; and sandbox with the smallest capability list that still works, because a compromised ad script should not inherit your origin's powers.
The honest part: the sandbox attribute is a jail with doors you open one by one. An empty sandbox allows almost nothing - scripts off, forms off, same-origin off - and each token you add (allow-scripts, allow-forms, allow-same-origin) grants a capability back. The dangerous combination is allow-scripts together with allow-same-origin on same-origin content: the embedded page can then remove its own sandbox. Pair the sandbox with srcdoc for zero-network demos and the jail stays sealed.
How to use
- Start the embed with the four defaults: src, title, width/height with CSS aspect-ratio, loading="lazy".
- Add capability attributes only as the embed proves it needs them: sandbox tokens, allow for fullscreen or clipboard, referrerpolicy for privacy.
- Audit the cost: every iframe is a second document - defer offscreen ones, and prefer first-party media elements over embed players when the content is yours.
Frequently asked questions
Why does every iframe need a title attribute?
Because assistive technology announces the frame by it: a screen reader user tabbing into an untitled iframe hears "frame" - no name, no purpose, no way to decide whether to enter. title is the iframe's accessible name (the same pattern as labeling a form input), and it is the single most common iframe failure in accessibility audits. Map embeds want title="Map of the store location"; payment frames want title="Payment form" - say what the frame contains, not what it is.
How does the sandbox attribute actually work?
It applies a default-deny policy: with no values, the embedded page cannot run scripts, submit forms, navigate the top page, or use plugins, and it is treated as a unique origin. Each token grants one capability back: allow-scripts (run JavaScript), allow-forms, allow-popups, allow-same-origin (keep its real origin for cookies and storage). The one combination to never ship with same-origin content is allow-scripts plus allow-same-origin - the framed page can then rewrite its own sandbox attribute, un-jailing itself. Third-party embeds ship with whatever token list their docs specify; your job is to not add more.
Do iframes slow down the page even when lazy?
loading="lazy" removes the network and render cost for frames below the fold - the browser skips them until they scroll near. What remains: the iframe element itself is cheap, but each frame that does load parses a full document with its own CSS and JavaScript, on the main thread of its own context. Maps, video players and social widgets are the usual heavyweights - lazy-load all of them, measure with the performance panel, and replace first-party content with native elements (a real <video> beats an embedded player for weight every time).
How do I stop an embed from shifting my layout?
Reserve the box before the frame loads: set width and height attributes (the intrinsic size), then CSS like aspect-ratio: 16 / 9 with width: 100% keeps the space stable at every screen size. The layout shift happens when the browser does not know the size until the embed's own document loads - which is always, for third parties. This is not cosmetic: layout shift is a Core Web Vitals metric, and unexpected movement from ads and embeds is the single largest CLS contributor on the average page.