Un `iframe` (inline frame : cadre, encadrement, carcasse en ligne) est un espace défini dans une page Web. Dans cet espace réservé on va pouvoir afficher une autre page Web provenant de notre site ou de n'importe quel autre site sur le réseau. Le W3C appelle cet espace un contexte de navigation et plus particuliérement contexte de navigation imbriqué (nested browsing context. En simplifiant c'est comme si on avait une nouvelle fenêtre (onglet) du navigateur à l'intérieur de la fenêtre (onglet) de la page principale. Cette fenêtre n'a pas de barre de menu ou de barre d'URL, mais elle aura éventuellement des barres de défilement. Elle a aussi son propre historique de navigation.

Le principe des `iframes` est utilisé par exemple pour embarquer des publicités sur un site, inclure des "widgets" provenant d'autres sites (météo, cours de la bourse, mur facebook, tweets, vidéos youtube, google map, etc) ou encore émuler un système d'onglets.

Ce qui est intéressant avec les `iframes` c'est que le temps de chargement et d'affichage de leur contenu ne bloque pas l'affichage de la page principale. Le navigateur fait d'abord le rendu de la page principale, réserve un espace pour l'affichage de la page embarquée dans l'`iframe` et quand il a fini le rendu principale s'occcupe du rendu du contenu de l'`iframe`.

Les exemples suivants nécessitent une connexion Internet car ils affichent des éléments se trouvant sur le réseau. Ce sont des widgets offerts par différents sites que l'on peut intégrer dans nos propres pages.

Exemple : Besançon avec google map
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Besançon avec google map</title> </head> <body> <p>L'iframe affiche la position de l'UFR ST de Besançon.</p> <iframe src="https://www.google.com/maps/embed?pb=!1m16!1m12!1m3!1d43334.05971058872!2d5.989899300000022!3d47.248296999999994!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!2m1!1sUFR+ST+-+Universit%C3%A9+de+Franche-Comt%C3%A9%2C+Besan%C3%A7on%2C+France!5e0!3m2!1sfr!2s!4v1386747735184" width="400" height="300" frameborder="0" style="border:0"> </iframe> <p>La page affichée dans l'iframe est générée par maps.google.com</p> </body> </html>
Exemple : prévisions météo
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Prévisions météo</title> </head> <body> <p>L'iframe affiche les prévisions météo pour la ville de Besançon.</p> <iframe height="190" width="250" src="http://www.prevision-meteo.ch/services/html/besancon/square"></iframe> <p>La page affichée dans l'iframe se trouve sur le site prevision-meteo.ch</p> </body> </html>
Exemple : vidéo youtube
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Vidéo youtube</title> </head> <body> <p>L'iframe affiche une vidéo de youtube.</p> <iframe width="560" height="315" allowfullscreen src="http://www.youtube.com/embed/QJSRuwqFch4?rel=0"> </iframe> <p>La ressource dans l'iframe se trouve sur le site youtube.com.</p> </body> </html>
Exemple : hit-parade spotify
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Hit-parade spotify</title> </head> <body> <p>Hit parade spotify</p> <iframe width="300" height="400" src="http://charts.spotify.com/embed/charts/most_streamed/fr/latest"> </iframe> <p>La page dans l'iframe se trouve sur le site spotify.com.</p> </body> </html>
Exemple : player deezer
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Player deezer</title> </head> <body> <p>Player deezer</p> <iframe width="500" height="240" src="http://www.deezer.com/plugins/player?autoplay=false&playlist=true&width=500&height=240&cover=true&type=playlist&id=30595446&title=&app_id=undefined"> </iframe> <p>La page dans l'iframe se trouve sur le site deezer.com.</p> </body> </html>

Ce dernier exemple embarque une page twitter. Twitter ne fournit pas le code HTML pour intégrer un `iframe` mais un lien HTML et du code JavaScript. C'est l'exécution de ce code qui au final générera un `iframe`.

