Bootstrap 5 Tutorial
Bootstrap 5 is the most popular CSS framework for building responsive, mobile-first websites. It ships with a powerful grid system, dozens of components, and hundreds of utility classes.
CDN Setup
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Bootstrap 5</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" />
</head>
<body>
<!-- Your content -->
<!-- Bootstrap JS Bundle (includes Popper) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Grid System
Bootstrap's 12-column grid uses .container, .row, and .col-* classes.
HTML
<!-- Basic grid -->
<div class="container">
<div class="row">
<div class="col-4">Column 1 (4/12)</div>
<div class="col-4">Column 2 (4/12)</div>
<div class="col-4">Column 3 (4/12)</div>
</div>
<!-- Responsive: full on mobile, 2 cols on tablet, 3 on desktop -->
<div class="row">
<div class="col-12 col-sm-6 col-md-4">Responsive col</div>
<div class="col-12 col-sm-6 col-md-4">Responsive col</div>
<div class="col-12 col-sm-12 col-md-4">Responsive col</div>
</div>
<!-- Auto columns -->
<div class="row">
<div class="col">Equal</div>
<div class="col">Equal</div>
<div class="col">Equal</div>
</div>
<!-- Gutters -->
<div class="row g-3"> <!-- g-0 to g-5 -->
<div class="col-6">...</div>
<div class="col-6">...</div>
</div>
<!-- Offset -->
<div class="row">
<div class="col-4 offset-4">Centered</div>
</div>
</div>
| Class | Breakpoint | Min Width |
|---|---|---|
col-* | xs (extra small) | < 576px |
col-sm-* | sm (small) | = 576px |
col-md-* | md (medium) | = 768px |
col-lg-* | lg (large) | = 992px |
col-xl-* | xl (extra large) | = 1200px |
col-xxl-* | xxl | = 1400px |
Buttons
HTML
<!-- Solid buttons -->
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-danger">Danger</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-info">Info</button>
<button class="btn btn-light">Light</button>
<button class="btn btn-dark">Dark</button>
<!-- Outline buttons -->
<button class="btn btn-outline-primary">Outline</button>
<button class="btn btn-outline-danger">Outline</button>
<!-- Sizes -->
<button class="btn btn-primary btn-sm">Small</button>
<button class="btn btn-primary btn-lg">Large</button>
<!-- Full width -->
<button class="btn btn-primary w-100">Full Width</button>
<!-- Disabled -->
<button class="btn btn-primary" disabled>Disabled</button>
<!-- Button group -->
<div class="btn-group">
<button class="btn btn-outline-primary">Left</button>
<button class="btn btn-outline-primary">Middle</button>
<button class="btn btn-outline-primary">Right</button>
</div>
Cards
HTML
<div class="card" style="width: 18rem;">
<img src="image.jpg" class="card-img-top" alt="Card image">
<div class="card-body">
<h5 class="card-title">Card Title</h5>
<p class="card-text">Some quick example text.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
<!-- Card grid (responsive) -->
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">Card 1</h5>
<p class="card-text">Content here.</p>
</div>
<div class="card-footer text-muted">2 days ago</div>
</div>
</div>
</div>
Modal
HTML
<!-- Trigger button -->
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#myModal">
Open Modal
</button>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1">
<div class="modal-dialog"> <!-- modal-dialog-centered modal-lg -->
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal Title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Modal body content goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>
<!-- JS control -->
<script>
const modal = new bootstrap.Modal(document.getElementById("myModal"));
modal.show(); // programmatically show
modal.hide(); // programmatically hide
</script>
Forms
HTML
<form>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email" placeholder="name@example.com">
<div class="form-text">We'll never share your email.</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password">
</div>
<!-- Validation states -->
<input type="text" class="form-control is-valid" value="Correct input">
<div class="valid-feedback">Looks good!</div>
<input type="text" class="form-control is-invalid">
<div class="invalid-feedback">Please provide a valid name.</div>
<!-- Select -->
<select class="form-select">
<option selected>Choose...</option>
<option value="1">One</option>
</select>
<!-- Checkbox & Radio -->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="check1">
<label class="form-check-label" for="check1">Default checkbox</label>
</div>
<!-- Switch -->
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="switch1">
<label class="form-check-label" for="switch1">Toggle this switch</label>
</div>
<!-- Inline form with Input Group -->
<div class="input-group">
<span class="input-group-text">@</span>
<input type="text" class="form-control" placeholder="Username">
<button class="btn btn-primary">Search</button>
</div>
<button type="submit" class="btn btn-primary mt-3">Submit</button>
</form>
Spacing Utilities
Bootstrap uses a shorthand pattern: {property}{sides}-{breakpoint}-{size}
| Class | Meaning |
|---|---|
m-3 | margin all sides, size 3 (1rem) |
p-2 | padding all sides, size 2 (0.5rem) |
mt-4 | margin-top, size 4 (1.5rem) |
mb-0 | margin-bottom 0 |
mx-auto | margin-left and margin-right: auto (center) |
py-5 | padding-top and padding-bottom, size 5 (3rem) |
ms-2 | margin-start (left in LTR) |
me-3 | margin-end (right in LTR) |
gap-3 | gap (flexbox/grid) size 3 |
Offcanvas
Offcanvas panels are useful for mobile navigation, cart previews, filters, and side tools. They behave like a lightweight slide-in modal.
Bootstrap 5
<button class="btn btn-primary" data-bs-toggle="offcanvas" data-bs-target="#menuPanel">
Open menu
</button>
<div class="offcanvas offcanvas-start" id="menuPanel">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Menu</h5>
<button class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">...</div>
</div>
Customization
Bootstrap becomes much more useful when students learn how to customize it instead of using only the defaults.
- Override Sass variables before importing Bootstrap.
- Use CSS custom properties for brand colors and spacing tweaks.
- Create your own component classes on top of Bootstrap layout utilities.
Utility API
Bootstrap's utility API lets you generate your own utility classes from Sass maps, which is useful for custom spacing, opacity, or z-index helpers.