RM

RM Partie 7 : Médias et formulaires

Partie 7 — Médias et formulaires

1) Objectifs pédagogiques


2) Insertion de médias

2.1 <audio>

<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>

<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 (sauf muted) ;
  • fournir des sous-titres (accessibilité) ;
  • définir width/height pour la stabilité ;
  • utiliser preload="metadata" pour limiter le réseau.

2.3 <iframe>

<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>

3.2 name, id, label (indispensables)

<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>Coordonnées</legend>
  <!-- champs -->
</fieldset>

3.4 Contrôles principaux


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">

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">

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

<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>

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>

5.3 <button>

<button type="submit">Envoyer</button>
<button type="reset">Réinitialiser</button>
<button type="button">Action JS</button>

6) Validation et accessibilité (sans JS)

6.1 Validation HTML5

input:required:invalid { border-color: #d33; }
input:required:valid   { border-color: #2a7; }

6.2 A11y (accessibilité)


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 :

  1. Champs :

    • Nom (obligatoire)
    • E-mail (obligatoire, type email)
    • Message (obligatoire, 10 à 2000 caractères)
  2. Bouton Envoyer (type submit)

  3. Associés à des labels ; required là où nécessaire

  4. (Bonus) Ajouter un champ Sujet (<select>), et une case CGU (checkbox)

Style minimal suggéré (optionnel) :


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 novalidate sur 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


11) Mini-quiz

  1. Donne 3 attributs importants pour <video> et explique leur utilité.
  2. À quoi servent action et method sur <form> ? Quand utiliser GET vs POST ?
  3. Différence entre required et pattern ?
  4. Pourquoi un <label> lié à un champ est-il indispensable ?
  5. Quel encodage de formulaire pour un upload de fichier ?
  6. Donne un exemple d’input de type range avec min, max, step, et valeur par défaut.
  7. Quel attribut rend un <iframe> plus sûr par défaut ?

Réponses (bref)

  1. controls (ui), poster (aperçu), preload (réseau), muted/autoplay/playsinline (comportement), width/height (stabilité), track (sous-titres).
  2. action = URL de réception ; method = verbe HTTP ; GET pour lecture/recherche (idempotent), POST pour envoi/écriture.
  3. required rend le champ obligatoire ; pattern exige une forme précise (regex).
  4. Accessibilité, zone de clic plus large, annonce correcte par lecteurs d’écran.
  5. enctype="multipart/form-data".
  6. <input type="range" min="0" max="10" step="1" value="5">.
  7. sandbox (puis autoriser finement avec allow-* si besoin).

12) Fiche-mémo (à coller en fin de poly)