MODULE H04
Bootstrap 5
Le framework CSS le plus populaire au monde — grille responsive, composants prêts à l'emploi et utilitaires puissants.
1. Introduction à Bootstrap 5
Bootstrap 5 est un framework CSS open-source qui fournit un système de grille responsive, des composants prêts à l'emploi et des utilitaires CSS. Version 5 : plus de dépendance jQuery !
Bootstrap 5 vs CSS pur Bootstrap accélère le développement mais ajoute du poids (~30KB). Pour des projets sur mesure, le CSS pur + Tailwind est souvent préférable.
2. Installation
<!-- Via CDN (rapide pour prototypage) -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mon Projet Bootstrap</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
crossorigin="anonymous">
</head>
<body>
<!-- votre contenu -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
crossorigin="anonymous"></script>
</body>
</html>
<!-- Via npm -->
<!-- npm install bootstrap -->
3. Système de grille (12 colonnes)
<!-- Container : centré et limité en largeur -->
<div class="container"> <!-- max-width selon breakpoint -->
<div class="container-fluid"><!-- 100% de largeur -->
<div class="container-lg"> <!-- container à partir de lg -->
<!-- Breakpoints Bootstrap -->
<!-- xs: <576px | sm: ≥576px | md: ≥768px | lg: ≥992px | xl: ≥1200px | xxl: ≥1400px -->
<!-- Grille responsive -->
<div class="container">
<div class="row">
<!-- 12 colonnes sur mobile, 6 sur sm, 4 sur md -->
<div class="col-12 col-sm-6 col-md-4">Colonne 1</div>
<div class="col-12 col-sm-6 col-md-4">Colonne 2</div>
<div class="col-12 col-sm-12 col-md-4">Colonne 3</div>
</div>
</div>
<!-- Colonnes auto-équilibrées -->
<div class="row">
<div class="col">1/3</div>
<div class="col">1/3</div>
<div class="col">1/3</div>
</div>
<!-- Gutter (espacement) -->
<div class="row g-3"> <!-- gap 3 -->
<div class="row gx-4 gy-2"><!-- gap horizontal 4, vertical 2 -->
<!-- Offset -->
<div class="col-4 offset-4">Centré</div>
<!-- Order -->
<div class="col order-last">Affiché en dernier</div>
<div class="col order-first">Affiché en premier</div>
4. Classes utilitaires
<!-- ── Espacement (margin/padding) ── -->
<!-- {m|p}{t|b|s|e|x|y}-(0..5|auto) -->
<div class="mt-3 mb-2 px-4 py-2">...</div>
<!-- mt=margin-top, mb=margin-bottom, px=padding-left+right -->
<!-- 0=0, 1=0.25rem, 2=0.5rem, 3=1rem, 4=1.5rem, 5=3rem -->
<!-- ── Display ── -->
<div class="d-none">Caché</div>
<div class="d-block">Block</div>
<div class="d-flex">Flex</div>
<div class="d-md-flex d-none">Flex à partir de md</div>
<!-- ── Flexbox utilitaires ── -->
<div class="d-flex justify-content-between align-items-center gap-3">
<span>Gauche</span>
<span>Droite</span>
</div>
<div class="d-flex flex-column flex-md-row">...</div>
<!-- ── Texte ── -->
<p class="text-center text-md-start">Centré mobile, gauche desktop</p>
<p class="text-primary fw-bold fs-4">Texte bleu gras taille 4</p>
<p class="text-muted font-monospace">Texte discret monospace</p>
<p class="text-truncate">Texte très long qui sera tronqué avec ...</p>
<!-- ── Couleurs ── -->
<!-- text-{primary|secondary|success|danger|warning|info|light|dark|white|muted} -->
<!-- bg-{primary|secondary|success|danger|...} -->
<div class="bg-primary text-white p-3">...</div>
<div class="bg-success bg-opacity-25">Fond vert à 25%</div>
<!-- ── Taille & position ── -->
<div class="w-100">100% largeur</div>
<div class="w-50 mx-auto">50% centré</div>
<div class="h-100">100% hauteur</div>
<div class="position-relative">
<span class="position-absolute top-0 end-0 badge bg-danger">3</span>
</div>
<!-- ── Bordures & ombres ── -->
<div class="border border-primary border-2 rounded-3 shadow-lg">...</div>
<div class="rounded-pill">Arrondi pill</div>
<div class="rounded-circle">Cercle</div>
5. Composants Bootstrap
<!-- ── Boutons ── -->
<button class="btn btn-primary">Primary</button>
<button class="btn btn-outline-secondary btn-sm">Outline SM</button>
<button class="btn btn-danger btn-lg disabled">Danger LG</button>
<!-- ── Badges ── -->
<span class="badge bg-success">Nouveau</span>
<span class="badge rounded-pill bg-primary">5</span>
<!-- ── Alertes ── -->
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>Attention !</strong> Votre session expire bientôt.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Fermer"></button>
</div>
<!-- ── Cards ── -->
<div class="card shadow-sm" style="width: 18rem">
<img src="img.jpg" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Titre de la carte</h5>
<p class="card-text text-muted">Description courte.</p>
<a href="#" class="btn btn-primary">Voir plus</a>
</div>
</div>
<!-- ── Accordion ── -->
<div class="accordion" id="myAccordion">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button"
data-bs-toggle="collapse" data-bs-target="#item1">
Question 1
</button>
</h2>
<div id="item1" class="accordion-collapse collapse show"
data-bs-parent="#myAccordion">
<div class="accordion-body">Réponse 1</div>
</div>
</div>
</div>
<!-- ── Tabs ── -->
<ul class="nav nav-tabs" id="myTabs" role="tablist">
<li class="nav-item">
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#tab1">Onglet 1</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#tab2">Onglet 2</button>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="tab1">Contenu 1</div>
<div class="tab-pane fade" id="tab2">Contenu 2</div>
</div>
<!-- ── Toast ── -->
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="myToast" class="toast" role="alert">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast"></button>
</div>
<div class="toast-body">Votre action a réussi !</div>
</div>
</div>
6. Formulaires Bootstrap
<form novalidate>
<!-- Input standard -->
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" required>
<div class="valid-feedback">Correct !</div>
<div class="invalid-feedback">Email invalide.</div>
</div>
<!-- Select -->
<div class="mb-3">
<label for="pays" class="form-label">Pays</label>
<select class="form-select" id="pays">
<option value="">Choisir...</option>
<option value="fr">France</option>
</select>
</div>
<!-- Textarea -->
<div class="mb-3">
<label for="msg" class="form-label">Message</label>
<textarea class="form-control" id="msg" rows="3"></textarea>
</div>
<!-- Checkbox -->
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="cgu" required>
<label class="form-check-label" for="cgu">J'accepte les CGU</label>
</div>
<!-- Switch -->
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="notifs">
<label class="form-check-label" for="notifs">Notifications email</label>
</div>
<!-- Input group -->
<div class="input-group mb-3">
<span class="input-group-text">@</span>
<input type="text" class="form-control" placeholder="Username">
<button class="btn btn-primary" type="button">Rechercher</button>
</div>
<!-- Floating labels -->
<div class="form-floating mb-3">
<input type="text" class="form-control" id="nom" placeholder="Nom">
<label for="nom">Votre nom</label>
</div>
<button type="submit" class="btn btn-primary">Envoyer</button>
</form>
8. Modal & Offcanvas
<!-- ── Modal ── -->
<!-- Déclencheur -->
<button type="button" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#maModal">
Ouvrir le modal
</button>
<!-- Modal -->
<div class="modal fade" id="maModal" tabindex="-1"
aria-labelledby="maModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="maModalLabel">Titre du modal</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Contenu du modal...</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
<button class="btn btn-primary">Confirmer</button>
</div>
</div>
</div>
</div>
<!-- ── Offcanvas (menu latéral) ── -->
<button class="btn btn-primary" data-bs-toggle="offcanvas"
data-bs-target="#sidebar" aria-controls="sidebar">
Ouvrir sidebar
</button>
<div class="offcanvas offcanvas-start" id="sidebar"
tabindex="-1" aria-labelledby="sidebarLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="sidebarLabel">Menu</h5>
<button class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<ul class="list-unstyled">
<li><a href="#">Lien 1</a></li>
<li><a href="#">Lien 2</a></li>
</ul>
</div>
</div>
9. Personnalisation avec Sass
// ── Override des variables Bootstrap avant import ──
// src/custom.scss
// Couleurs principales
$primary: #6366f1; // Indigo au lieu du bleu
$secondary: #64748b;
$success: #22c55e;
$danger: #ef4444;
// Typographie
$font-family-base: 'Inter', system-ui, sans-serif;
$font-size-base: 1rem;
$line-height-base: 1.6;
// Bordures
$border-radius: 10px;
$border-radius-lg: 14px;
$border-radius-sm: 6px;
// Grid
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1400px
);
// Importer Bootstrap APRÈS les variables
@import "bootstrap/scss/bootstrap";
// Vos styles personnalisés
.btn-primary {
font-weight: 600;
letter-spacing: 0.3px;
}
Avec npm Installez Bootstrap via npm pour accéder aux fichiers Sass :
npm install bootstrap puis importez dans votre SCSS.10. Bonnes pratiques accessibilité Bootstrap
<!-- ── Boutons avec aria ── -->
<button class="btn btn-primary" aria-label="Fermer">
<span aria-hidden="true">×</span>
</button>
<!-- ── Nav avec aria-current ── -->
<a class="nav-link active" aria-current="page" href="/">Accueil</a>
<!-- ── Live region pour les alertes ── -->
<div class="alert alert-success" role="alert" aria-live="polite">
Formulaire envoyé avec succès !
</div>
<!-- ── Icônes accessibles ── -->
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.min.css">
<i class="bi bi-heart" aria-hidden="true"></i> <!-- décorative -->
<i class="bi bi-search" aria-label="Rechercher" role="img"></i> <!-- informative -->
<!-- ── Tableau accessible ── -->
<table class="table table-striped table-hover table-responsive">
<caption class="visually-hidden">Liste des utilisateurs</caption>
<thead class="table-dark">
<tr>
<th scope="col">#</th>
<th scope="col">Nom</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">1</th><td>Alice</td><td>alice@example.com</td></tr>
</tbody>
</table>
<!-- ── visually-hidden (accessible mais invisible) ── -->
<span class="visually-hidden">(requis)</span>