Skip to content

<iframe> - Inline Frame Element

Embedded Content HTML 4.0

The iframe element creates a nested browsing context, allowing you to embed another HTML document within the current page. It’s commonly used for embedding third-party content like maps, videos, social media widgets, and external applications.

Result
<iframe src="url" title="description"></iframe>

The <iframe> element requires both opening and closing tags. Any content between the tags is displayed only if the browser doesn’t support iframes (rare in modern browsers).

AttributeDescriptionExample
srcURL of the embedded contentsrc="https://example.com"
titleAccessible description (required)title="Google Maps location"
widthWidth in pixels or percentagewidth="600" or width="100%"
heightHeight in pixelsheight="400"
nameName for targetingname="main-frame"
AttributeDescriptionExample
sandboxEnables security restrictionssandbox="allow-scripts"
allowPermissions Policy (formerly Feature Policy)allow="camera; microphone"
referrerpolicyControls referrer informationreferrerpolicy="no-referrer"
cspContent Security Policy for iframecsp="default-src 'self'"
AttributeDescriptionExample
loadingLazy loading behaviorloading="lazy" or loading="eager"
srcdocInline HTML contentsrcdoc="<p>Hello</p>"
allowfullscreenEnable fullscreen APIallowfullscreen
allowpaymentrequestAllow Payment Request APIallowpaymentrequest
AttributeDescriptionStatus
frameborderBorder around iframeDeprecated - use CSS
scrollingScrollbar behaviorDeprecated - use CSS
marginwidth, marginheightMarginsDeprecated - use CSS
alignAlignmentDeprecated - use CSS

The sandbox attribute is your primary defense against malicious iframe content. It applies strict restrictions unless explicitly relaxed.

Result
ValueDescriptionUse Case
(empty)Maximum restrictionsUntrusted content
allow-scriptsAllow JavaScript executionInteractive content
allow-same-originAllow same-origin accessAPI calls to parent domain
allow-formsAllow form submissionForms and inputs
allow-popupsAllow opening new windowsOAuth flows, external links
allow-popups-to-escape-sandboxPopups escape sandboxPayment gateways
allow-top-navigationAllow navigating parentFull-page navigation
allow-downloadsAllow file downloadsDocument viewers
allow-modalsAllow alert(), confirm()User confirmations
allow-orientation-lockLock screen orientationGames, video players
allow-pointer-lockCapture mouse pointerGames, 3D viewers
allow-presentationAllow Presentation APIScreen sharing
allow-storage-access-by-user-activationStorage access after user interactionEmbedded apps
<!-- Untrusted third-party content -->
<iframe
src="https://third-party.com/widget"
sandbox="allow-scripts"
title="Third-party widget">
</iframe>
<!-- User-generated content -->
<iframe
srcdoc="<h1>User Content</h1>"
sandbox
title="User preview">
</iframe>

The allow attribute controls which browser features the iframe can access.

Result
PermissionDescription
cameraAccess camera
microphoneAccess microphone
geolocationAccess location
autoplayAutoplay media
fullscreenEnter fullscreen mode
paymentPayment Request API
usb, bluetoothDevice access
accelerometer, gyroscopeMotion sensors
picture-in-picturePicture-in-picture mode

Implement CSP headers to control iframe sources:

<!-- In HTTP headers or meta tag -->
<meta http-equiv="Content-Security-Policy"
content="frame-src 'self' https://trusted-domain.com; frame-ancestors 'self';">

CSP Directives for Iframes:

  • frame-src: Controls which URLs can be embedded in iframes
  • frame-ancestors: Controls which sites can embed YOUR page in an iframe
  • child-src: Legacy fallback for frame-src
Result

Older method to prevent clickjacking (replaced by CSP frame-ancestors):

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
X-Frame-Options: ALLOW-FROM https://trusted-site.com

Use postMessage() API for secure cross-origin communication:

Result
Result
Result
Result
Result
Result
Result
Result

Loading Strategies:

  • loading="lazy": Load when near viewport (default for off-screen iframes)
  • loading="eager": Load immediately
  • No attribute: Browser decides (usually immediate)
<!-- Low priority iframe -->
<iframe
src="https://ads.example.com"
importance="low"
loading="lazy">
</iframe>
<!-- High priority iframe -->
<iframe
src="https://critical-app.com"
importance="high">
</iframe>
Result
Result
Result
Result
Result
Result
<iframe
src="https://www.youtube.com/embed/dQw4w9WgXcQ"
title="Rick Astley - Never Gonna Give You Up (Official Video)"
width="560"
height="315">
</iframe>
<iframe
src="https://maps.google.com/maps?q=london&output=embed"
title="Google Maps showing London, United Kingdom">
</iframe>
Result
Result
Result
FeatureChromeFirefoxSafariEdge
Basic <iframe>1+1+1+12+
sandbox4+17+5+10+
sandbox tokensVariesVariesVariesVaries
allow (Permissions Policy)60+74+11.1+79+
loading77+77+16.4+79+
srcdoc20+25+6+79+
referrerpolicy51+50+11.1+79+
csp61+79+

Error: Refused to display 'https://example.com' in a frame because it set 'X-Frame-Options' to 'deny'.

Solution: The target site prevents embedding. You cannot override this. Options:

  1. Contact site owner for permission
  2. Use site’s official embed API if available
  3. Link to content instead of embedding

Error: Blocked a frame from accessing a cross-origin frame.

Solution: Use postMessage() for cross-origin communication. You cannot directly access cross-origin iframe content.

Error: Mixed Content: The page was loaded over HTTPS, but requested an insecure frame.

Solution: Always use HTTPS for iframe src when parent page is HTTPS:

<!-- Change this -->
<iframe src="http://example.com"></iframe>
<!-- To this -->
<iframe src="https://example.com"></iframe>

Solution: Use aspect ratio padding technique:

Result
  • Always use sandbox attribute for untrusted content
  • Never combine allow-scripts and allow-same-origin for untrusted sources
  • Implement CSP with frame-src and frame-ancestors
  • Use allow attribute to restrict permissions
  • Validate event.origin in postMessage handlers
  • Use HTTPS for all iframe sources
  • Include descriptive title attribute
  • Set referrerpolicy to limit referrer information
  • Use loading="lazy" for below-fold iframes
  • Regularly audit third-party iframe sources