Comment mettre à l'échelle le contenu d'un iframe?

237

Comment puis-je mettre à l'échelle le contenu d'une iframe (dans mon exemple, c'est une page HTML et non une popup) dans une page de mon site Web?

Par exemple, je souhaite afficher le contenu qui apparaît dans l'iframe à 80% de la taille d'origine.

John Griffiths
la source
14
Raclage de questions - bonne pratique? Je ne pense pas.
Konrad Rudolph
9
Cas d'utilisation typique: prévisualisation d'une page / d'un site dans un éditeur wysiwyg en ligne
frenchone

Réponses:

224

La solution de Kip devrait fonctionner sur Opera et Safari si vous changez le CSS en:

<style>
    #wrap { width: 600px; height: 390px; padding: 0; overflow: hidden; }
    #frame { width: 800px; height: 520px; border: 1px solid black; }
    #frame {
        -ms-zoom: 0.75;
        -moz-transform: scale(0.75);
        -moz-transform-origin: 0 0;
        -o-transform: scale(0.75);
        -o-transform-origin: 0 0;
        -webkit-transform: scale(0.75);
        -webkit-transform-origin: 0 0;
    }
</style>

Vous pouvez également spécifier le débordement: caché sur #frame pour empêcher les barres de défilement.

lxs
la source
@JonathanM - cf meta.stackexchange.com/questions/75043/… , ai-je fait quelque chose de mal ici?
lxs
@lxs, pas du tout. Je l'ai adoré et lui ai donné un +1. Bon travail.
Jonathan M
7
J'ai remarqué que sur Chrome, j'obtiens à la fois le zoom et la transformation Webkit, ce qui entraîne l'application de l'échelle deux fois.
dennisjtaylor
1
comme le dit @dennisjtaylor, le chrome semble appliquer l'échelle deux fois - comme on le voit ici jsfiddle.net/zjTBq/embedded/result
Horse
3
Comme tous les navigateurs modernes prennent en charge la transformation depuis un certain temps, j'envisagerais d'utiliser la version non préfixée (au moins comme alternative).
wortwart
55

J'ai trouvé une solution qui fonctionne dans IE et Firefox (au moins sur les versions actuelles). Sur Safari / Chrome, l'iframe est redimensionné à 75% de sa taille d'origine, mais le contenu de l'iframe n'est pas du tout mis à l'échelle. Dans Opera, cela ne semble pas fonctionner. Cela semble un peu ésotérique, donc s'il y a une meilleure façon de le faire, je serais heureux de recevoir des suggestions.

<style>
#wrap { width: 600px; height: 390px; padding: 0; overflow: hidden; }
#frame { width: 800px; height: 520px; border: 1px solid black; }
#frame { zoom: 0.75; -moz-transform: scale(0.75); -moz-transform-origin: 0 0; }
</style>

...

<p>Some text before the frame</p>
<div id="wrap">
<iframe id="frame" src="test2.html"></iframe>
</div>
<p>Some text after the frame</p>
</body>

Remarque: j'ai dû utiliser l' wrapélément pour Firefox. Pour une raison quelconque, dans Firefox, lorsque vous réduisez l'objet de 75%, il utilise toujours la taille d'origine de l'image pour des raisons de mise en page. (Essayez de supprimer le div de l'exemple de code ci-dessus et vous verrez ce que je veux dire.)

J'ai trouvé une partie de cela à partir de cette question .

Kip
la source
31

Après avoir lutté avec cela pendant des heures à essayer de le faire fonctionner dans IE8, 9 et 10, voici ce qui a fonctionné pour moi.

Ce CSS simplifié fonctionne dans FF 26, Chrome 32, Opera 18 et IE9 -11 à partir du 1/7/2014:

.wrap
{
    width: 320px;
    height: 192px;
    padding: 0;
    overflow: hidden;
}

