HTML <iframe> Tag
The HTML <iframe> tag embeds another document inline. Learn its attributes, the sandbox and allow security features, and lazy loading.
The <iframe> tag (short for inline frame) embeds another HTML document inside the current page. It is the standard way to display third-party content such as a video player, a map, an advertisement, or a sandboxed widget. The embedded document is loaded into a nested browsing context that is independent of the host page, but the two can interact through JavaScript when they share the same origin.
This page covers the <iframe> syntax, its attributes, how to size and style a frame, browser-native lazy loading, and the two features you should reach for whenever you embed content you don't fully control: sandbox and allow.
For embedding non-HTML resources, see also the <embed> and <frame> tags.

Syntax
The <iframe> tag is a normal HTML element that requires a closing tag. Always add a title attribute (see Accessibility below).
Example of an HTML <iframe> Tag
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<iframe src="https://www.w3docs.com" title="W3docs homepage"></iframe>
</body>
</html>To set the size of iframe, use the height and width attributes, or use CSS. The attribute values are set in pixels by default, but they can also be in percent.
Example of an HTML <iframe> Tag With the Height and Width Attributes
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<iframe src="https://www.w3docs.com" title="W3docs homepage" width="80%" height="300"></iframe>
</body>
</html>Modern browsers do not apply a default border to iframes. You can still use the CSS border property to style the frame if needed.
Example of an HTML <iframe> Tag With the CSS Border Property
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<iframe src="https://www.w3docs.com" title="W3docs homepage" width="80%" height="300" style="border: none"></iframe>
</body>
</html>Embedding inline HTML with srcdoc
Instead of pointing at a URL with src, you can supply the frame's entire markup inline using the srcdoc attribute. This is handy for previews, sandboxed snippets, or generated HTML where you don't have a separate file or URL. When both attributes are present, srcdoc takes precedence (with src used as a fallback for browsers that don't support srcdoc).
<iframe
title="Inline greeting"
srcdoc="<!DOCTYPE html><html><body><h1>Hello from srcdoc!</h1></body></html>">
</iframe>Because the markup lives in an HTML attribute, any literal double quotes inside it must be written as " and any ampersands as &.
Lazy loading offscreen iframes
The loading attribute lets the browser defer loading an iframe until it is about to scroll into view. Native lazy loading is now a stable web standard, supported in all modern browsers since around 2020, so you no longer need a JavaScript library for this common case.
Supported values:
lazy— defers the load until the iframe is near the viewport. Recommended for offscreen frames (video players, maps, ad slots) that aren't visible on first paint.eager— loads the resource immediately, regardless of its position. This is the default.
<iframe src="video-player.html" title="Promo video" loading="lazy"></iframe>Deferring offscreen iframes reduces initial page weight, speeds up first load, and avoids spending the user's bandwidth on content they may never scroll to.
Restricting content with the sandbox attribute
By default, an embedded page can run scripts, submit forms, open pop-ups, navigate the top-level page, and read cookies for its own origin. When you embed content you don't fully control, that is a security risk. The sandbox attribute applies a strict set of restrictions, then lets you re-enable only the capabilities the frame actually needs by listing space-separated tokens.
An empty sandbox (i.e. sandbox="") applies all restrictions: no scripts, no forms, no pop-ups, no plugins, and the content is forced into a unique opaque origin. You then loosen it token by token:
| Token | Re-enables |
|---|---|
allow-forms | Form submission. |
allow-same-origin | Treating the content as same-origin (so it can use its own cookies and storage). |
allow-scripts | Running JavaScript. |
allow-popups | Opening new windows or tabs (e.g. window.open, target="_blank"). |
allow-downloads | Triggering file downloads. |
allow-modals | Showing modal dialogs like alert(), confirm(), and prompt(). |
allow-top-navigation | Navigating the top-level browsing context (the parent page). |
allow-pointer-lock | Using the Pointer Lock API. |
Combine allow-scripts and allow-same-origin with care: granting both to content from another origin effectively lets that content remove its own sandbox, so only do it for content you trust.
Example of a Sandboxed <iframe>
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<iframe
src="https://example.com/widget.html"
title="Third-party widget"
sandbox="allow-scripts allow-forms">
</iframe>
</body>
</html>Here the widget may run scripts and submit forms, but it cannot navigate the parent page, open pop-ups, or access same-origin cookies and storage.
Granting browser features with the allow attribute
While sandbox controls the basic browsing-context restrictions, the allow attribute sets a Permissions Policy for the frame — it decides which powerful browser features (camera, microphone, geolocation, fullscreen, autoplay, etc.) the embedded document may use. Most of these features are blocked in cross-origin iframes unless you opt in with allow.
<iframe
src="https://example.com/player.html"
title="Video player"
allow="fullscreen; camera 'none'">
</iframe>This grants the frame permission to enter fullscreen while explicitly denying access to the camera. You can scope a feature to specific origins, e.g. allow="geolocation 'self' https://maps.example.com".
Accessibility
Every <iframe> should have a title attribute that briefly describes the frame's purpose. Screen readers announce the title so users understand what the embedded content is before entering it; without a title, the frame is announced only as an unlabeled "frame", which is confusing.
<iframe src="map.html" title="Map showing our office location"></iframe>Use a concise, unique title for each iframe on the page (for example "Customer feedback survey" rather than just "iframe").
When a page refuses to be framed
Embedding doesn't always succeed: the page you point src at can refuse to be displayed inside a frame. Sites do this to prevent clickjacking, where an attacker overlays a hidden frame on top of their own UI. A page can opt out of being framed in two ways:
- The legacy
X-Frame-OptionsHTTP response header (DENYorSAMEORIGIN). - The modern Content-Security-Policy
frame-ancestorsdirective, e.g.Content-Security-Policy: frame-ancestors 'self'.
If a target site sends either of these, your iframe will show a blank or error frame instead of the content — this is expected behavior, not a bug in your markup. Many large sites (banks, social networks) block framing for security, which is why you can't embed them directly.
Attributes
| Attribute | Value | Description |
|---|---|---|
| align | left right top bottom middle | Specifies how text is aligned and wrapped around the frame. Not supported in HTML5. |
| allow | string | Specifies a policy that allows or restricts certain features in the iframe. |
| allowfullscreen | Defines that the frame can be opened in a full screen mode. | |
| frameborder | 1 0 | Defines if the iframe border around the frame should be displayed or not. Not supported in HTML5. |
| height | pixels | Defines the height of the frame (default height 150px). |
| longdesc | URL | Defines a page which has a long description of the content. Not supported in HTML5. |
| marginheight | pixels | Defines the top and bottom margins of the frame. Not supported in HTML5. |
| marginwidth | pixels | Defines the left and right margins of the frame. Not supported in HTML5. |
| loading | eager lazy | Sets whether the frame loads immediately or is deferred until near the viewport. |
| name | text | Defines the name of the frame (a target for links and forms). |
| referrerpolicy | keyword | Sets which referrer info to send with the request. Takes a keyword such as no-referrer, origin, or strict-origin-when-cross-origin — not a URL. |
| sandbox | token list | Applies extra restrictions to the frame's content. Empty (sandbox="") applies all restrictions; add space-separated tokens such as allow-scripts or allow-forms to relax them. See the sandbox section. |
| scrolling | yes no auto | Defines whether the scroll bar should be displayed or not. Not supported in HTML5. |
| seamless | seamless | Specifies that the contents of the attached document should be displayed as part of the parent document. |
| src | URL | Specifies the address of the document whose contents will be loaded into the frame. |
| srcdoc | HTML code | Stores the contents of the frame directly in the attribute, instead of loading a separate URL. |
| title | text | Describes the frame's content for assistive technology. Should be present on every iframe. |
| width | pixels | Defines the width of the frame. (default width is 300px). |
The <iframe> tag supports the Global attributes and the Event Attributes.
Related tags
- HTML
<frame>Tag — defines a single frame within a<frameset>(legacy framesets, obsolete in HTML5). - HTML
<embed>Tag — embeds external content such as a plugin or media resource.