Exemple : tweets
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Tweets</title> </head> <body> <p>Tweets avec le hashtag #html</p> <a class="twitter-timeline" href="https://twitter.com/search?q=%23html" data-widget-id="409606580020072448"> Tweets concernant "#html"</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0], p=/^http:/.test(d.location)?'http':'https' if(!d.getElementById(id)){js=d.createElement(s);js.id=id; js.src=p+"://platform.twitter.com/widgets.js" fjs.parentNode.insertBefore(js,fjs);}} (document,"script","twitter-wjs"); </script> <p>La page dans l'iframe est générée par le site twitter.com.</p> </body> </html>

### L'élément <iframe>

On utilise l'élément iframe pour embarquer dans la page web en cours une autre page. La balise doit avoir une balise de fermeture `</iframe>` bien que le contenu de l'élément ne soit pas dans le fichier HTML.

#### Dimensions

L'élément iframe créant un espace d'affichage dans une page, il faut en définir les dimensions avec les attributs `width` et `height`. La valeur de ces attributs est un nombre de pixels, sans que l'unité ne soit précisée.

Il n'est pas possible que les dimensions d'un `iframe` s'adaptent automatiquement à leur contenu.
Si le contenu de la page embarquée est trop petit pour remplir complétement l'`iframe`, un espace vide sera généré.
Si le contenu de la page embarquée est trop grand pour tenir dans l'espace de l'`iframe`, une barre de défilement verticale et/ou une barre de défilement horizontale seront automatiquement créée par le navigateur pour que le contenu puisse être vu malgré tout.

#### L'attribut src

Comme pour tous les éléments embarqués, il faut aussi définir la localisation de la ressource sur le réseau. On utilise l'attribut `src` dont la valeur est l'URL de la ressource.
Bien sûr si la ressource est située dans un des dossiers de votre site, il faut utiliser une URL relative pour faire le lien.

Je vous rappelle qu'il convient d'être prudent avec les caractères utilisés pour les noms des fichiers et des dossiers qui les contiennent et je vous conseille (à nouveau) d'adopter les règles suivantes :

- les noms de fichier et de dossiers étant sensibles à la casse, utilisez uniquement des minuscules,
- utilisez uniquement les caractères aplhabétiques non accentués (de a à z), des chiffres (de 0 à 9), le caractère -, le caractère _ et le caractère .
- n'utilisez jamais d'espaces.

Exemple : embarquer une page Web
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Embarquer une page Web</title> </head> <body> <p>Gandalf est un héros du "Seigneur des Anneaux". <iframe src="pages/gandalf.html" width="400" height="400"> </iframe> On le trouve aussi dans "Bilbo le Hobbit". </p> </body> </html>

En testant l'exemple, on voit que le navigateur a automatiquement placé une barre de défilement verticale pour que l'on puisse faire défiler la page embarquée et la consulter en entier.
Une barre de défilement horizontal aurait aussi été ajoutée automatiquement si cela avait été nécessaire.

iframe est un élément en ligne. Si vous agrandissez la fenêtre de test, vous verrez que le texte entoure l'`iframe`. Pour qu'un `iframe` soit considéré comme un bloc il faut le placer dans un élément p ou div, ou l'entourer par des éléments de bloc.

On peut avoir autant d'élements iframe que l'on veut dans une page.

Exemple : plusieurs iframes dans la page
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Plusieurs iframes</title> </head> <body> <h3>Gandalf</h3> <iframe src="pages/gandalf.html" width="400" height="200"> </iframe> <h3>Sauron</h3> <iframe src="pages/sauron.html" width="200" height="150"> </iframe> <h3>Yoda</h3> <iframe src="pages/yoda.html" width="300" height="100"> </iframe> <h3>Palpatine</h3> <iframe src="pages/palpatine.html" width="400" height="200"> </iframe> </body> </html>

#### Bordure

Dans les versions précédentes de HTML, des attributs permettaient de gérer la bordure entourant un iframe. Bien que ces attributs soient toujours supportés par les navigateurs, il convient maintenant d'utiliser des propriétés de style CSS pour agir sur l'aspect des `iframes`.

Par défaut les `iframes` sont entourés par une bordure de 1 ou 2 pixels. On peut gérer cette bordure avec plusieurs propriétés CSS comme `border`, `border-style`, `border-color`, etc.

L'exemple suivant montre comment enlever la bordure autour d'un `iframe`, ou comment changer sa couleur.

