Retour au cours

frontend / html

Liens et images

Leçon 31 exercice

Explication

Ce que vous allez apprendre

  • Créer des liens internes, externes, d'ancre, email et téléphone avec <a href>
  • Sécuriser un lien qui s'ouvre dans un nouvel onglet avec rel="noopener noreferrer"
  • Rendre une image accessible grâce à un alt toujours présent et pertinent
  • Éviter le Cumulative Layout Shift en précisant width/height sur chaque <img>
  • Associer une légende à une image avec <figure>/<figcaption>

Dans quel contexte ?

Un chef de projet signale un bug visuel sur produit.html : à chaque chargement de page, le texte "saute" vers le bas d'une vingtaine de pixels dès que la photo du produit finit de charger. C'est un Cumulative Layout Shift classique, causé par une balise <img src="produit.jpg" alt="Chaise en bois"> sans width/height. C'est exactement le genre de défaut, invisible en local sur une connexion rapide mais très gênant en 4G, que cette leçon apprend à prévenir.

Étape 1 : le lien, ce qui a donné son nom au Web

S'il fallait ne retenir que deux balises HTML, ce seraient <a> (le lien) et <img> (l'image). Le lien hypertexte est littéralement ce qui a donné son nom au "World Wide Web" : un réseau de documents reliés entre eux par des liens cliquables.

Étape 2 : un lien peut pointer vers plus que des pages

D'abord, la version simple : <a href="..."> pointe vers une autre page. Mais sa destination peut aussi être une ancre dans la page actuelle, une adresse email ou même un numéro de téléphone — le code de cette leçon montre chaque cas.

Étape 3 : le piège du lien qui ouvre un nouvel onglet

Il reste un cas délicat : quand un lien ouvre un site externe dans un nouvel onglet. Par défaut, la page ouverte peut accéder à certaines informations de la page d'origine via window.opener — une faille de sécurité subtile.

Voici comment on la corrige : on ajoute systématiquement rel="noopener noreferrer". C'est une bonne pratique invisible à l'œil nu, mais qui protège concrètement l'utilisateur.

Type de lienSyntaxeCas d'usage
Interne<a href="/produits">Naviguer vers une autre page du site
Ancre<a href="#section-2">Sauter à un endroit de la page actuelle
Email<a href="mailto:contact@exemple.com">Ouvre le client mail par défaut
Téléphone<a href="tel:+33600000000">Compose le numéro sur mobile
Externe sécurisé<a href="..." target="_blank" rel="noopener noreferrer">Ouvre un site tiers dans un nouvel onglet

Piège fréquent

Oublier rel="noopener" sur un lien target="_blank" permet à la page ouverte d'accéder partiellement à window.opener, la fenêtre d'origine — une faille de sécurité connue sous le nom de "tabnabbing". Prenez le réflexe d'ajouter systématiquement rel="noopener noreferrer" dès que vous écrivez target="_blank".

Étape 4 : passons à l'image, un contenu qui doit rester accessible

Une image n'est pas qu'un fichier à afficher : c'est un contenu qui doit garder du sens même quand il ne peut pas être vu, que ce soit parce que le fichier ne charge pas, ou parce que l'utilisateur est aveugle et utilise un lecteur d'écran.

Étape 5 : l'attribut qui rend l'image compréhensible sans les yeux

C'est là qu'intervient alt : il décrit ce que l'image représente. Il est obligatoire sur chaque <img>, même quand le texte doit rester vide (alt="") pour une image purement décorative — jamais absent, seulement vide dans ce cas précis.

Étape 6 : le piège de performance à éviter

Il reste un dernier piège très courant : oublier width et height sur ses images. Pendant le chargement, le navigateur ne sait alors pas quelle place réserver, et le contenu "saute" visuellement dès que l'image apparaît — c'est le Cumulative Layout Shift.

Préciser les dimensions dès le départ règle ce problème : le navigateur réserve l'espace à l'avance, pour un affichage stable dès le premier rendu.

