srcdoc
Embed inline HTML content in an iframe without a separate document. Useful for sandboxed previews, user-generated content isolation, and self-contained examples.
Overview
The srcdoc attribute on <iframe> lets you embed inline HTML content directly in the attribute value, without pointing to a separate URL. The iframe renders the provided HTML as a complete document in its own browsing context.
Applies to: <iframe>
When both srcdoc and src are present, srcdoc takes priority. The src serves as a fallback for browsers that do not support srcdoc (all modern browsers do).
Values
| Attribute | Value | Behavior |
|---|---|---|
srcdoc | HTML string (escaped) | Renders the HTML as the iframe's content |
src | URL | Fallback if srcdoc is absent or unsupported |
Basic Usage
Provide HTML content as the attribute value. All HTML special characters must be escaped since they are inside an attribute.
<!-- Inline HTML content inside an iframe --><iframe srcdoc="<h1>Hello</h1><p>This is inline content.</p>" title="Inline content example" width="400" height="200"></iframe>
Escaping Requirements
Because srcdoc content lives inside an HTML attribute, you must escape HTML entities. This is the most common pain point with srcdoc.
<!-- HTML must be escaped in the attribute value --><iframe srcdoc=" <style> body { font-family: system-ui; padding: 1rem; } h1 { color: #333; } </style> <h1>Styled Content</h1> <p>This includes its own <code>style</code> block.</p>" title="Styled inline content" width="400" height="200"></iframe> <!-- Character escaping rules: < becomes < > becomes > & becomes & " becomes " (if using double-quoted attribute)-->
Sandboxed Content
Pair srcdoc with the sandbox attribute for secure content isolation. The content runs in a unique origin, completely separated from the parent page.
<!-- Sandboxed preview: no scripts, no forms, no navigation --><iframe srcdoc="<h2>User Post</h2><p>This content is isolated.</p>" sandbox title="User post preview" width="100%" height="150"></iframe> <!-- Allow scripts but nothing else --><iframe srcdoc="<script>document.write('Dynamic content')</script>" sandbox="allow-scripts" title="Scripted preview" width="100%" height="100"></iframe>
Priority over src
When both attributes are present, srcdoc wins. This originally allowed for graceful degradation to a server-rendered URL in older browsers.
<!-- srcdoc takes priority over src --><iframe src="https://example.com" srcdoc="<p>This content is shown instead of example.com.</p>" title="srcdoc priority demo" width="400" height="100"></iframe> <!-- The src acts as a fallback for browsers that don't support srcdoc (all modern browsers support it, so this is mainly historical) -->
Live Preview Pattern
A common use case is a live HTML preview that updates as the user types. Set the iframe's srcdoc property via JavaScript for dynamic content.
<label for="html-input">Enter HTML:</label><textarea id="html-input" rows="6" cols="50"><h1>Hello</h1><p>Edit me!</p></textarea> <iframe id="preview" sandbox="allow-scripts" title="Live preview" width="100%" height="200"></iframe> <script>const textarea = document.getElementById('html-input');const preview = document.getElementById('preview'); textarea.addEventListener('input', () => { preview.srcdoc = textarea.value;}); // Initial renderpreview.srcdoc = textarea.value;</script>
Email Rendering
Email clients often render HTML emails in iframes to isolate the email's styles and scripts from the application UI. The srcdoc + sandbox combination is ideal for this.
<!-- Render email HTML safely in an isolated context --><iframe srcdoc="<!-- email HTML content here -->" sandbox title="Email preview" width="100%" height="400" style="border: 1px solid #ccc;"></iframe> <!-- The sandbox attribute without any allow-* tokens prevents: - JavaScript execution - Form submission - Link navigation to parent - Popups - Plugin content-->
Accessibility
- Always provide a
titleattribute on iframes usingsrcdoc. Screen readers announce the title to help users understand the iframe's purpose. - The content inside the iframe is a separate document with its own accessibility tree. Ensure the inline HTML is well-structured with headings and landmarks.
- Sandboxed iframes that prevent keyboard navigation can trap focus. Test keyboard flow into and out of the iframe.
Limitations
- HTML escaping makes complex content hard to read in source code. For longer content, setting
iframe.srcdocvia JavaScript avoids the escaping burden. - The content has a unique, opaque origin. It cannot access the parent page's cookies, localStorage, or DOM (and the parent cannot access the iframe's DOM when sandboxed).
- There is no way to link to a specific anchor within a
srcdociframe from the parent page. - Very large
srcdocvalues can bloat the HTML document size, since the content is inline rather than loaded on demand. - The
srcdoccontent does not have a URL, so it cannot be bookmarked, shared, or opened in a new tab.
See Also
sandbox— restrict iframe capabilities for security<iframe>— the iframe elementloading— lazy-load iframes below the foldreferrerpolicy— control referrer for iframe requests