Tableaux et formulaires en HTML 5
Sommaire
Un tableau HTML sert à présenter des données tabulaires : des valeurs qui se lisent en croisant lignes et colonnes. Historiquement, les tableaux ont aussi été détournés pour faire de la mise en page ; cette pratique est aujourd’hui à proscrire absolument — c’est le rôle de CSS (Flexbox et Grid, chapitre 8).
4.1. Tableau simple
Un tableau est délimité par <table>. Chaque ligne est un <tr> (table row), qui contient des cellules de deux types : <th> (table header) pour les en-têtes et <td> (table data) pour les données. Une légende, fortement recommandée, s’ajoute avec <caption> en premier enfant de <table>.
Sur chaque <th>, l’attribut scope= précise la portée de l’en-tête : col (la colonne entière) ou row (la ligne entière).
<table>
<caption>Heures de travail nécessaires à la production d'une unité</caption>
<tr>
<th scope="col">Pays</th>
<th scope="col">Drap</th>
<th scope="col">Vin</th>
</tr>
<tr>
<th scope="row">Angleterre</th>
<td>100</td>
<td>120</td>
</tr>
<tr>
<th scope="row">Portugal</th>
<td>90</td>
<td>80</td>
</tr>
</table>
4.2. En-tête, corps et pied de tableau
Comme la page elle-même, un tableau peut être structuré en trois zones : <thead> (lignes d’en-tête), <tbody> (corps) et <tfoot> (ligne de synthèse : totaux, moyennes…). Cette structure clarifie le code et permet, en CSS, de styler chaque zone séparément.
<table>
<caption>Fréquentation mensuelle</caption>
<thead>
<tr>
<th scope="col">Mois</th>
<th scope="col">Visiteurs</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Janvier</th>
<td>1 240</td>
</tr>
<tr>
<th scope="row">Février</th>
<td>1 105</td>
</tr>
</tbody>
<tfoot>
<tr>
<th scope="row">Total</th>
<td>2 345</td>
</tr>
</tfoot>
</table>
4.3. Tableaux complexes
Un tableau est dit complexe dès qu’une cellule s’étend sur plusieurs lignes ou colonnes, au moyen des attributs rowspan= et colspan=.
Ces fusions perturbent la lecture automatique : le simple scope= ne suffit plus à relier chaque donnée à ses en-têtes. La solution : donner un identifiant (id=) à chaque <th>, puis lister explicitement dans chaque <td> les identifiants de ses en-têtes via l’attribut headers=.
<table>
<caption>Chiffre d'affaires semestriel</caption>
<thead>
<tr>
<th id="entreprise" rowspan="2">Entreprise</th>
<th id="ca" colspan="2">Chiffre d'affaires</th>
</tr>
<tr>
<th id="semestre-1" headers="ca">1er semestre</th>
<th id="semestre-2" headers="ca">2e semestre</th>
</tr>
</thead>
<tbody>
<tr>
<th id="societe-1" headers="entreprise">Société 1</th>
<td headers="societe-1 semestre-1">10</td>
<td headers="societe-1 semestre-2">20</td>
</tr>
<tr>
<th id="societe-2" headers="entreprise">Société 2</th>
<td headers="societe-2 semestre-1">30</td>
<td headers="societe-2 semestre-2">40</td>
</tr>
</tbody>
<tfoot>
<tr>
<th id="total" headers="entreprise">Total</th>
<td headers="total semestre-1">40</td>
<td headers="total semestre-2">60</td>
</tr>
</tfoot>
</table>
Un formulaire permet à l’utilisateur de saisir des données et de les envoyer au serveur. Il est délimité par la balise de type bloc <form> et contient des contrôles : champs de saisie, listes, cases à cocher, boutons…
5.1. Le contrôle universel : <input>
La plupart des contrôles se déclarent avec la balise vide <input>. Deux attributs sont essentiels : name=, le nom sous lequel la donnée sera transmise au serveur, et type=, qui détermine la nature du contrôle :
| Type | Description |
|---|---|
text | Champ de texte libre sur une ligne |
number | Valeur numérique (avec attributs min=, max=, step=) |
email | Adresse électronique (validation automatique du format) |
tel | Numéro de téléphone (affiche le clavier numérique sur mobile) |
url | Adresse web (validation automatique du format) |
password | Mot de passe (saisie masquée) |
checkbox | Case à cocher (choix multiples) |
radio | Bouton radio (choix unique parmi les input partageant le même name=) |
date / time | Sélecteur de date / d’heure |
color | Sélecteur de couleur |
file | Sélecteur de fichier à téléverser |
hidden | Valeur transmise sans être affichée |
L’attribut value= fixe une valeur initiale. Pour les cases à cocher et boutons radio, l’attribut checked présélectionne le contrôle.
5.2. Listes déroulantes : <select>
Une liste déroulante se construit avec <select> (qui porte le name=) et des <option> :
<label for="visite">Visite guidée souhaitée</label>
<select name="visite" id="visite">
<option value="">— Choisir une visite —</option>
<option value="vieux-port">Le vieux port</option>
<option value="citadelle" selected>La citadelle</option>
</select>
L’attribut selected présélectionne une option ; <optgroup label="…"> permet de regrouper des options sous un intitulé commun.
5.3. Zones de texte multilignes : <textarea>
Pour une saisie libre sur plusieurs lignes, <textarea> s’utilise avec une balise ouvrante et une balise fermante. rows= et cols= suggèrent ses dimensions initiales, maxlength= limite la longueur du texte.
5.4. Boutons
Un bouton se définit avec <button>, dont le nœud texte constitue le libellé. Son attribut type= prend trois valeurs :
submit(valeur par défaut) : déclenche l’envoi du formulaire ;reset: réinitialise tous les contrôles à leur valeur initiale (à utiliser avec prudence : un clic malheureux efface toute la saisie) ;button: sans effet propre, pour un comportement défini en JavaScript.
5.5. Libellés et regroupements : la clé de l’accessibilité
Chaque contrôle doit avoir un libellé, déclaré avec <label>. Deux écritures sont possibles :
<!-- Liaison explicite par for/id (recommandée) -->
<label for="courriel">Adresse électronique</label>
<input type="email" name="courriel" id="courriel">
<!-- Liaison par imbrication -->
<label>
Adresse électronique
<input type="email" name="courriel">
</label>
Les contrôles apparentés — typiquement une série de boutons radio — se regroupent dans un <fieldset>, dont le premier enfant <legend> donne l’intitulé du groupe :
<fieldset>
<legend>Formule d'abonnement</legend>
<label><input type="radio" name="formule" value="simple" checked> Simple</label>
<label><input type="radio" name="formule" value="famille"> Famille</label>
</fieldset>
5.6. Validation et envoi des données
L’attribut required, ajouté à un contrôle, le rend obligatoire : le navigateur bloque l’envoi et signale le champ s’il est vide. Les attributs min=, max=, maxlength= et pattern= (expression régulière) complètent cette validation native, qui reste une aide à la saisie : le serveur doit toujours revalider les données.
L’envoi est piloté par deux attributs de <form> :
action=: URL destinataire des données (facultatif si c’est la page courante) ;method=:gettransmet les valeurs dans l’URL (?nom=valeur&autre=valeur), adapté aux recherches et filtres ;postles transmet dans le corps de la requête HTTP, obligatoire dès que les données sont sensibles ou modifient un état côté serveur.
<form action="/inscription" method="post">
<label for="nom">Nom</label>
<input type="text" name="nom" id="nom" autocomplete="family-name" required>
<label for="courriel">Adresse électronique</label>
<input type="email" name="courriel" id="courriel" autocomplete="email" required>
<button type="submit">S'inscrire</button>
</form>