Le formulaire pas à pas
Apprenez à créer des formulaires HTML complets et accessibles, champ par champ, jusqu’au formulaire d’inscription professionnel.
- 11 types de champs
- Labels et ARIA
- Validation HTML5
- Projet complet
Qu'est-ce qu'un Formulaire HTML ?
Les formulaires sont essentiels pour l'interactivité web : collecte de données, authentification, feedback utilisateur, commandes...
Anatomie d'un Formulaire
Structure de base :
html
<form action="traitement.php" method="POST">
<label for="nom">Nom :</label>
<input type="text" id="nom" name="nom" required>
<button type="submit">Envoyer</button>
</form>
Composants expliqués :
<form>
Conteneur principal avec action (où envoyer) et méthode (comment envoyer)
<label>
Étiquette associée à un champ pour l'accessibilité
<input>
Champ de saisie avec type, nom et validation
<button>
Bouton d'envoi ou d'action
Méthodes GET vs POST
GET Méthode GET
- Données visibles dans l'URL
- Limitée à ~2000 caractères
- Peut être mise en favoris
- Idéale pour recherche/filtres
html
URL résultante :
site.com/search?q=pizza&ville=paris
POST Méthode POST
- Données cachées (corps de requête)
- Aucune limite de taille
- Plus sécurisé
- Pour inscription, connexion, upload
html
Données cachées dans :
Corps HTTP (invisible)
Structure et Attributs Essentiels
Découvrez les attributs indispensables pour créer des formulaires professionnels et accessibles.
Attributs <form>
action
URL de destination des données
action="process.php"
method
GET ou POST
method="POST"
enctype
Pour upload de fichiers
enctype="multipart/form-data"
Attributs <input>
name
Identifiant côté serveur
name="email"
id
Lien avec <label>
id="user_email"
placeholder
placeholder="nom@email.com"
Validation HTML5
required
required
pattern
pattern="[0-9]{5}"
min/max
min="1" max="100"
Les 10 Types de Champs Essentiels
Découvrez chaque type de champ avec ses spécificités, ses attributs et ses cas d'usage.
1 Champ Texte (type="text")
Code HTML :
html
<label for="nom">Nom complet :</label>
<input
type="text"
id="nom"
name="nom"
placeholder="Jean Dupont"
maxlength="50"
required
>
Attributs spécifiques :
- maxlength : Nombre max de caractères
- minlength : Nombre min de caractères
- size : Largeur visible du champ
- readonly : Lecture seule
Rendu visuel :
Cas d'usage :
- Noms, prénoms
- Adresses
- Titres d'articles
- Recherche générale
11 Champ Caché (type="hidden")
Code HTML :
html
<!-- Token CSRF -->
<input
type="hidden"
name="_token"
value="csrf_abc123xyz"
>
<!-- ID d'utilisateur -->
<input
type="hidden"
name="user_id"
value="1234"
>
<!-- Action/État -->
<input
type="hidden"
name="action"
value="update_profile"
>
Caractéristiques :
- Invisible à l'utilisateur
- Pas d'interaction possible
- Transmis automatiquement
- Valeur fixe ou générée dynamiquement
Rendu visuel :
⚠️ Sécurité importante :
- Visible dans le code source HTML
- Modifiable par l'utilisateur technique
- Toujours valider côté serveur
- Ne pas stocker de données sensibles
✅ Cas d'usage courants :
- Tokens CSRF : Protection contre les attaques
- IDs d'enregistrement : Identifier les données à modifier
- Actions de formulaire : Spécifier l'opération à effectuer
- Données de session : Informations temporaires
- Valeurs calculées : Résultats d'étapes précédentes
- Timestamps : Horodatage de soumission
❌ À éviter absolument :
- Mots de passe : Visibles dans le code source
- Clés API : Exposées côté client
- Prix/montants : Modifiables par l'utilisateur
- Permissions : Facilement contournables
- Données personnelles : Problèmes de confidentialité
- Logique métier critique : Non sécurisée
Exemples pratiques d'utilisation :
1. Formulaire d'édition d'un article
html
<h5 class="text-white font-medium mb-3"></h5>
<form method="POST" action="/articles/update">
<!-- ID de l'article à modifier -->
<input type="hidden" name="article_id" value="456">
<!-- Token de sécurité -->
<input type="hidden" name="_token" value="">
... <!-- Champs visibles -->
</form>
2. Formulaire de panier e-commerce
html
<h5 class="text-white font-medium mb-3"></h5>
<form method="POST" action="/cart/add">
<!-- ID du produit -->
<input type="hidden" name="product_id" value="789">
<!-- Prix (calculé côté serveur, pas de sécurité ici) -->
<input type="hidden" name="price_display" value="29.99">
<!-- Quantité visible à l'utilisateur -->
<input type="number" name="quantity" min="1" value="1">
</form>
3. Formulaire multi-étapes
html
<h5 class="text-white font-medium mb-3"></h5>
<form method="POST" action="/registration/step2">
<!-- Étape courante -->
<input type="hidden" name="current_step" value="2">
<!-- Données de l'étape précédente -->
<input type="hidden" name="step1_data" value="">
<!-- Timestamp de début -->
<input type="hidden" name="started_at" value="">
... <!-- Champs de l'étape 2 -->
</form>
Manipulation avec JavaScript :
html
// Créer un champ hidden dynamiquement
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = 'dynamic_data';
hiddenInput.value = 'valeur_calculée';
form.appendChild(hiddenInput);
// Modifier la valeur d'un champ hidden existant
document.querySelector('input[name="_token"]').value = 'nouveau_token';
// Vérifier l'existence d'un champ hidden
const tokenField = document.querySelector('input[name="_token"]');
if (tokenField) {
console.log('Token:', tokenField.value);
}
2 Champ Email (type="email")
Code HTML :
html
<label for="email">Email :</label>
<input
type="email"
id="email"
name="email"
placeholder="nom@example.com"
autocomplete="email"
required
>
Rendu visuel :
Avantages :
- Validation automatique du format email
- Clavier mobile optimisé (@, .com)
- Autocomplétion du navigateur
- Impossible d'envoyer sans @ et domaine
3 Champ Mot de Passe (type="password")
Code HTML :
html
<label for="password">Mot de passe :</label>
<input
type="password"
id="password"
name="password"
minlength="8"
pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}"
required
>
Pattern expliqué :
- (?=.*[a-z]) : 1 minuscule minimum
- (?=.*[A-Z]) : 1 majuscule minimum
- (?=.*\d) : 1 chiffre minimum
- .{8,} : 8 caractères minimum
Rendu visuel :
Bonnes pratiques :
- Toujours masquer la saisie
- Ajouter des règles de complexité
- Permettre l'affichage temporaire
- Confirmation sur un 2ème champ
4 Champ Numérique (type="number")
Code HTML :
html
<label for="age">Âge :</label>
<input
type="number"
id="age"
name="age"
min="13"
max="120"
step="1"
value="25"
required
>
Rendu visuel :
Attributs spécifiques :
- min/max : Valeurs limites
- step : Incrément (0.01 pour décimales)
- value : Valeur par défaut
- Boutons +/- automatiques
5 Champ Date (type="date")
Code HTML :
html
<label for="naissance">Date de naissance :</label>
<input
type="date"
id="naissance"
name="naissance"
min="1900-01-01"
max="2010-12-31"
value="1995-06-15"
required
>
Rendu visuel :
Format et contraintes :
- Format obligatoire : YYYY-MM-DD
- Calendrier intégré dans la plupart des navigateurs
- min/max : Plage de dates autorisées
- Validation automatique de date valide
6 Liste Déroulante (<select>)
Code HTML :
html
<label for="pays">Pays :</label>
<select id="pays" name="pays" required>
<option value="">-- Choisir un pays --</option>
<optgroup label="Europe">
<option value="FR" selected>France</option>
<option value="DE">Allemagne</option>
</optgroup>
<optgroup label="Amérique">
<option value="US">États-Unis</option>
<option value="CA">Canada</option>
</optgroup>
</select>
Rendu visuel :
Éléments clés :
- <option> : Chaque choix avec value et texte
- <optgroup> : Regroupement d'options
- selected : Option présélectionnée
- multiple : Sélection multiple possible
7 Zone de Texte (<textarea>)
Code HTML :
html
<label for="message">Message :</label>
<textarea
id="message"
name="message"
rows="5"
cols="50"
placeholder="Votre message ici..."
maxlength="500"
required
>
Texte par défaut ici
</textarea>
Rendu visuel :
Différences avec input :
- Texte multiligne autorisé
- rows/cols : Taille visuelle
- Contenu entre balises (pas value)
- Redimensionnable par l'utilisateur
8 Boutons Radio (type="radio")
Code HTML :
html
<fieldset>
<legend>Genre :</legend>
<label>
<input type="radio" id="homme" name="genre" value="M" checked>
Homme
</label>
<label>
<input type="radio" id="femme" name="genre" value="F">
Femme
</label>
<label>
<input type="radio" id="autre" name="genre" value="A">
Autre
</label>
</fieldset>
Rendu visuel :
Règles importantes :
- Même name = groupe exclusif
- value différente pour chaque option
- <fieldset> + <legend> pour l'accessibilité
- Un seul choix possible par groupe
9 Cases à Cocher (type="checkbox")
Code HTML :
html
<fieldset>
<legend>Langages préférés :</legend>
<label>
<input type="checkbox" id="html" name="langages[]" value="html" checked>
HTML
</label>
<label>
<input type="checkbox" id="css" name="langages[]" value="css" checked>
CSS
</label>
<label>
<input type="checkbox" id="js" name="langages[]" value="javascript">
JavaScript
</label>
<!-- Case unique -->
<label>
<input type="checkbox" id="newsletter" name="newsletter" value="oui" required>
J'accepte les conditions
</label>
</fieldset>
Rendu visuel :
Bonnes pratiques :
- name[] : Tableau pour choix multiples
- name unique pour case unique
- required : Obligatoire à cocher
- checked : Présélectionnée
10 Upload de Fichiers (type="file")
Code HTML :
html
<!-- IMPORTANT: form avec enctype -->
<form enctype="multipart/form-data">
<label for="photo">Photo de profil :</label>
<input
type="file"
id="photo"
name="photo"
accept="image/*"
required
>
<!-- Multiple fichiers -->
<label for="documents">Documents :</label>
<input
type="file"
id="documents"
name="documents[]"
accept=".pdf,.doc,.docx"
multiple
>
</form>
Rendu visuel :
Attributs spécifiques :
- enctype="multipart/form-data" sur <form>
- accept : Types de fichiers autorisés
- multiple : Sélection multiple
- capture : Appareil photo mobile
Organisation et Accessibilité des Formulaires
Apprenez à structurer vos formulaires avec fieldset/legend et à améliorer l'expérience utilisateur avec placeholder et label.
Fieldset et Legend - Groupement de Champs
Structure de base :
html
<fieldset>
<legend>Informations personnelles</legend>
<label for="prenom">Prénom :</label>
<input type="text" id="prenom" name="prenom">
<label for="nom">Nom :</label>
<input type="text" id="nom" name="nom">
</fieldset>
<fieldset disabled>
<legend>Options avancées</legend>
<!-- Tous les champs seront désactivés -->
<input type="checkbox" name="option1"> Option 1
</fieldset>
Rendu visuel :
Avantages de fieldset/legend :
- Regroupement visuel et logique
- Amélioration de l'accessibilité
- Support des lecteurs d'écran
- Attribut disabled sur tout le groupe
Labels - Association et Accessibilité
Différentes techniques :
html
<!-- Méthode 1: for/id (recommandée) -->
<label for="email_user">Adresse email :</label>
<input type="email" id="email_user" name="email">
<!-- Méthode 2: label englobant -->
<label>
Téléphone :
<input type="tel" name="telephone">
</label>
<!-- Label avec icône et description -->
<label for="mot_de_passe" class="label-avec-info">
🔒 Mot de passe
<span class="required">*</span>
<small class="help-text">8 caractères minimum</small>
</label>
<input type="password" id="mot_de_passe" name="password">
<!-- Label pour radio/checkbox -->
<label class="checkbox-label">
<input type="checkbox" name="newsletter">
Je souhaite recevoir la newsletter hebdomadaire
</label>
Rendu et comportement :
Points clés des labels :
- Cliquer sur le label active le champ
- Obligatoire pour l'accessibilité
- for="id" = association explicite
- Label englobant = association implicite
- Peut contenir des éléments de mise en forme
Placeholder - Texte d'Aide et Exemples
Exemples d'utilisation :
html
<!-- Placeholder informatif -->
<input type="text" name="nom"
placeholder="Dupont">
<!-- Placeholder avec format -->
<input type="email" name="email"
placeholder="nom@entreprise.com">
<!-- Placeholder avec instructions -->
<input type="tel" name="telephone"
placeholder="01 23 45 67 89">
<!-- Placeholder pour recherche -->
<input type="search" name="recherche"
placeholder="Rechercher un produit, une marque...">
<!-- Textarea avec placeholder -->
<textarea name="message" rows="4"
placeholder="Décrivez votre problème en détail...">
</textarea>
<!-- Placeholder avec unité -->
<input type="number" name="poids"
placeholder="70 (en kg)">
Démonstration interactive :
⚠️ Bonnes pratiques :
- Ne JAMAIS remplacer le label par placeholder
- Donner des exemples concrets, pas des instructions
- Être concis mais informatif
- Éviter les textes redondants avec le label
❌ À éviter :
- placeholder="Entrez votre nom" (redondant)
- placeholder="Nom*" (remplace le label)
- Placeholders trop longs (lisibilité)
- Informations critiques uniquement dans placeholder
Accessibilité Avancée avec ARIA
Attributs ARIA pour formulaires :
html
<!-- Champ avec description -->
<label for="password">Mot de passe</label>
<input type="password" id="password"
aria-describedby="pwd-help pwd-error"
aria-required="true">
<div id="pwd-help">8 caractères minimum</div>
<div id="pwd-error" role="alert">Erreur: trop court</div>
<!-- Groupe avec titre -->
<div role="group" aria-labelledby="shipping-title">
<h3 id="shipping-title">Adresse de livraison</h3>
<!-- champs adresse -->
</div>
<!-- Champ optionnel -->
<label for="commentaire">
Commentaire <span aria-label="optionnel">(optionnel)</span>
</label>
<textarea id="commentaire" aria-required="false"></textarea>
Impact sur l'accessibilité :
Attributs ARIA essentiels :
- aria-required : Indique si le champ est obligatoire
- aria-describedby : Lie le champ à sa description
- aria-labelledby : Référence un titre/label
- role="alert" : Annonce les erreurs
- aria-invalid : État de validation
Bénéfices :
- Lecteurs d'écran informés
- Navigation clavier améliorée
- Contexte accessible à tous
- Conformité WCAG 2.1
Test d'accessibilité :
- Naviguer uniquement au clavier (Tab)
- Tester avec un lecteur d'écran
- Vérifier les contrastes de couleurs
- Valider avec axe DevTools
Validation HTML5 Avancée
Découvrez les techniques de validation côté client pour améliorer l'expérience utilisateur.
Messages d'Erreur Personnalisés
CSS pour le style :
html
/* Champs valides */
input:valid {
border-color: green;
background: rgba(0,255,0,0.1);
}
/* Champs invalides */
input:invalid {
border-color: red;
background: rgba(255,0,0,0.1);
}
/* Focus sur champ obligatoire vide */
input:required:invalid {
border-color: orange;
}
JavaScript pour messages :
html
// Messages personnalisés
const email = document.getElementById('email');
email.addEventListener('invalid', function(e) {
if (this.validity.valueMissing) {
this.setCustomValidity('Veuillez renseigner votre email');
} else if (this.validity.typeMismatch) {
this.setCustomValidity('Format email invalide');
} else {
this.setCustomValidity('');
}
});
Patterns (RegEx) Utiles
Code postal français :
pattern="[0-9]{5}"
Exactement 5 chiffres
Téléphone français :
pattern="0[1-9]([0-9]{8})"
Commence par 0, puis 9 chiffres
Mot de passe fort :
pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}"
8+ caractères avec maj, min, chiffre et symbole
URL :
pattern="https?://.+"
Commence par http:// ou https://
Nom d'utilisateur :
pattern="[a-zA-Z0-9_-]{3,16}"
3-16 caractères, lettres, chiffres, _ et -
Carte bancaire :
pattern="[0-9]{4}[\s]?[0-9]{4}[\s]?[0-9]{4}[\s]?[0-9]{4}"
16 chiffres avec espaces optionnels
Projet : Formulaire d'Inscription Complet
Créons ensemble un formulaire professionnel utilisant tous les 10 types de champs étudiés.
Formulaire Complet - Tous les Champs
html
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Inscription - Formulaire Complet</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
.form-group { margin-bottom: 20px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input, select, textarea { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
input:valid { border-color: green; background: rgba(0,255,0,0.1); }
input:invalid { border-color: red; background: rgba(255,0,0,0.1); }
fieldset { border: 1px solid #ddd; border-radius: 5px; padding: 15px; }
legend { font-weight: bold; padding: 0 10px; }
.checkbox-group label, .radio-group label { display: flex; align-items: center; font-weight: normal; }
.checkbox-group input, .radio-group input { width: auto; margin-right: 10px; }
button { background: #007bff; color: white; padding: 12px 30px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; }
button:hover { background: #0056b3; }
.required { color: red; }
</style>
</head>
<body>
<h1>Formulaire d'Inscription Complet</h1>
<form action="traitement.php" method="POST" enctype="multipart/form-data">
<!-- 1. CHAMP TEXTE -->
<div class="form-group">
<label for="nom">Nom complet <span class="required">*</span></label>
<input type="text" id="nom" name="nom" placeholder="Jean Dupont" maxlength="50" required>
</div>
<!-- 2. CHAMP EMAIL -->
<div class="form-group">
<label for="email">Email <span class="required">*</span></label>
<input type="email" id="email" name="email" placeholder="nom@example.com" autocomplete="email" required>
</div>
<!-- 3. CHAMP MOT DE PASSE -->
<div class="form-group">
<label for="password">Mot de passe <span class="required">*</span></label>
<input type="password" id="password" name="password" minlength="8"
pattern="(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}" required>
<small>8 caractères min. avec majuscule, minuscule et chiffre</small>
</div>
<!-- 4. CHAMP NUMÉRIQUE -->
<div class="form-group">
<label for="age">Âge <span class="required">*</span></label>
<input type="number" id="age" name="age" min="13" max="120" step="1" value="25" required>
</div>
<!-- 5. CHAMP DATE -->
<div class="form-group">
<label for="naissance">Date de naissance <span class="required">*</span></label>
<input type="date" id="naissance" name="naissance" min="1900-01-01" max="2010-12-31" required>
</div>
<!-- 6. LISTE DÉROULANTE -->
<div class="form-group">
<label for="pays">Pays <span class="required">*</span></label>
<select id="pays" name="pays" required>
<option value="">-- Choisir un pays --</option>
<optgroup label="Europe">
<option value="FR" selected>France</option>
<option value="DE">Allemagne</option>
<option value="ES">Espagne</option>
</optgroup>
<optgroup label="Amérique">
<option value="US">États-Unis</option>
<option value="CA">Canada</option>
</optgroup>
</select>
</div>
<!-- 7. ZONE DE TEXTE -->
<div class="form-group">
<label for="message">Message de présentation</label>
<textarea id="message" name="message" rows="5" placeholder="Parlez-vous un peu de vous..." maxlength="500"></textarea>
<small>Maximum 500 caractères</small>
</div>
<!-- 8. BOUTONS RADIO -->
<fieldset class="form-group">
<legend>Genre <span class="required">*</span></legend>
<div class="radio-group">
<label>
<input type="radio" id="homme" name="genre" value="M" checked required>
Homme
</label>
<label>
<input type="radio" id="femme" name="genre" value="F" required>
Femme
</label>
<label>
<input type="radio" id="autre" name="genre" value="A" required>
Autre
</label>
</div>
</fieldset>
<!-- 9. CASES À COCHER -->
<fieldset class="form-group">
<legend>Langages de programmation préférés</legend>
<div class="checkbox-group">
<label>
<input type="checkbox" name="langages[]" value="html" checked>
HTML
</label>
<label>
<input type="checkbox" name="langages[]" value="css" checked>
CSS
</label>
<label>
<input type="checkbox" name="langages[]" value="javascript">
JavaScript
</label>
<label>
<input type="checkbox" name="langages[]" value="php">
PHP
</label>
<label>
<input type="checkbox" name="langages[]" value="python">
Python
</label>
</div>
</fieldset>
<!-- 10. UPLOAD DE FICHIERS -->
<div class="form-group">
<label for="photo">Photo de profil <span class="required">*</span></label>
<input type="file" id="photo" name="photo" accept="image/*" required>
<small>Images seulement (JPG, PNG, GIF)</small>
</div>
<div class="form-group">
<label for="documents">Documents complémentaires</label>
<input type="file" id="documents" name="documents[]" accept=".pdf,.doc,.docx" multiple>
<small>PDF ou Word (sélection multiple possible)</small>
</div>
<!-- CONDITIONS OBLIGATOIRES -->
<div class="form-group">
<div class="checkbox-group">
<label>
<input type="checkbox" name="conditions" value="accepte" required>
J'accepte les <a href="conditions.html" target="_blank">conditions d'utilisation</a> <span class="required">*</span>
</label>
<label>
<input type="checkbox" name="newsletter" value="oui">
Je souhaite recevoir la newsletter
</label>
</div>
</div>
<!-- BOUTONS -->
<div class="form-group">
<button type="submit">S'inscrire</button>
<button type="reset" style="background: #6c757d; margin-left: 10px;">Réinitialiser</button>
</div>
</form>
<script>
// Messages de validation personnalisés
const email = document.getElementById('email');
const password = document.getElementById('password');
email.addEventListener('invalid', function() {
if (this.validity.valueMissing) {
this.setCustomValidity('Veuillez renseigner votre email');
} else if (this.validity.typeMismatch) {
this.setCustomValidity('Format email invalide');
} else {
this.setCustomValidity('');
}
});
email.addEventListener('input', function() {
this.setCustomValidity('');
});
password.addEventListener('invalid', function() {
if (this.validity.valueMissing) {
this.setCustomValidity('Mot de passe requis');
} else if (this.validity.patternMismatch) {
this.setCustomValidity('Le mot de passe doit contenir au moins 8 caractères avec majuscule, minuscule et chiffre');
} else {
this.setCustomValidity('');
}
});
password.addEventListener('input', function() {
this.setCustomValidity('');
});
</script>
</body>
</html>
Instructions
- 1. Créez le fichier HTML : Copiez le code ci-dessus dans un fichier formulaire-complet.html
- 2. Ouvrez dans votre navigateur : Double-cliquez sur le fichier ou faites glisser dans votre navigateur
- 3. Testez tous les champs : Remplissez le formulaire et observez la validation en temps réel
- 4. Experimentez : Modifiez les attributs, patterns et styles pour comprendre leur impact
Fonctionnalités incluses
✓
Tous les 10 types de champs Text, email, password, number, date, select, textarea, radio, checkbox, file
✓
Validation HTML5 complète Required, pattern, min/max, maxlength, accept
✓
Messages d'erreur personnalisés JavaScript pour améliorer l'expérience utilisateur
✓
Style CSS intégré Validation visuelle, responsive, professionnel
✓
Accessibilité Labels, fieldset, legend, attributs ARIA
✓
Prêt pour la production Structure professionnelle, sécurisé, maintenable
Maîtrisez les Formulaires HTML ! 📝
Vous avez maintenant tous les outils pour créer des formulaires professionnels et sécurisés. Passez à l'étape suivante : la sécurisation côté serveur.
🎯 Prochaines étapes recommandées :
1. Créer le formulaire complet • 2. Apprendre PHP pour traitement • 3. Sécuriser avec validation serveur • 4. Améliorer avec JavaScript
Maîtrisez les formulaires HTML
Vous avez maintenant tous les outils pour créer des formulaires HTML professionnels, accessibles et sécurisés.