RM Partie 7 : Médias et formulaires
Partie 7 — Médias et formulaires
1) Objectifs pédagogiques
- intégrer des médias avec
<audio>,<video>,<iframe>et leurs attributs clés (accessibilité, performance, sécurité) ; - construire des formulaires HTML accessibles
avec
<form>,<label>,<input>,<textarea>,<select>,<button>; - utiliser les types de champs HTML5
(
email,number,date,range,color, etc.) ; - appliquer des attributs modernes de
validation/ex-périence (
required,placeholder,pattern,min,max,step,autocomplete, etc.) ; - réaliser un formulaire de contact simple et correct.
2) Insertion de médias
2.1 <audio>
Balise pour lire du son. Formats courants : MP3 (
audio/mpeg), Ogg (audio/ogg), WAV (audio/wav).Attributs utiles :
controls(affiche les contrôles natifs)autoplay(démarre automatiquement — à éviter, et souvent bloqué sauf simuted)loop(boucle)preload="none|metadata|auto"(politique de préchargement)muted(démarre muet)crossorigin="anonymous|use-credentials"(si source cross-origin)
<audio controls preload="metadata">
<source src="media/jingle.mp3" type="audio/mpeg">
<source src="media/jingle.ogg" type="audio/ogg">
Votre navigateur ne supporte pas l’audio HTML5.
</audio>2.2 <video>
Pour la vidéo. Formats courants : MP4/H.264 (
video/mp4), WebM (video/webm), Ogg/Theora (video/ogg).Attributs utiles :
controls,autoplay,muted,loop,playsinline(mobile),preload,poster="image.jpg"width/height(réserver l’espace, éviter les sauts de mise en page)crossorigin(si nécessaire)
Sous-titres / accessibilité via
<track>:<track kind="subtitles|captions|descriptions|chapters|metadata" srclang="fr" label="Français" src="subs.vtt" default>- Format de sous-titres : WebVTT
(
.vtt)
<video controls width="800" height="450" preload="metadata" poster="media/apercu.jpg">
<source src="media/demo.webm" type="video/webm">
<source src="media/demo.mp4" type="video/mp4">
<track kind="subtitles" srclang="fr" label="Français" src="media/demo-fr.vtt" default>
Votre navigateur ne supporte pas la vidéo HTML5.
</video>Bonnes pratiques vidéo :
- ne pas forcer
autoplay(saufmuted) ;- fournir des sous-titres (accessibilité) ;
- définir
width/heightpour la stabilité ;- utiliser
preload="metadata"pour limiter le réseau.
2.3 <iframe>
Intègre une page web tierce (ex. carte, lecteur externe).
Attention sécurité : iframes peuvent exposer ta page ; toujours restreindre.
Attributs utiles :
src(URL),title(obligatoire pour accessibilité),loading="lazy"sandbox(désactive scripts/fonctions par défaut, puis autoriser finement) Exemples :sandboxtout court (très restrictif) ; ousandbox="allow-scripts allow-same-origin allow-forms".referrerpolicy="no-referrer"oustrict-origin-when-cross-originselon ton besoinallow(liste d’autorisations :fullscreen; geolocation; clipboard-read; ...)width/heightou CSSaspect-ratiopour le responsive
<div class="embed">
<iframe
src="https://www.example.com/carte"
title="Carte interactive de la zone"
loading="lazy"
sandbox="allow-scripts allow-same-origin"
referrerpolicy="strict-origin-when-cross-origin">
</iframe>
</div>
<style>
.embed { max-width: 900px; margin: 1rem auto; }
.embed iframe { width: 100%; aspect-ratio: 16 / 9; border: 0; }
</style>3) Formulaires HTML — bases solides
3.1 <form>
Enveloppe qui regroupe les champs et définit l’envoi :
action="/endpoint"(URL de réception)method="get|post"(GET pour lecture/recherche ; POST pour créer/envoyer des données)enctype(type d’encodage) :application/x-www-form-urlencoded(défaut)multipart/form-data(upload de fichiers)text/plain(rarement utile)
novalidate(désactive la validation HTML5)autocomplete="on|off"(ou plus fin sur chaque champ)
3.2 name,
id, label (indispensables)
name: clé utilisée lors de la soumission (sansname, le champ n’est pas envoyé).id+<label for="id">: associe sémantiquement le libellé au champ (clic sur le label → focus).- Toujours préférer un label visible (ne pas
remplacer par un
placeholder).
<form action="/contact" method="post">
<div>
<label for="fnom">Nom</label>
<input type="text" id="fnom" name="nom" required>
</div>
</form>3.3 Groupes de champs
<fieldset>+<legend>pour regrouper logiquement : accessibilité ++disabledsur<fieldset>pour désactiver tout un groupe.
<fieldset>
<legend>Coordonnées</legend>
<!-- champs -->
</fieldset>3.4 Contrôles principaux
<input>: champ générique (type varie)<textarea>: texte multi-ligne<select>+<option>(+<optgroup>)<button>(types :submit|button|reset)
4) Types
d’<input> (HTML5 inclus)
4.1 Texte & variantes
<input type="text" id="nom" name="nom" required>
<input type="email" id="mail" name="email" required>
<input type="url" id="site" name="site">
<input type="tel" id="tel" name="tel" inputmode="tel">email: validation de forme (peut accepter plusieurs simultiple)url: validation de forme URLtel: pas de validation, mais clavier numérique sur mobile (inputmode="tel")autocomplete="given-name|family-name|email|tel|organization|street-address|postal-code|country"…
4.2 Nombres & sliders
<input type="number" id="age" name="age" min="0" max="120" step="1">
<input type="range" id="note" name="note" min="0" max="10" step="1" value="5">number: flèches + validation (attention aux séparateurs décimaux par locale)range: slider (prévoir un affichage de valeur via JS si besoin)
4.3 Dates & couleurs
<input type="date" id="rdv" name="rdv">
<input type="time" id="heure" name="heure">
<input type="datetime-local" id="dt" name="dt">
<input type="month" id="mois" name="mois">
<input type="week" id="semaine" name="semaine">
<input type="color" id="couleur" name="couleur" value="#204ECF">4.4 Sélections binaires et choix
<input type="checkbox" id="cgu" name="cgu" required>
<label for="cgu">J’accepte les conditions</label>
<!-- Radios : même name, valeurs différentes -->
<label><input type="radio" name="genre" value="f"> Femme</label>
<label><input type="radio" name="genre" value="h"> Homme</label>
<label><input type="radio" name="genre" value="na" checked> Préfère ne pas répondre</label>4.5 Fichiers
<input type="file" id="cv" name="cv" accept=".pdf,.doc,.docx" />
<!-- multiple pour plusieurs fichiers -->Pour uploader des fichiers, form doit être
enctype="multipart/form-data".
4.6 Aides à la saisie
placeholder="ex: Jean Dupont": exemple ou indice (ne remplace pas un label)maxlength,minlengthpattern="^0[1-9](\s?\d{2}){4}$"(ex. pattern pour téléphone FR — simple ; garde en tête queteln’impose rien)inputmode="numeric|decimal|email|url|search": clavier virtuel adaptélist+<datalist>: suggestions non contraignantes
<input id="ville" name="ville" list="villes">
<datalist id="villes">
<option value="Amiens">
<option value="Lille">
<option value="Paris">
</datalist>5) <textarea>,
<select>, <button>
5.1 <textarea>
<label for="msg">Message</label>
<textarea id="msg" name="message" rows="6" maxlength="2000" placeholder="Ton message…"></textarea>- Attributs utiles :
rows,cols,maxlength,placeholder,wrap="soft|hard"
5.2 <select>
<label for="sujet">Sujet</label>
<select id="sujet" name="sujet">
<option value="">— Choisir —</option>
<optgroup label="Support">
<option value="bug">Signaler un bug</option>
<option value="aide">Demander de l’aide</option>
</optgroup>
<optgroup label="Infos">
<option value="devis">Demander un devis</option>
</optgroup>
</select>multiple(sélections multiples) +size(nombre d’éléments visibles)
5.3 <button>
<button type="submit">Envoyer</button>
<button type="reset">Réinitialiser</button>
<button type="button">Action JS</button>- Par défaut, un
<button>dans un<form>esttype="submit"→ explicite letypepour éviter les surprises.
6) Validation et accessibilité (sans JS)
6.1 Validation HTML5
required: champ obligatoiretypedétermine une validation native (email, url, number…)min,max,step(numérique/dates)pattern: regex (ancre la regex — souvent^…$):valid,:invalid,:required,:optional(pseudo-classes CSS)titlepeut préciser l’exigence d’unpattern.
input:required:invalid { border-color: #d33; }
input:required:valid { border-color: #2a7; }6.2 A11y (accessibilité)
- Toujours un
<label>lié (for/id) ; placeholder ≠ label. aria-describedby="idAide"pour relier un texte d’aide ou d’erreur.- Groupes logiques avec
<fieldset>/<legend>. - Ordre logique des champs ; navigation Tab fluide.
- Contrastes suffisants et focus visibles (
:focus/:focus-visible).
7) Exemple de formulaire enrichi (aperçu)
<form action="/contact" method="post" autocomplete="on">
<fieldset>
<legend>Contact</legend>
<div>
<label for="nom">Nom</label>
<input type="text" id="nom" name="nom" required autocomplete="family-name">
</div>
<div>
<label for="email">E-mail</label>
<input type="email" id="email" name="email" required autocomplete="email" placeholder="prenom.nom@example.com">
</div>
<div>
<label for="sujet">Sujet</label>
<select id="sujet" name="sujet" required>
<option value="">— Choisir —</option>
<option value="infos">Demande d’informations</option>
<option value="support">Support technique</option>
<option value="autre">Autre</option>
</select>
</div>
<div>
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" required minlength="10" maxlength="2000"></textarea>
<p id="aide-msg">Min. 10 caractères. Max. 2000.</p>
</div>
<div>
<input type="checkbox" id="cgu" name="cgu" required>
<label for="cgu">J’accepte les conditions d’utilisation</label>
</div>
<div>
<button type="submit">Envoyer</button>
<button type="reset">Réinitialiser</button>
</div>
</fieldset>
</form>Pour un upload de fichier :
<form enctype="multipart/form-data">+<input type="file">.
8) Exercice
But : Créer un formulaire de contact simple.
Exigences minimales :
Champs :
- Nom (obligatoire)
- E-mail (obligatoire, type
email) - Message (obligatoire, 10 à 2000 caractères)
Bouton Envoyer (type
submit)Associés à des labels ;
requiredlà où nécessaire(Bonus) Ajouter un champ Sujet (
<select>), et une case CGU (checkbox)
Style minimal suggéré (optionnel) :
- police lisible, largeur max ~ 60ch,
line-height: 1.6 - états de validation visibles (bordure/ombre)
9) Corrigé possible (HTML + CSS basique)
index.html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Contact — Exercice formulaires</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="assets/css/contact.css">
</head>
<body>
<main class="container">
<h1>Contact</h1>
<!-- MEDIA DÉMO (facultatif) -->
<figure>
<figcaption>Extrait audio de présentation (facultatif)</figcaption>
<audio controls preload="metadata">
<source src="media/intro.mp3" type="audio/mpeg">
Votre navigateur ne supporte pas l’audio HTML5.
</audio>
</figure>
<form action="/contact" method="post" class="form" autocomplete="on" novalidate>
<fieldset>
<legend>Écris-nous</legend>
<div class="field">
<label for="nom">Nom</label>
<input type="text" id="nom" name="nom" required autocomplete="name" placeholder="Jean Dupont">
<small id="nom-help" class="help">Ton nom complet.</small>
</div>
<div class="field">
<label for="email">E-mail</label>
<input type="email" id="email" name="email" required autocomplete="email" placeholder="prenom.nom@example.com">
<small class="help">Nous ne partagerons pas ton e-mail.</small>
</div>
<div class="field">
<label for="sujet">Sujet</label>
<select id="sujet" name="sujet" required>
<option value="">— Choisir —</option>
<option value="infos">Demande d’informations</option>
<option value="support">Support technique</option>
<option value="autre">Autre</option>
</select>
</div>
<div class="field">
<label for="message">Message</label>
<textarea id="message" name="message" rows="6" minlength="10" maxlength="2000" required placeholder="Ton message…"></textarea>
<small class="help">Entre 10 et 2000 caractères.</small>
</div>
<div class="checks">
<input type="checkbox" id="cgu" name="cgu" required>
<label for="cgu">J’accepte les conditions d’utilisation</label>
</div>
<div class="actions">
<button type="submit">Envoyer</button>
<button type="reset">Réinitialiser</button>
</div>
</fieldset>
</form>
</main>
</body>
</html>assets/css/contact.css
/* Base & typographie */
*,
*::before,
*::after { box-sizing: border-box; }
html { font-size: 100%; }
body {
margin: 0;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
color: #222;
background: #f7f9fc;
line-height: 1.6;
}
/* Conteneur centré */
.container {
max-width: 60ch;
margin: 2rem auto;
padding: 0 1rem;
}
/* Formulaire */
.form fieldset { border: 1px solid #e5e7eb; padding: 1rem 1.25rem; background: #fff; }
.form legend { font-weight: 600; padding: 0 .25rem; }
.field { margin: 1rem 0; }
.field label { display: block; font-weight: 600; margin-bottom: .25rem; }
.field input[type="text"],
.field input[type="email"],
.field select,
.field textarea {
width: 100%;
padding: .6rem .7rem;
border: 1px solid #c8ced8;
border-radius: 4px;
background: #fff;
color: #222;
}
.field textarea { resize: vertical; }
.help { display: block; color: #5f6b7a; font-size: .875rem; margin-top: .25rem; }
/* Cases à cocher */
.checks {
display: flex;
align-items: center;
gap: .5rem;
margin: 1rem 0;
}
/* Actions */
.actions { display: flex; gap: .5rem; }
.actions button {
padding: .6rem .9rem;
border: 1px solid #204ecf;
background: #204ecf;
color: #fff;
border-radius: 4px;
cursor: pointer;
}
.actions button[type="reset"] {
background: #fff;
color: #204ecf;
}
/* États de focus & validation */
.field input:focus,
.field select:focus,
.field textarea:focus {
outline: 2px solid transparent;
box-shadow: 0 0 0 3px rgba(32,78,207,.25);
border-color: #204ecf;
}
.field input:required:invalid,
.field select:required:invalid,
.field textarea:required:invalid {
border-color: #d33;
}
.field input:required:valid,
.field select:required:valid,
.field textarea:required:valid {
border-color: #2a7;
}Note : j’ai mis
novalidatesur le<form>pour éviter les popups natives hétérogènes pendant la démo ; tu peux le retirer pour activer la validation native.
10) Pièges fréquents
- Remplacer les labels par des placeholders → mauvaise accessibilité et perte du contexte au remplissage.
- Oublier les
name→ les champs ne sont pas envoyés. - Abuser de
patternpour l’e-mail → préfèretype="email"(et valide côté serveur). - Oublier
enctype="multipart/form-data"pour un upload de fichiers. - Mettre
autoplaysansmuted→ bloqué par les navigateurs. - Intégrer des iframes sans
titlenisandbox→ accessibilité/sécurité dégradées. - Oublier
width/heightsur<video>→ sauts de mise en page.
11) Mini-quiz
- Donne 3 attributs importants pour
<video>et explique leur utilité. - À quoi servent
actionetmethodsur<form>? Quand utiliserGETvsPOST? - Différence entre
requiredetpattern? - Pourquoi un
<label>lié à un champ est-il indispensable ? - Quel encodage de formulaire pour un upload de fichier ?
- Donne un exemple d’
inputde typerangeavecmin,max,step, et valeur par défaut. - Quel attribut rend un
<iframe>plus sûr par défaut ?
Réponses (bref)
controls(ui),poster(aperçu),preload(réseau),muted/autoplay/playsinline(comportement),width/height(stabilité),track(sous-titres).action= URL de réception ;method= verbe HTTP ; GET pour lecture/recherche (idempotent), POST pour envoi/écriture.requiredrend le champ obligatoire ;patternexige une forme précise (regex).- Accessibilité, zone de clic plus large, annonce correcte par lecteurs d’écran.
enctype="multipart/form-data".<input type="range" min="0" max="10" step="1" value="5">.sandbox(puis autoriser finement avecallow-*si besoin).
12) Fiche-mémo (à coller en fin de poly)
- Audio/vidéo :
controls,preload="metadata",poster,mutedsi autoplay,track(sous-titres),width/height. - Iframe :
title,loading="lazy",sandbox(puisallow-*),referrerpolicy,aspect-ratioCSS. - Form :
action,method,enctype,autocomplete,novalidate. - Champs :
label for/id,name(soumission),required,min|max|step,pattern,placeholder(indice),inputmode,autocomplete. - Types HTML5 :
email,url,tel,number,range,date/time/datetime-local/month/week,color,file,checkbox,radio. - Accessibilité : labels visibles,
fieldset/legend,aria-describedbypour aides/erreurs, focus visible, contraste. - Toujours valider côté serveur en plus de la validation HTML5.