-
Objectifs
- Comprendre la structure d'un formulaire horizontal en Bootstrap 5.3 (grille
.row / .col-*)
- Être capable d'aligner étiquettes et champs côte à côte, y compris pour les cases à cocher, boutons radio et listes
- Être capable de rendre un formulaire horizontal adaptatif (responsive)
-
-
Présentation
- Bootstrap permet trois dispositions principales de formulaires :
- Formulaire vertical (par défaut) : chaque étiquette au-dessus de son champ ;
- Formulaire en ligne : tous les éléments sur une seule ligne ;
- Formulaire horizontal: l'étiquette à gauche et le champ à droite, une ligne par champ.
- Le formulaire horizontal est adapté aux formulaires de taille moyenne (inscription, profil, paramètres) : il est compact et facile à parcourir des yeux.
- Il repose entièrement sur le système de grille de Bootstrap : aucune classe spéciale n'est appliquée au
<form>.
-
- Pour créer un formulaire horizontal, procédez comme suit :
- Pour chaque champ, créez un <div> avec les classes
.row (ligne de grille) et .mb-3 (espacement sous la ligne).
- Donnez à l'étiquette une largeur de colonne (
.col-sm-2) et la classe .col-form-label: elle est alors centrée verticalement par rapport au champ.
- Placez le champ dans un <div> de colonne qui complète la ligne (
.col-sm-10, car 2 + 10 = 12).
- Pour les éléments sans étiquette (case à cocher, bouton), décalez la colonne avec
.offset-sm-2 afin de les aligner sur les champs.
- Le préfixe
sm signifie que la disposition horizontale s'applique à partir de 576 px. En dessous (mobile), les étiquettes repassent automatiquement au-dessus des champs.
<form>
<div class="row mb-3">
<label for="prenom" class="col-sm-2 col-form-label">Prénom</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="prenom" placeholder="Entrez votre prénom">
</div>
</div>
<div class="row mb-3">
<label for="nom" class="col-sm-2 col-form-label">Nom</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="nom" placeholder="Entrez votre nom">
</div>
</div>
<div class="row mb-3">
<div class="col-sm-10 offset-sm-2">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="souvenir">
<label class="form-check-label" for="souvenir">Se souvenir de moi</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-10 offset-sm-2">
<button type="submit" class="btn btn-primary">Se connecter</button>
</div>
</div>
</form>
- Ce qui nous donne la figure suivante.