.frame
{
    width: 1280px;
    height: 786px;
    border: 0;

    -ms-transform: scale(0.25);
    -moz-transform: scale(0.25);
    -o-transform: scale(0.25);
    -webkit-transform: scale(0.25);
    transform: scale(0.25);

    -ms-transform-origin: 0 0;
    -moz-transform-origin: 0 0;
    -o-transform-origin: 0 0;
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}

Pour IE8, définissez la largeur / hauteur pour correspondre à l'iframe et ajoutez -ms-zoom à la div du conteneur .wrap:

.wrap
{
    width: 1280px; /* same size as frame */
    height: 768px;
    -ms-zoom: 0.25; /* for IE 8 ONLY */
}

Utilisez simplement votre méthode préférée pour renifler le navigateur afin d'inclure conditionnellement le CSS approprié, voir Existe - t-il un moyen de faire du CSS conditionnel spécifique au navigateur dans un fichier * .css? pour quelques idées.

IE7 était une cause perdue car -ms-zoom n'existait pas avant IE8.

Voici le HTML réel que j'ai testé avec:

<div class="wrap">
   <iframe class="frame" src="http://time.is"></iframe>
</div>
<div class="wrap">
    <iframe class="frame" src="http://apple.com"></iframe>
</div>

http://jsfiddle.net/esassaman/PnWFY/

Eric Sassaman
la source
17

Je viens de tester et pour moi, aucune des autres solutions n'a fonctionné. J'ai simplement essayé cela et cela a parfaitement fonctionné sur Firefox et Chrome, comme je m'y attendais:

<div class='wrap'>
    <iframe ...></iframe>
</div>

et le css:

.wrap {
    width: 640px;
    height: 480px;
    overflow: hidden;
}

iframe {
    width: 76.92% !important;
    height: 76.92% !important;
    -webkit-transform: scale(1.3);
    transform: scale(1.3);
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
}

Cela réduit tout le contenu de 30%. Les pourcentages largeur / hauteur doivent bien sûr être ajustés en conséquence (1 / scale_factor).

MrP01
la source
2
Vous souhaitez également ajouter overflow: hidden;à l' .wrapélément. Lorsque vous utilisez iframe { width: 200%; height: 200%; transform: scale(0.5); }iframe commence à déborder.
ozgrozer
Il s'agit de l'approche de pointe. Merci!
fuggi
10

Suivi de la réponse de lxs : j'ai remarqué un problème où avoir les balises zoomet --webkit-transformen même temps semble confondre Chrome (version 15.0.874.15) en faisant un effet à double zoom. J'ai pu contourner le problème en remplaçant zoompar -ms-zoom(ciblé uniquement sur IE), en laissant Chrome utiliser uniquement la --webkit-transformbalise, et cela a clarifié les choses.

r3cgm
la source
9

Vous n'avez pas besoin d'envelopper l'iframe avec une balise supplémentaire. Assurez-vous simplement d'augmenter la largeur et la hauteur de l'iframe du même montant que vous réduisez l'iframe.

par exemple pour faire évoluer le contenu de l'iframe à 80%:

#frame { /* Example size! */
    height: 400px; /* original height */
    width: 100%; /* original width */
}
#frame {
    height: 500px; /* new height (400 * (1/0.8) ) */
    width: 125%; /* new width (100 * (1/0.8) )*/

    transform: scale(0.8); 
    transform-origin: 0 0;
}

Fondamentalement, pour obtenir la même taille si vous avez besoin de mettre à l'échelle les dimensions.

Matthew Wilcoxson
la source
7

html {zoom: 0.4;}? -)

roenving
la source
3
Ce serait 0,8 pour 80%, mais c'est un Microsoftism propriétaire, donc probablement pas adapté. Cela ne fonctionnerait également que si le document chargé dans le cadre pouvait être modifié, ce qui est peu probable.
Quentin
7

J'ai pensé partager ce que j'ai trouvé, en utilisant une grande partie de ce qui a été donné ci-dessus. Je n'ai pas vérifié Chrome, mais cela fonctionne dans IE, Firefox et Safari, pour autant que je sache.

