web-dev-qa-db-fra.com

Comment appliquer le CSS à l'iframe?

J'ai une page simple qui a quelques sections iframe (pour afficher des liens RSS). Comment appliquer le même format CSS de la page principale à la page affichée dans l'iframe?

955
John

Edit: Cela ne fonctionne pas entre domaines sauf si le en-tête CORS approprié est défini.

Il y a deux choses différentes ici: le style du bloc iframe et le style de la page incorporée dans l'iframe. Vous pouvez définir le style du bloc iframe de la manière habituelle:

<iframe name="iframe1" id="iframe1" src="empty.htm" 
        frameborder="0" border="0" cellspacing="0"
        style="border-style: none;width: 100%; height: 120px;"></iframe>

Le style de la page incorporée dans l'iframe doit être défini en l'incluant dans la page enfant:

<link type="text/css" rel="Stylesheet" href="Style/simple.css" />

Ou il peut être chargé à partir de la page parent avec Javascript:

var cssLink = document.createElement("link");
cssLink.href = "style.css"; 
cssLink.rel = "stylesheet"; 
cssLink.type = "text/css"; 
frames['iframe1'].document.head.appendChild(cssLink);
418
Tamas Czinege

J'ai rencontré ce problème avec Google Calendar. Je voulais le styler sur un fond plus sombre et changer de police.

Heureusement, l'URL du code incorporé n'avait aucune restriction sur l'accès direct. Ainsi, en utilisant PHP fonction file_get_contents, il est possible d'obtenir le contenu complet de la page. Au lieu d'appeler l'URL de Google, il est possible d'appeler un fichier php situé sur votre serveur, ex. google.php, qui contiendra le contenu original avec les modifications:

$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');

Ajout du chemin à votre feuille de style:

$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);

(Cela placera votre feuille de style en dernier juste avant la balise de fin head.)

Spécifiez l'URL de base à partir de l'URL d'origine si css et js sont appelés relativement:

$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);

Le fichier final google.php devrait ressembler à ceci:

<?php
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
echo $content;

Ensuite, vous modifiez le code incorporé iframe en:

<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>

Bonne chance!

194

Si le contenu de l'iframe n'est pas entièrement sous votre contrôle ou si vous souhaitez accéder au contenu de pages différentes avec des styles différents, vous pouvez essayer de le manipuler à l'aide de JavaScript.

var frm = frames['frame'].document;
var otherhead = frm.getElementsByTagName("head")[0];
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "style.css");
otherhead.appendChild(link);

Notez que selon le navigateur que vous utilisez, cela pourrait ne fonctionner que sur les pages servies à partir du même domaine.

72
Horst Gutmann
var $head = $("#eFormIFrame").contents().find("head");

$head.append($("<link/>", {
    rel: "stylesheet",
    href: url,
    type: "text/css"
}));
58
Rami Sarieddine

Un iframe est géré universellement comme une page HTML différente par la plupart des navigateurs. Si vous souhaitez appliquer la même feuille de style au contenu de l'iframe, il suffit de la référencer à partir des pages utilisées.

33
hangy

Voici comment appliquer directement du code CSS sans utiliser <link> pour charger une feuille de style supplémentaire.

var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
          '#banner{display:none}; ' +
          '</style>';
jQuery(head).append(css);

Cela cache la bannière dans la page iframe. Merci pour vos suggestions!

28
domih

Si vous contrôlez la page dans l'iframe, comme l'a dit hangy, la méthode la plus simple consiste à créer un fichier CSS partagé avec des styles communs, puis créez un lien vers ce dernier à partir de vos pages html.

Sinon, il est peu probable que vous puissiez modifier dynamiquement le style d'une page à partir d'une page externe de votre iframe. Cela est dû au fait que les navigateurs ont renforcé la sécurité des scripts dom cross frame en raison d’une possible utilisation abusive pour usurpation de contenu et autres piratages.

Ce tutoriel peut vous fournir plus d'informations sur les scripts iframes en général. À propos des scripts inter-images explique les restrictions de sécurité de la perspective IE.

27
Ash

Ce qui précède avec un peu de changement fonctionne:

var cssLink = document.createElement("link") 
cssLink.href = "pFstylesEditor.css"; 
cssLink.rel = "stylesheet"; 
cssLink.type = "text/css"; 

//Instead of this
//frames['frame1'].document.body.appendChild(cssLink);
//Do this

var doc=document.getElementById("edit").contentWindow.document;

//If you are doing any dynamic writing do that first
doc.open();
doc.write(myData);
doc.close();

//Then append child
doc.body.appendChild(cssLink);

Fonctionne bien avec ff3 et ie8 au moins

21
Tom Merchant