Bonne pratique

Sur produit.html, remplacez <img src="produit.jpg" alt="Chaise en bois"> par <img src="produit.jpg" alt="Chaise en bois massif, vue de trois quarts" width="800" height="600" loading="lazy">. Le width/height élimine le saut visuel, et loading="lazy" évite de charger l'image tant qu'elle n'approche pas de l'écran visible.

Et ensuite ?

Une fois liens et images maîtrisés, la prochaine étape logique consiste à organiser des ensembles de contenus avec des listes et des tableaux.

Commandes & code

Liens et images

Les deux éléments les plus utilisés du Web, avec leurs attributs souvent mal exploités.

html
<!-- Liens de base -->
<a href="https://exemple.com">Lien externe</a>
<a href="/produits">Lien relatif interne</a>
<a href="#section-2">Ancre vers une section de la même page</a>
<a href="mailto:contact@exemple.com">Envoyer un email</a>
<a href="tel:+33600000000">Appeler</a>

<!-- Ouverture dans un nouvel onglet : toujours sécuriser avec rel -->
<a href="https://partenaire.com" target="_blank" rel="noopener noreferrer">
    Site partenaire
</a>
<!-- noopener : empêche la page ouverte d'accéder à `window.opener`
     (faille de sécurité + fuite de perf sinon)
     noreferrer : n'envoie pas l'en-tête Referer -->

<!-- Téléchargement forcé -->
<a href="/rapport.pdf" download="rapport-annuel.pdf">Télécharger le PDF</a>

<!-- Lien désactivé sémantiquement (préférer un vrai state disabled côté JS/CSS) -->
<a href="/page-indisponible" aria-disabled="true">Page indisponible</a>
html
<!-- Images : attributs essentiels -->
<img
    src="/images/produit.jpg"
    alt="Chaise en bois massif, vue de trois quarts"
    width="800"
    height="600"
    loading="lazy"
>
<!-- alt : OBLIGATOIRE. Décrit le contenu pour lecteurs d'écran + image cassée.
     Décorative uniquement ? -> alt="" (chaîne vide, jamais absente)
     width/height : évite le layout shift (le navigateur réserve l'espace
     avant même que l'image soit chargée)
     loading="lazy" : ne charge l'image que quand elle approche du viewport -->

<img src="/icones/fleche.svg" alt="" role="presentation">
<!-- image purement décorative : alt vide + role presentation -->

<!-- Figure : image + légende associée sémantiquement -->
<figure>
    <img src="/images/graphique-ventes.png" alt="Graphique des ventes 2024, en hausse de 12%">
    <figcaption>Évolution des ventes trimestrielles, 2024</figcaption>
</figure>
Attribut de <a>Effet
hrefdestination du lien
target="_blank"ouverture dans un nouvel onglet
rel="noopener noreferrer"sécurise l'ouverture externe
downloadforce le téléchargement

Résumé

  • rel="noopener noreferrer" est quasi-systématique avec target="_blank".
  • alt est obligatoire sur <img> ; vide (alt="") pour le purement décoratif.
  • width/height sur <img> évitent le Cumulative Layout Shift (CLS).
  • <figure>/<figcaption> relie sémantiquement un média et sa légende.

Exercices pratiques

1 disponible
1

Mission : corriger produit.html avant la mise en ligne

Objectif : Corriger un bug de Cumulative Layout Shift sur une image produit et sécuriser un lien externe qui s'ouvre dans un nouvel onglet.

Contexte

Le chef de projet signale deux problèmes sur produit.html : le texte "saute" vers le bas d'une vingtaine de pixels dès que la photo produit.jpg finit de charger, et le lien vers le site du fabricant, <a href="https://fabricant.com" target="_blank">, s'ouvre dans un nouvel onglet sans aucune protection.

Ta mission : corriger ces deux défauts.

Résoudre l’exercice →