-
- Un groupe de boutons radio (ou de cases) se décrit avec un <fieldset> et un titre <legend>.
- Le
<fieldset> prend la classe .row, et la <legend> les classes .col-form-label + une largeur de colonne.
- Ajoutez
.pt-0 à la <legend> pour qu'elle soit alignée avec le premier bouton radio (et non centrée sur tout le groupe).
<fieldset class="row mb-3">
<legend class="col-form-label col-sm-2 pt-0">Niveau</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="niveau" id="niveau1" value="debutant" checked>
<label class="form-check-label" for="niveau1">Débutant</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="niveau" id="niveau2" value="intermediaire">
<label class="form-check-label" for="niveau2">Intermédiaire</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="niveau" id="niveau3" value="avance" disabled>
<label class="form-check-label" for="niveau3">Avancé (indisponible)</label>
</div>
</div>
</fieldset>
-
Taille des étiquettes
- Quand un champ est agrandi (
.form-control-lg) ou réduit (.form-control-sm), l'étiquette doit suivre pour rester bien alignée.
- Utilisez alors
.col-form-label-lg ou .col-form-label-sm en plus de .col-form-label.
<div class="row mb-3">
<label for="champSm" class="col-sm-2 col-form-label col-form-label-sm">Petit</label>
<div class="col-sm-10">
<input type="text" class="form-control form-control-sm" id="champSm" placeholder="Petit champ">
</div>
</div>
<div class="row mb-3">
<label for="champLg" class="col-sm-2 col-form-label col-form-label-lg">Grand</label>
<div class="col-sm-10">
<input type="text" class="form-control form-control-lg" id="champLg" placeholder="Grand champ">
</div>
</div>
-
Largeur des colonnes et disposition responsive
- Vous pouvez choisir librement le partage étiquette / champ, à condition que la somme fasse 12:
.col-sm-3 + .col-sm-9, .col-sm-4 + .col-sm-8…
- On peut combiner plusieurs points de rupture : par exemple
.col-md-3 .col-lg-2 pour une étiquette plus étroite sur les très grands écrans.
- Un champ n'est pas obligé d'occuper toute la ligne :
.col-sm-4 pour un code postal, .col-sm-auto pour une largeur adaptée au contenu.
- Plusieurs champs peuvent partager une même ligne (ex. code postal + ville).
<div class="row mb-3">
<label for="adresse" class="col-md-3 col-lg-2 col-form-label">Adresse</label>
<div class="col-md-9 col-lg-10">
<input type="text" class="form-control" id="adresse" placeholder="N° et rue">
</div>
</div>
<div class="row mb-3">
<label for="cp" class="col-md-3 col-lg-2 col-form-label">Code postal</label>
<div class="col-md-3 col-lg-2">
<input type="text" class="form-control" id="cp" placeholder="8000">
</div>
<label for="ville" class="col-md-2 col-lg-1 col-form-label">Ville</label>
<div class="col-md-4 col-lg-7">
<input type="text" class="form-control" id="ville" placeholder="Nabeul">
</div>
</div>
-
- Cet exemple regroupe les principaux contrôles dans une disposition horizontale : e-mail avec texte d'aide, mot de passe, liste, zone de texte, interrupteur et boutons.
<form class="p-4 border rounded">
<div class="row mb-3">
<label for="email" class="col-sm-3 col-form-label">E-mail</label>
<div class="col-sm-9">
<input type="email" class="form-control" id="email" aria-describedby="emailAide" required>
<div id="emailAide" class="form-text">Votre adresse ne sera jamais partagée.</div>
</div>
</div>
<div class="row mb-3">
<label for="mdp" class="col-sm-3 col-form-label">Mot de passe</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="mdp" minlength="8" required>
</div>
</div>
<div class="row mb-3">
<label for="filiere" class="col-sm-3 col-form-label">Filière</label>
<div class="col-sm-9">
<select class="form-select" id="filiere">
<option selected disabled value="">Choisir une filière</option>
<option value="web">Développement web</option>
<option value="mobile">Développement mobile</option>
</select>
</div>
</div>
<div class="row mb-3">
<label for="motivation" class="col-sm-3 col-form-label">Motivation</label>
<div class="col-sm-9">
<textarea class="form-control" id="motivation" rows="3"></textarea>
</div>
</div>
<div class="row mb-3">
<div class="col-sm-9 offset-sm-3">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="newsletter">
<label class="form-check-label" for="newsletter">Recevoir la newsletter</label>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-9 offset-sm-3">
<button type="submit" class="btn btn-primary">S'inscrire</button>
<button type="reset" class="btn btn-outline-secondary ms-2">Annuler</button>
</div>
</div>
</form>
-
Comparaison Bootstrap 3, 4 et 5.3
- La structure des formulaires horizontaux a évolué d'une version à l'autre :
| Élément |
Bootstrap 3 |
Bootstrap 4 |
Bootstrap 5.3 |
Classe sur <form> |
.form-horizontal obligatoire |
aucune |
aucune |
| Ligne d'un champ |
.form-group |
.form-group.row |
.row.mb-3 |
| Étiquette |
.control-label |
.col-form-label |
.col-form-label |
| Décalage de colonne |
.col-sm-offset-2 |
.offset-sm-2 |
.offset-sm-2 |
| Case à cocher |
.checkbox |
.form-check |
.form-check (+ .form-switch) |
| Liste déroulante |
.form-control |
.form-control / .custom-select |
.form-select |
| Bouton neutre |
.btn-default |
.btn-secondary |
.btn-secondary, .btn-outline-* |
-
Bonnes pratiques
- Vérifiez que la somme des colonnes de chaque ligne vaut 12 (étiquette + champ, ou offset + contenu).
- Utilisez le même partage (ex. 3/9) sur toutes les lignes pour un alignement propre.
- Choisissez le point de rupture (
sm, md, lg) selon la longueur des étiquettes : des étiquettes longues demandent plus de place, donc un point de rupture plus grand.
- Reliez toujours chaque
<label> à son champ (for = id) et utilisez <fieldset> + <legend> pour les groupes de radios ou de cases.
- Testez sur mobile : en dessous du point de rupture, le formulaire redevient vertical.