Si vous souhaitez réutiliser CSS et JavaScript à partir de la page principale, vous devriez peut-être envisager de remplacer <IFRAME> par un contenu chargé avec Ajax. C’est plus convivial maintenant, lorsque les robots de recherche sont capables d’exécuter JavaScript.

Ceci est jQuery exemple qui inclut une autre page HTML dans votre document. Ceci est beaucoup plus convivial que iframe. Afin de vous assurer que les robots ne sont pas en train d'indexer la page incluse, ajoutez-la pour la désactiver dans robots.txt

<html>
  <header>
    <script src="/js/jquery.js" type="text/javascript"></script>
  </header>
  <body>
    <div id='include-from-outside'></div>
    <script type='text/javascript'>
      $('#include-from-outside').load('http://example.com/included.html');
    </script> 
  </body>
</html>

Vous pouvez également inclure jQuery directement à partir de Google: http://code.google.com/apis/ajaxlibs/documentation/ - cela signifie l'inclusion automatique facultative des versions les plus récentes et une augmentation significative de la vitesse. En outre, cela signifie que vous devez leur faire confiance pour ne vous livrer que le jQuery;)

15
sorin

Ce qui suit a fonctionné pour moi.

var iframe = top.frames[name].document;
var css = '' +
          '<style type="text/css">' +
          'body{margin:0;padding:0;background:transparent}' +
          '</style>';
iframe.open();
iframe.write(css);
iframe.close();
14
peter

Développement de la solution jQuery ci-dessus pour faire face aux retards de chargement du contenu du cadre.

$('iframe').each(function(){
    function injectCSS(){
        $iframe.contents().find('head').append(
            $('<link/>', { rel: 'stylesheet', href: 'iframe.css', type: 'text/css' })
        );
    }

    var $iframe = $(this);
    $iframe.on('load', injectCSS);
    injectCSS();
});
10
David Bradshaw

Mon version compacte:

<script type="text/javascript">
$(window).load(function () {
    var frame = $('iframe').get(0);
    if (frame != null) {
        var frmHead = $(frame).contents().find('head');
        if (frmHead != null) {
            frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
            //frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
        }
    }   
});
</script>

Cependant, parfois la iframe n'est pas prête lorsque la fenêtre est chargée. Il est donc nécessaire d'utiliser un timer.

Code prêt à l'emploi (avec minuteur):

<script type="text/javascript">
var frameListener;
$(window).load(function () {
    frameListener = setInterval("frameLoaded()", 50);
});
function frameLoaded() {
    var frame = $('iframe').get(0);
    if (frame != null) {
        var frmHead = $(frame).contents().find('head');
        if (frmHead != null) {
            clearInterval(frameListener); // stop the listener
            frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
            //frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
        }
    }
}
</script>

... et lien jQuery:

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
10
Zbigniew Wiadro

Lorsque vous dites "doc.open ()", cela signifie que vous pouvez écrire n’importe quelle balise HTML dans l’iframe. Vous devez donc écrire toutes les balises de base de la page HTML. Si vous souhaitez avoir un lien CSS dans votre tête iframe, écrivez simplement un iframe avec lien CSS dedans. Je vous donne un exemple:

doc.open();

doc.write('<!DOCTYPE html><html><head><meta charset="utf-8"/><meta http-quiv="Content-Type" content="text/html; charset=utf-8"/><title>Print Frame</title><link rel="stylesheet" type="text/css" href="/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');

doc.close();
8
parham fazel

Vous ne pourrez pas styler le contenu de l'iframe de cette façon. Ma suggestion serait d'utiliser un script côté serveur (PHP, ASP ou un script Perl) ou de trouver un service en ligne qui convertira un flux en code JavaScript. La seule autre façon de le faire serait de pouvoir inclure un serveur.

7
PageCandy

utilisation peut essayer ceci:

$('iframe').load( function() {
     $('iframe').contents().find("head")
     .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
  });
7
Ajay Malhotra

D'autres réponses semblent utiliser des liens jQuery et CSS.

Ce code utilise JavaScript vanille. Il crée un nouvel élément <style>. Il définit le contenu textuel de cet élément comme une chaîne contenant le nouveau CSS. Et il ajoute cet élément directement à la tête du document iframe.

var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
  '.some-class-name {' +
  '  some-style-name: some-value;' +
  '}' 
;
iframe.contentDocument.head.appendChild(style);
5
jtheletter

Incase si vous avez accès à la page iframe et que vous voulez qu’un CSS différent s’applique dessus uniquement lorsque vous le chargez via iframe sur votre page, ici j’ai trouvé une solution pour ce genre de choses

cela fonctionne même si iframe charge un domaine différent