Les décalages spécifiques et le facteur de zoom dans cet exemple ont fonctionné pour réduire et centrer deux sites Web dans des iframes pour les onglets Facebook (largeur 810 px).

Les deux sites utilisés étaient un site wordpress et un réseau ning. Je ne suis pas très bon en html, donc cela aurait probablement pu être mieux fait, mais le résultat semble bon.

<style>
    #wrap { width: 1620px; height: 3500px; padding: 0; position:relative; left:-100px; top:0px; overflow: hidden; }
    #frame { width: 1620px; height: 3500px; position:relative; left:-65px; top:0px; }
    #frame { -ms-zoom: 0.7; -moz-transform: scale(0.7); -moz-transform-origin: 0px 0; -o-transform: scale(0.7); -o-transform-origin: 0 0; -webkit-transform: scale(0.7); -webkit-transform-origin: 0 0; }
</style>
<div id="wrap">
    <iframe id="frame" src="http://www.example.com"></iframe>
</div>
Jon Fergus
la source
5

Si vous souhaitez que l'iframe et son contenu soient mis à l'échelle lorsque la fenêtre est redimensionnée, vous pouvez définir ce qui suit sur l'événement de redimensionnement de la fenêtre ainsi que sur l'événement de chargement des iframes.

function()
{
    var _wrapWidth=$('#wrap').width();
    var _frameWidth=$($('#frame')[0].contentDocument).width();

    if(!this.contentLoaded)
      this.initialWidth=_frameWidth;
    this.contentLoaded=true;
    var frame=$('#frame')[0];

    var percent=_wrapWidth/this.initialWidth;

    frame.style.width=100.0/percent+"%";
    frame.style.height=100.0/percent+"%";

    frame.style.zoom=percent;
    frame.style.webkitTransform='scale('+percent+')';
    frame.style.webkitTransformOrigin='top left';
    frame.style.MozTransform='scale('+percent+')';
    frame.style.MozTransformOrigin='top left';
    frame.style.oTransform='scale('+percent+')';
    frame.style.oTransformOrigin='top left';
  };

Cela rendra l'iframe et son échelle de contenu à 100% de la largeur du div en boucle (ou quel que soit le pourcentage que vous souhaitez). En prime, vous n'avez pas besoin de définir le CSS du cadre sur des valeurs codées en dur car elles seront toutes définies de manière dynamique, vous aurez juste besoin de vous soucier de la façon dont vous souhaitez que le div en boucle s'affiche.

J'ai testé cela et cela fonctionne sur Chrome, IE11 et Firefox.

user3298597
la source
4

Je pense que vous pouvez le faire en calculant la hauteur et la largeur que vous voulez avec javascript (via document.body.clientWidth etc.) puis en injectant l'iframe dans votre HTML comme ceci:

var element = document.getElementById ("myid");
element.innerHTML + = "<iframe src = 'http: //www.google.com' height = '200' width = '" + document.body.clientWidth * 0.8 + "' />";

Je n'ai pas testé cela dans IE6 mais cela semble fonctionner avec les bons :)

Eric Wendelin
la source
Excusez mon ignorance, mais cela ne ferait-il pas l'iframe à 80% de la page source, plutôt que de faire un zoom arrière sur la page source elle-même?
Phill Healey
3

Pour ceux d'entre vous qui ont du mal à faire fonctionner cela dans IE, il est utile d'utiliser -ms-zoomcomme suggéré ci-dessous et d'utiliser la fonction de zoom sur le #wrapdiv, pas l' iframeid. D'après mon expérience, avec la zoomfonction essayant de mettre à l'échelle la division iframe #frame, elle mettrait à l'échelle la taille de l'iframe et non le contenu qu'elle contient (ce que vous recherchez).

Ressemble à ça. Fonctionne pour moi sur IE8, Chrome et FF.