Exemple : gestion de la bordure
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>iframe sans bordure</title> <style> .sans-bord {border: 0} .bord-rouge {border: 1px solid red} </style> </head> <body> <h3>Gandalf</h3> <iframe src="pages/gandalf.html" width="400" height="150" class="sans-bord"> </iframe> <h3>Yoda</h3> <iframe src="pages/yoda.html" width="400" height="150" class="bord-rouge"> </iframe> </body> </html>

#### Barres de défilement

Comme on l'a vu dans les exemples précédents, le navigateur place automatiquement une barre de défilement verticale pour que l'on puisse faire défiler la page embarquée et la consulter en entier.

Avant HTML5, l'attribut `scrolling` permettait de gérer ces barres de défilement, mais cet attribut est déprécié et n'a pas été remplacé. Pour le moment, la propriété de style CSS `overflow` qui devrait gérer cet affichage n'est pas pris en compte pour les `iframes` par les navigateurs.
On continue donc d'utiliser l'attribut `scrolling` avec les valeurs :

- `no` : aucune barre de défilement ne sera présente, et ce même si le contenu embarqué ne tient pas dans l'espace de l'`iframe` ;
- `yes` : dans les versions anciennes de navigateurs, une barre de défilement verticale (et éventuellement une barre de défilement horizontale) seront présentes, et ce même si elles sont inutiles. Dans les nouvelles versions cette valeur réagit comme `auto` ;
- `auto` : le navigateur gère automatiquement les barres de défilement (comportement par défaut).

Exemple : barres de défilement
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Barres de défilement</title> </head> <body> <h3>Yoda - no</h3> <iframe src="pages/yoda.html" width="400" height="150" scrolling="no"> </iframe> <h3>Yoda - yes</h3> <iframe src="pages/yoda.html" width="400" height="500" scrolling="yes"> </iframe> <h3>Yoda - auto</h3> <iframe src="pages/gandalf.html" width="400" height="150" scrolling="auto"> </iframe> </body> </html>

### Liens et iframes

Avec l'attribut `target` de l'élément a on va pouvoir faire un lien qui va s'afficher dans un `iframe`.

Pour que ça fonctionne, il faut que l'élément iframe soit nommé en utilisant un attribut `name` ou un attribut `id`. La valeur de cet attribut sera utilisée comme valeur de l'attribut `target` du lien.

Exemple : lien vers un iframe
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Lien vers un iframe</title> </head> <body> <p>Préférez vous <a href="pages/gandalf.html" target="voir">Gandalf</a> ou <a href="pages/yoda.html" target="voir">Yoda</a> ? </p> <iframe width="400" height="150" name="voir"> </iframe> </body> </html>

#### Liens vers un iframe

Complétez le code HTML pour obtenir le résultat ci-dessous.

liens vers des iframes
arborescence de l'exercice

Quand on clique sur les petites images en haut de la page, une image correspondante de grandes dimensions s'affiche dans l'iframe situé sous les petites images.

L'iframe a pour dimensions 816 pixels sur 600. Il est entouré par une bordure noir de 1 pixel d'épaisseur.

Les images se trouvent dans l'arborescence ci-contre.

Pour simplifier, ne donnez pas les dimensions des images dans le code HTML.

Nom | Dossier | Correspondance | Dossier
--- | --- | --- | ---
`affiche_150.jpg` | `lord_rings` | `affiche_800.jpg` | `images` dans `lord_rings`
`lego_150.jpg` | `star_wars` | `lego_800.jpg` | `images` dans `star_wars`
`family_150.jpg` | `star_wars` | `family_800.jpg` | `images` dans `star_wars`

Code à compléter

Exercice : liens vers un iframe
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Liens vers un iframe</title> <style> </style> </head> <body> </body> </html>

Une solution possible

Exercice : liens vers un iframe
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Liens vers un iframe</title> <style> .bord-fin { border: 1px solid black; } </style> </head> <body> <p> <a href="../exemples/lord_rings/images/affiche_800.jpg" target="grande_image"> <img src="../exemples/lord_rings/affiche_150.jpg"></a> <a href="../exemples/star_wars/images/lego_800.jpg" target="grande_image"> <img src="../exemples/star_wars/lego_150.jpg"></a> <a href="../exemples/star_wars/images/family_800.jpg" target="grande_image"> <img src="../exemples/star_wars/family_150.jpg"></a> </p> <iframe width="816" height="600" name="grande_image" class="bord-fin"> </iframe> </body> </html>

