Question
I have a simple HTML page containing several <iframe> elements that display RSS-related pages. How can I apply the same CSS styles from the main page to the document displayed inside each iframe?
Short Answer
An iframe contains a separate HTML document, so CSS rules from the parent page do not automatically cross into it. You will learn how to style iframe content when both pages are under your control and on the same origin, plus what to do when embedded content comes from another website.
Concept
An <iframe> is not just a visual section of a page. It loads a complete, separate document with its own:
- HTML structure
- CSS stylesheets
- JavaScript environment
windowanddocumentobjects
Therefore, this CSS in a parent page affects the iframe element itself, but not the page loaded inside it:
iframe {
width: 100%;
border: 0;
}
To style the iframe's internal document, that document must load its own CSS. If you own both documents and they have the same origin, JavaScript can also access the iframe document and add a stylesheet dynamically.
An origin is generally the combination of protocol, host, and port. For example:
https://example.com/page.htmlandhttps://example.com/feed.htmlare usually same-origin.https://example.comandhttps://feeds.example.netare cross-origin.http://example.comandhttps://example.comare cross-origin because the protocol differs.
Browser security rules prevent a page from reading or changing cross-origin iframe content. This protects users from a malicious site embedding a bank or email site and trying to inspect private information.
Mental Model
Think of an iframe as a separate apartment inside a building.
- The parent page can paint the outside of the apartment door: the iframe's size, border, position, and background around it.
- The parent page cannot rearrange furniture inside the apartment just because it is in the same building.
- If you own both apartments and have the key (same origin), JavaScript can enter and make changes.
- If another organization owns the apartment (cross-origin), the browser does not give you the key.
The most reliable approach is to put the shared styling rules in a CSS file that both documents load.
Syntax and Examples
Style the iframe element from the parent document:
<!-- index.html -->
<iframe class="rss-frame" src="rss-view.html" title="RSS links"></iframe>
/* main.css */
.rss-frame {
display: block;
width: 100%;
min-height: 240px;
border: 1px solid #cbd5e1;
border-radius: 8px;
}
This styles the frame's box, not the content in rss-view.html.
To give both pages the same visual styles, load one shared stylesheet in each document:
<!-- index.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="shared.css">
</head>
<body>
<h1>News</h1>
<iframe class="rss-frame" src="rss-view.html" title="RSS links"></iframe>
</body>
</html>
<!-- rss-view.html -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="shared.css">
</head>
<body>
<ul class="feed-list">
<li><a href="/articles/1">New release notes</a></li>
<li><a href="/articles/2">Weekly engineering update</a></li>
</ul>
</body>
</html>
/* shared.css */
body {
margin: 0;
font-family: system-ui, sans-serif;
color: #1e293b;
}
.feed-list {
padding: 1rem 1.5rem;
}
a {
color: #2563eb;
}
The two documents remain separate, but they use identical CSS rules from the same file.
Step by Step Execution
Consider two files hosted at https://my-site.test:
<!-- parent.html -->
<iframe id="feed" src="feed.html" title="Feed"></iframe>
<script>
const frame = document.querySelector('#feed');
frame.addEventListener('load', () => {
const frameDocument = frame.contentDocument;
frameDocument.body.classList.add('embedded-feed');
});
</script>
<!-- feed.html -->
<style>
.embedded-feed {
background: #f8fafc;
font-family: Arial, sans-serif;
}
</style>
<p>Latest RSS item</p>
Execution flow:
- The browser loads
parent.html. - It creates the iframe and requests
feed.html. - The iframe finishes loading and emits its
loadevent. - The callback reads
frame.contentDocument, which representsfeed.html's document. - The script adds
embedded-feedto the iframe document's<body>. - The CSS declared in
feed.htmlmatches that class and changes the iframe content.
This works only when the parent and feed.html are same-origin. If src points to a different origin, accessing contentDocument may be unavailable or attempting to use its contents will be blocked by the browser.
Real World Use Cases
- Documentation previews: An application embeds HTML previews that use the same design system stylesheet as the main interface.
- Internal dashboards: A portal embeds reports generated by another route on the same company domain.
- Legacy migrations: A modern shell page embeds an older page while both gradually adopt shared CSS.
- Widget configuration: A site owns an iframe-based editor and applies a theme class after the editor loads.
- RSS presentation: Rather than embedding a third-party feed page, a server fetches and parses permitted feed data, then renders it in the site's own HTML template.
For third-party embeds such as a social media post, payment form, map, or externally hosted RSS viewer, use the provider's documented appearance options. The provider may offer query parameters, a configuration API, or a theme setting, but your parent CSS cannot override arbitrary content inside its iframe.
Real Codebase Usage
In real projects, developers usually avoid copying a large <style> block into every iframe page. Common patterns include:
- Shared stylesheet: Both the parent and iframe document load
shared.cssor a design-system stylesheet. - Theme variables: Each document loads the same CSS variables, such as
--brand-colorand--surface-color. - Iframe-specific stylesheet: The embedded page loads
embed.cssin addition to shared styles to remove margins or adjust compact layouts. - Same-origin initialization: A parent listens for
loadbefore usingiframe.contentDocumentoriframe.contentWindow. - Cross-origin messaging: If both applications cooperate but are hosted on different origins, they use
window.postMessage()to request supported theme changes. The iframe application must explicitly listen for and validate those messages. - Server-side rendering: For RSS data, the application often fetches the feed on the server or through a backend endpoint and renders the items directly, avoiding iframe styling and layout limitations.
A practical shared-theme setup might look like this:
<!-- In every document you control -->
<link rel="stylesheet" href="/assets/design-system.css">
<link rel="stylesheet" href="/assets/embed.css">
embed.css can be included only by iframe pages when they need embedded-specific adjustments.
Common Mistakes
Expecting parent selectors to enter the iframe
This does not style paragraphs inside the embedded page:
iframe p {
color: red;
}
An iframe is replaced content, not a normal container whose descendants CSS can select. Use CSS within the iframe document instead.
Styling only the iframe box
iframe {
background: black;
color: white;
}
This may affect the space around or behind the embedded document, but color does not automatically change text inside the iframe. Add styles to the iframe page.
Trying to access a cross-origin iframe with JavaScript
const frame = document.querySelector('iframe');
frame.contentDocument.body.style.color = 'red';
This is blocked when the iframe loads a different origin. You cannot bypass this with CSS, JavaScript, or CORS headers on the parent page.
Running code before the iframe loads
The iframe document may not exist yet when the parent script first runs. Wait for load:
frame.addEventListener('load', () => {
frame.contentDocument.body.classList.add('compact');
});
Assuming sandbox grants access
The sandbox attribute restricts iframe capabilities; it does not let a parent access cross-origin content. In fact, sandbox settings can make access more restrictive.
Embedding raw RSS XML
RSS feeds are often XML, not a styled HTML page designed for embedding. A better user experience is usually to parse the feed and render safe, formatted links in your own page.
Comparisons
| Approach | Can style iframe content? | Best use case |
|---|---|---|
Parent CSS targeting iframe | No, only the frame box | Set dimensions, borders, and layout |
| Shared CSS loaded by both documents | Yes | You control both same-origin documents |
Parent JavaScript with contentDocument | Yes, same-origin only | Small dynamic adjustments after loading |
postMessage() | Only if the iframe implements it | Cooperative cross-origin applications |
| Provider theme/configuration options | Sometimes | Third-party widgets and embeds |
| Render RSS data in the parent page | Yes | Full design control over feed content |
| Term | Meaning |
|---|---|
| Same-origin | Parent and iframe share compatible protocol, host, and port |
| Cross-origin | The pages differ by protocol, host, or port |
| CORS | A server mechanism for cross-origin network requests; it does not grant DOM access to iframe content |
Cheat Sheet
<!-- Style the iframe element -->
<iframe class="panel" src="embedded.html" title="Embedded content"></iframe>
.panel {
width: 100%;
height: 300px;
border: 0;
}
<!-- Put this in BOTH documents for shared styles -->
<link rel="stylesheet" href="/css/shared.css">
// Same-origin only: wait until the iframe has loaded.
const frame = document.querySelector('iframe');
frame.addEventListener('load', () => {
frame.contentDocument.body.classList.add('theme-dark');
});
Key rules:
- Parent CSS cannot select elements inside an iframe.
- An iframe page should normally load its own stylesheet.
- JavaScript access to iframe DOM content requires same-origin pages.
- CORS does not allow a parent to manipulate a cross-origin iframe's DOM.
- For third-party iframes, use documented customization options or render the data yourself.
FAQ
Can CSS from the parent page style an iframe's contents?
No. The parent stylesheet can style the <iframe> element but not the separate document loaded inside it.
How do I use the same CSS in a parent page and iframe?
Place shared rules in a CSS file, such as shared.css, and include that file with a <link> element in both HTML documents.
Can JavaScript style an iframe after it loads?
Yes, if the iframe document is same-origin. Listen for the iframe's load event, then use contentDocument or contentWindow.document.
Why do I get a cross-origin error when accessing an iframe?
The parent and iframe have different origins, such as different domains, protocols, or ports. The browser blocks access for security.
Does enabling CORS let me style an external iframe?
No. CORS controls certain network requests; it does not permit DOM access to a cross-origin iframe.
Can I style an external RSS feed inside an iframe?
Not unless the external site provides styling controls or you control its page. Usually, fetch or process the feed through an authorized backend and render the feed items in your own HTML.
Why should every iframe have a title?
A descriptive title helps screen-reader users understand the purpose of the embedded content.
Mini Project
Description
Create a small news dashboard that embeds a same-origin feed page. The parent page controls the frame layout, while the parent and feed page share a stylesheet so the interface has one consistent appearance.
Goal
Build a styled same-origin iframe whose internal content uses the same shared CSS as the main page.
Requirements
Create a parent page containing an iframe with a descriptive title. Create a separate HTML page to load inside the iframe. Use one shared CSS file in both documents. Style the iframe element independently for size and border. Display at least two feed links inside the embedded page.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.
Bootstrap Table Text Alignment Classes: Right-Align Currency Values
Learn Bootstrap text alignment utilities for table headers and cells, including .text-right in Bootstrap 3/4 and .text-end in Bootstrap 5.