vérifier à propos de postMessage()

plan est, envoyer le css à iframe comme un message comme

iframenode.postMessage('h2{color:red;}','*');

* est d'envoyer ce message quel que soit le domaine dans lequel il se trouve dans l'iframe

et recevez le message dans iframe et ajoutez le message reçu (CSS) à cet en-tête de document.

code à ajouter à la page iframe

window.addEventListener('message',function(e){

    if(e.data == 'send_user_details')
    document.head.appendChild('<style>'+e.data+'</style>');

});
4
CodeRows

J'ai trouvé une autre solution pour mettre le style dans le HTML principal comme celui-ci

<style id="iframestyle">
    html {
        color: white;
        background: black;
    }
</style>
<style>
    html {
        color: initial;
        background: initial;
    }
    iframe {
        border: none;
    }
</style>

puis dans iframe faire ceci (voir le js onload)

<iframe  onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>

et en js

<script>
    ifstyle = document.getElementById('iframestyle')
    iframe = top.frames["log"];
</script>

Ce n'est peut-être pas la meilleure solution, et cela peut certainement être amélioré, mais c'est une autre option si vous souhaitez conserver une balise "style" dans la fenêtre parente

3
jperelli

Je pense que le moyen le plus simple est d’ajouter une autre div, au même endroit que l’iframe, puis

rendre son z-index plus grand que le conteneur iframe, pour que vous puissiez facilement styliser votre propre div. Si vous avez besoin de cliquer dessus, utilisez simplement pointer-events:none sur votre propre div, ainsi l'iframe fonctionnerait au cas où vous auriez besoin de cliquer dessus;)

J'espère que ça va aider quelqu'un;)

2
Mateusz Winnicki

Ici, il y a deux choses à l'intérieur du domaine

  1. section iFrame
  2. Page chargée dans l'iFrame

Donc, vous voulez appeler ces deux sections comme suit,

1. Style pour la section iFrame

Il peut styler en utilisant CSS avec ce nom respecté id ou class. Vous pouvez également le styler dans vos feuilles de style parent.

<style>
#my_iFrame{
height: 300px;
width: 100%;
position:absolute;
top:0;
left:0;
border: 1px black solid;
}
</style>

<iframe name='iframe1' id="my_iFrame" src="#" cellspacing="0"></iframe>

2. Stylisez la page chargée dans l'iFrame

Ce style peut être chargé à partir de la page parent à l'aide de Javascript

var cssFile  = document.createElement("link") 
cssFile.rel  = "stylesheet"; 
cssFile.type = "text/css"; 
cssFile.href = "iFramePage.css"; 

puis définissez ce fichier CSS sur la section respectée d'iFrame

//to Load in the Body Part
frames['my_iFrame'].document.body.appendChild(cssFile); 
//to Load in the Head Part
frames['my_iFrame'].document.head.appendChild(cssFile);

Ici, vous pouvez éditer la partie tête de la page à l'intérieur de l'iFrame de cette façon aussi

var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
   $("<link/>",{ 
      rel: "stylesheet", 
      href: urlPath, 
      type: "text/css" }
     ));
2
K.Suthagar

Nous pouvons insérer une balise de style dans iframe. posté aussi ici ...

<style type="text/css" id="cssID">
.className
{
    background-color: red;
}
</style>

<iframe id="iFrameID"></iframe>

<script type="text/javascript">
    $(function () {
        $("#iFrameID").contents().find("head")[0].appendChild(cssID);
        //Or $("#iFrameID").contents().find("head")[0].appendChild($('#cssID')[0]);
    });
</script>
2
Palanikumar
var link1 = document.createElement('link');
    link1.type = 'text/css';
    link1.rel = 'stylesheet';
    link1.href = "../../assets/css/normalize.css";
window.frames['richTextField'].document.body.appendChild(link1);
1
Jeeva

Vous pouvez également utiliser la technologie CSS-in-JS, comme ci-dessous lib:

https://github.com/cssobj/cssobj

Il peut injecter un objet JS en tant que CSS à iframe, dynamiquement

1
James Yang

Il existe un script merveilleux qui remplace un nœud par une version iframe de lui-même. CodePen Démo

enter image description here

Exemples d'utilisation:

// Single node
var component = document.querySelector('.component');
var iframe = iframify(component);

// Collection of nodes
var components = document.querySelectorAll('.component');
var iframes = Array.prototype.map.call(components, function (component) {
  return iframify(component, {});
});

// With options
var component = document.querySelector('.component');
var iframe = iframify(component, {
  headExtra: '<style>.component { color: red; }</style>',
  metaViewport: '<meta name="viewport" content="width=device-width">'
});
1
karlisup