#wrap {
  overflow: hidden;
  position: relative;
  width:800px;
  height:850px;
  -ms-zoom: 0.75;
}
Tiago
la source
Utilisation zoomen mode standard IE8, utilisation -ms-zoomen mode bizarreries.
Jonathon Hill
3

Ce fut ma solution sur une page avec une largeur de 890px

#frame { 
overflow: hidden;
position: relative;
width:1044px;
height:1600px;
-ms-zoom: 0.85;
-moz-transform: scale(0.85);
-moz-transform-origin: 0px 0;
-o-transform: scale(0.85);
-o-transform-origin: 0 0;
-webkit-transform: scale(0.85);
-webkit-transform-origin: 0 0; 

}
Mathias Asberg
la source
2

La solution #wrap #frame fonctionne très bien, tant que les nombres dans #wrap sont #frame fois le facteur d'échelle. Il ne montre que cette partie du cadre réduit. Vous pouvez le voir ici en réduisant les sites Web et en le mettant dans un formulaire de type pinterest (avec le plugin Woodmark jQuery):

http://www.genautica.com/sandbox/woodmark-index.html

Stefan Gruenwald
la source
2

Ce n'est donc probablement pas la meilleure solution, mais semble fonctionner correctement.

<IFRAME ID=myframe SRC=.... ></IFRAME>

<SCRIPT>
    window.onload = function(){document.getElementById('myframe').contentWindow.document.body.style = 'zoom:50%;';};
</SCRIPT>

Évidemment, n'essayez pas de réparer le parent, ajoutez simplement le style "zoom: 50%" au corps de l'enfant avec un peu de javascript.

Peut-être pourrait définir le style de l'élément "HTML", mais n'a pas essayé cela.

Graham
la source
1
Ne fais pas ça. De developer.mozilla.org/en-US/docs/Web/CSS/zoom : "Cette fonctionnalité n'est pas standard et n'est pas sur une piste standard. Ne l'utilisez pas sur des sites de production face au Web: elle ne fonctionnera pas pour chaque utilisateur. Il peut également y avoir de grandes incompatibilités entre les implémentations et le comportement peut changer à l'avenir. "
hackel
+1 Cela (modifier le contenu de l'iframe, pas l'iframe lui-même) semble être une meilleure idée. J'avais besoin d'un moyen de réduire une page et de l'afficher comme un aperçu de cette page et cette approche a résolu le problème.
akinuri
@akinuri Oui, c'est exactement pour cela que je l'ai utilisé. Je suis passé par un certain nombre de solutions, mais cela semblait le plus simple. Je viens de parcourir les iframes et de les réduire pour obtenir une page de vignettes. Aucune modification des pages enfants n'est requise.
Graham
1

Si votre html est stylisé avec css, vous pouvez probablement lier différentes feuilles de style pour différentes tailles.

Jon
la source
0

Je ne pense pas que HTML possède une telle fonctionnalité. La seule chose que je peux imaginer ferait l'affaire est de faire un peu de traitement côté serveur. Peut-être pourriez-vous obtenir un instantané d'image de la page Web que vous souhaitez diffuser, la mettre à l'échelle sur le serveur et la diffuser au client. Ce serait cependant une page non interactive. (peut-être qu'un plan d'imagerie pourrait avoir le lien, mais quand même.)

Une autre idée serait d'avoir un composant côté serveur qui modifierait le HTML. Un peu comme la fonction de zoom de firefox 2.0. bien sûr, ce n'est pas un zoom parfait, mais c'est mieux que rien.

A part ça, je suis à court d'idées.

Alexandros Marinos
la source
0

Comme je l'ai dit, je doute que vous puissiez le faire.
Vous pouvez peut-être redimensionner au moins le texte lui-même, en définissant un style font-size: 80%;.
Non testé, pas sûr que cela fonctionne, et ne redimensionnera pas les boîtes ou les images.

PhiLho
la source