#### Liens vers des iframes

Réalisez des ensembles de liens et d'iframes pour obtenir le résultat ci-contre. Quand on clique sur les images, une page HTML descriptive du personnage s'affiche dans l'iframe situé sous le personnage. Les pages sur lesquelles pointent les liens se trouvent dans l'arborescence suivante : arborescence de l'exercice Les pages HTML concernant "Le Seigneur des Anneaux" se trouvent dans le dossier `lord_rings`. Les images concernant "Le Seigneur des Anneaux" se trouvent dans le dossier `lord_rings/images`. Les pages HTML concernant "La Guerre des Etoiles" se trouvent dans le dossier `star_wars`. Les images concernant "La Guerre des Etoiles" se trouvent dans le dossier `star_wars/images`. Les pages s'appellent du nom du personnage, tout en minuscules, et les espaces éventuels remplacés par un _ (underscore). L'extension du fichier est `.html` Les images s'appellent du nom du personnage, tout en minuscules, et les espaces éventuels remplacés par un _ (underscore). L'extension du fichier est `.png`. Pour simplifier ne donnez pas les dimensions des images. | liens vers des iframes Par ordre d'apparition : Gandalf, Frodon, Gimli, Sauron, Saroumane, Gollum, Yoda, Luke Skywalker, Chewbacca, Palpatine, Dark vador, Comte Dooku.

Code à compléter

Exercice : liens vers des iframes
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Liens vers des iframes</title> </head> <body> <h3>Anneaux ou Etoiles ?</h3> </body> </html>

Une solution possible

Exercice : liens vers des iframes
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Liens vers des iframes</title> </head> <body> <h3>Anneaux ou Etoiles ?</h3> <p> <a href="../exemples/lord_rings/gandalf.html" target="lord_gentils"> <img src="../exemples/lord_rings/images/gandalf.png"></a> <a href="../exemples/lord_rings/frodon.html" target="lord_gentils"> <img src="../exemples/lord_rings/images/frodon.png"></a> <a href="../exemples/lord_rings/gimli.html" target="lord_gentils"> <img src="../exemples/lord_rings/images/gimli.png"></a> </p> <iframe width="350" height="150" name="lord_gentils"> </iframe> <p> <a href="../exemples/lord_rings/sauron.html" target="lord_mechants"> <img src="../exemples/lord_rings/images/sauron.png"></a> <a href="../exemples/lord_rings/saroumane.html" target="lord_mechants"> <img src="../exemples/lord_rings/images/saroumane.png"></a> <a href="../exemples/lord_rings/gollum.html" target="lord_mechants"> <img src="../exemples/lord_rings/images/gollum.png"></a> </p> <iframe width="350" height="150" name="lord_mechants"> </iframe> <p> <a href="../exemples/star_wars/yoda.html" target="star_gentils"> <img src="../exemples/star_wars/images/yoda.png"></a> <a href="../exemples/star_wars/luke_skywalker.html" target="star_gentils"> <img src="../exemples/star_wars/images/luke_skywalker.png"></a> <a href="../exemples/star_wars/chewbacca.html" target="star_gentils"> <img src="../exemples/star_wars/images/chewbacca.png"></a> </p> <iframe width="350" height="150" name="star_gentils"> </iframe> <p> <a href="../exemples/star_wars/palpatine.html" target="star_mechants"> <img src="../exemples/star_wars/images/palpatine.png"></a> <a href="../exemples/star_wars/dark_vador.html" target="star_mechants"> <img src="../exemples/star_wars/images/dark_vador.png"></a> <a href="../exemples/star_wars/comte_dooku.html" target="star_mechants"> <img src="../exemples/star_wars/images/comte_dooku.png"></a> </p> <iframe width="350" height="150" name="star_mechants"> </iframe> </body> </html>

Une page dans un `iframe` peut aussi donner comme cible d'un de ses liens la page conteneur. La valeur de l'attribut `target` doit être le mot-clé `_parent`.

