49

How do I make an <iframe> inherit its parent's styles and javascript.

I have tried

var parentHead = $("head", parent.document).html();
$("head").html(parentHead);

But, it strips out the <script> tags. Moreover, I do not see the styles affecting my iframe.

Is there a better/any other approach to this that I'm missing? Thanks.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
Robin Maben
  • 22,194
  • 16
  • 64
  • 99

4 Answers4

52

You can "inherit" the CSS of the parent by having such code in the iframe:

<head>
<script type="text/javascript">
window.onload = function() {
    if (parent) {
        var oHead = document.getElementsByTagName("head")[0];
        var arrStyleSheets = parent.document.getElementsByTagName("style");
        for (var i = 0; i < arrStyleSheets.length; i++)
            oHead.appendChild(arrStyleSheets[i].cloneNode(true));
    }
}
</script>
</head>

Worked fine for me in IE, Chrome and Firefox.

Regarding JavaScript, I couldn't find a way to add the parent JavaScript into the iframe directly, however you can add parent. anywhere to use the JS from within the parent, for example:

<button type="button" onclick="parent.MyFunc();">Click please</button>

This will invoke function called MyFunc defined in the parent page when the button is clicked.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • 8
    I think the element you should look for in the head of the parent is not `style` but `link`. – Bazzz Jan 06 '11 at 14:49
  • 27
    Be aware that you cannot do this across domains - the iframe must be local for the child to be able to interrogate the parent's DOM. – RET Jun 10 '11 at 06:45
  • But the point of inheriting the styles and js would be not to call them again on the child page, therefore loading them only once at the parent. It seems that this approach does not helps on that issue. – anakin Nov 09 '15 at 20:47
  • @anakin I admit, I don't know of a way to do that without calling them again. Do you mean something like in [this other answer](http://stackoverflow.com/a/28217534/447356)? – Shadow The GPT Wizard Nov 11 '15 at 19:49
  • Excellent except that I did it from iframe to parent for a decent hack! – Nishant Apr 09 '16 at 12:45
  • @Nishant not sure, what do you mean? – Shadow The GPT Wizard Apr 09 '16 at 15:52
  • I had to customize a jQuery based `wysiwyg` editor which gets constructed in its own Iframe by adding a few jQuery dialog widgets. For some reason the jquery widgets needed to be created in main Dom and attached to the Iframe. css was causing a lot of problem though since parent didn't have jQuery UI css. I managed to copy all the css from Iframe into parent Dom i.e reverse of the op's question and it worked fine. Otherwise I would have had to figure out how to get everything loaded in parent Dom. – Nishant Apr 09 '16 at 16:39
  • Inherit JQuery var $ = window.parent.$, jQuery = window.parent.jQuery; – Arun Prasad E S Jun 30 '17 at 06:48
24

Here is my "best of" solution to add the styles of the iframe's parent (not the scripts). It works with IE6-11, Firefox, Chrome, (old) Opera and probably everywhere.

function importParentStyles() {
    var parentStyleSheets = parent.document.styleSheets;
    var cssString = "";
    for (var i = 0, count = parentStyleSheets.length; i < count; ++i) {
        if (parentStyleSheets[i].cssRules) {
            var cssRules = parentStyleSheets[i].cssRules;
            for (var j = 0, countJ = cssRules.length; j < countJ; ++j)
                cssString += cssRules[j].cssText;
        }
        else
            cssString += parentStyleSheets[i].cssText;  // IE8 and earlier
    }
    var style = document.createElement("style");
    style.type = "text/css";
    try {
        style.innerHTML = cssString;
    }
    catch (ex) {
        style.styleSheet.cssText = cssString;  // IE8 and earlier
    }
    document.getElementsByTagName("head")[0].appendChild(style);
}
Tobias81
  • 1,820
  • 1
  • 16
  • 17
  • This one is very good answer. But missing the importedCssRules if parent had. – joydesigner Sep 10 '15 at 23:37
  • This will have issue in IE while accessing cssText in some cases i.e. keyframe rules. You will get "Member not found" https://connect.microsoft.com/IE/feedback/details/955703/accessing-csstext-of-a-keyframe-rule-that-contains-a-webkit-property-via-cssom-generates-exception – Tejasvi Hegde Oct 26 '16 at 12:01
  • This an awesome answer. You might want to access the `cssRules` property in a try...catch block though, because the access might be denied in some cases. – Marcin Wanago Nov 09 '20 at 15:25
1

You can always collect all styles to string and set it as innerHTML of style element in iframe.

var selfStyleSheets = document.styleSheets;
var cssString = [];
for (var i = 0, count = selfStyleSheets.length; i < count; i++)
{
    var cssRules = selfStyleSheets[i].cssRules;
    for (var j = 0, countJ = cssRules.length; j < countJ; j++)
    {
        cssString.push(cssRules[j].cssText);
    }
}
var styleEl = iframe.contentDocument.createElement('style');
styleEl.type = 'text/css';
styleEl.innerHTML = cssString.join("\n");

iframe.contentDocument.head.appendChild(styleEl);
Alexey
  • 65
  • 2
  • Doesn't work with IE6-8 (if that matters). It also doesn't actually answer the question, because it does the opposite (adds the iframe's styles to the parent). – Tobias81 Jan 29 '15 at 14:49
-1
var cssLink = document.createElement("link") 
cssLink.href = "style.css"; 
cssLink .rel = "stylesheet"; 
cssLink .type = "text/css"; 
frames['frame1'].document.body.appendChild(cssLink);

And stlye.css as parent's style? Not sure about javascript, but possibly same way.

Badr Hari
  • 8,114
  • 18
  • 67
  • 100