Code HTML de la page affichée dans l'`iframe` de l'exemple suivant :

    <!DOCTYPE html>
    <html lang="fr">
    	<head>
    		<meta charset="utf-8">
    		<title>Lien vers le parent</title>
    	</head>
    	<body>

    	<p>Ce lien va ouvrir la
    		<a href="gandalf.html" target="_parent">
    		page gandalf.html</a> dans la fenêtre principale.
    	</p>

    	</body>
    </html>

Exemple : lien vers le parent conteneur
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Lien vers le parent</title> </head> <body> <p>En cliquant sur le lien de la page dans l'iframe, vous allez remplacer cette page. </p> <iframe src="pages/enfant.html" width="400" height="150"> </iframe> </body> </html>

### Protection

Embarquer une page étrangère dans notre site peut s'avèrer dangereux car la page embarquée aura accès a l'environnement de la page parent : les cookies, le stockage local, les scripts, les éléments HTML, etc.

L'attribut `sandbox` permet de restreindre les droits des pages embarquées. `sandbox` travaille sur le principe de la liste blanche : d'abord on enlève tous les droits, puis on accord seulement les droits qui semblent nécessaires.

Si l'attribut `sandbox` est absent de la balise d'ouverture de l'élément iframe, la page embarquée a tous les droits. Si c'est une page de votre site, c'est normal, par contre si c'est une page d'un autre site c'est peut-être trop.

Exemple : pas de sandbox
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Tous les droits</title> </head> <body> <p>La page dans l'iframe ouvre une fenêtre pop-up d'alerte avec JavaScript, a un lien qui s'ouvre dans la fenêtre parent, a une vidéo en autoplay, a un script qui affiche la date du jour. </p> <iframe src="pages/bac_a_sable.html" width="500" height="350"> </iframe> </body> </html>

Si la valeur de l'attribut `sandbox` est une valeur vide (`<iframe sandbox="" src="http/site.com/page.html">` ) on enlève le maximum de droits :

- les scripts JavaScript de la page embarquée ne seront pas exécutés,
- la page embarquée n'aura accès à aucun cookie ou moyens de stockage local (DOM, Indexed DB, etc.),
- la page embarquée ne pourra pas créer de nouvelles fenêtres (par exemple avec des liens `target="_blank"`,
- les formulaires de la page embarquée ne pourront pas être envoyés,
- la page embarquée peut seulement naviguer dans son contexte de navigation (les liens avec `target="_parent"` ou `target="_top"` ne fonctionneront pas,
- tous les éléments avec des événements automatiques sont bloqués (par exemple une vidéo avec `autoplay`,

Exemple : sandbox sans valeur
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Aucun droit</title> </head> <body> <p>La page dans l'iframe ouvre une fenêtre pop-up d'alerte avec JavaScript, a un lien qui s'ouvre dans la fenêtre parent, a une vidéo en autoplay, a un script qui affiche la date du jour. </p> <iframe src="pages/bac_a_sable.html" width="500" height="350" sandbox=""> </iframe> </body> </html>

Pour accorder des droits à la page embarquée, on va donner comme valeur à l'attribut `sandbox` une liste de mots-clés :

- `allow-forms` : les formulaires peuvent être envoyés
- `allow-popups` : des nouvelles fenêtres peuvent être créées (avec `target` ou par JavaScript),
- `allow-pointer-lock` : autorise le verrouillage du curseur de la souris,
- `allow-same-origin` : donne accès à la page embarquée aux objets qui ont la même origine (domaine) qu'elle,
- `allow-scripts` : autorise l'exécution du code JavaScript et l'exécution automatique des éléments,
- `allow-top-navigation` : autorise la page embarquée à naviguer dans les contextes de navigation suppérieurs.

Exemple : sandbox avec popup et scripts
<!DOCTYPE html> <html lang="fr"> <head> <meta charset="utf-8"> <title>Aucun droit</title> </head> <body> <p>La page dans l'iframe ouvre une fenêtre pop-up d'alerte avec JavaScript, a un lien qui s'ouvre dans la fenêtre parent, a une vidéo en autoplay, a un script qui affiche la date du jour. </p> <iframe src="pages/bac_a_sable.html" width="500" height="350" sandbox="allow-same-origin allow-popups allow-scripts"> </iframe> </body> </html>