🧩 Bootstrap Components and Utilities
Once the grid gives you a layout, Bootstrap's component library fills it with ready-made, accessible interface pieces — and its utility classes let you adjust their spacing, color, and alignment without ever opening a CSS file. This lesson shows you how the two work together.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Use core components — navbar, breadcrumb, card, accordion, modal, and forms — with correct markup
- Apply utility classes for spacing, flexbox, text, and color and read their naming convention
- Combine components with utilities to build a polished section without custom CSS
- Explain which components need Bootstrap's JavaScript bundle and how
data-bs-*attributes drive them - Apply the accessibility practices (ARIA, focus, screen-reader text) that keep components usable for everyone
Estimated Time: 40–50 minutes • Difficulty: Intermediate
Hands-on: Build a three-card "features" section by combining the card component with utility classes.
In This Lesson
Components as Building Blocks
A component is a pre-styled, pre-behaving chunk of interface — a navbar, a card, a modal — that you drop in by writing the right HTML and class names. Bootstrap ships dozens of them, all sharing the same visual language so a page assembled from them looks coherent by default.
💡 Analogy — LEGO bricks: Components are standardized, interoperable bricks. Each one snaps cleanly into the grid and next to its neighbors, so you spend your time arranging pieces rather than moulding them from raw plastic.
Bootstrap's components fall into a few natural families:
📖 Two kinds of component
CSS-only: cards, breadcrumbs, and badges need only the stylesheet.
JavaScript-powered: modals, tooltips, dropdowns, and the collapsing navbar need Bootstrap's JS bundle loaded and are triggered by data-bs-* attributes.
Content: Cards & Accordion
Cards
A card is a flexible bordered container for a mixed bag of content — image, title, text, buttons. It's the workhorse of product listings, blog previews, and dashboards.
<div class="card" style="width: 18rem;">
<img src="product.jpg" class="card-img-top" alt="Product photo">
<div class="card-body">
<h5 class="card-title">Product name</h5>
<p class="card-text">A short description of the product.</p>
<a href="#" class="btn btn-primary">Add to cart</a>
</div>
</div>
Accordion
An accordion is a stack of collapsible panels — ideal for FAQs, where showing one answer at a time keeps the page tidy. It relies on Bootstrap's JS and data-bs-* attributes.
<div class="accordion" id="faq">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button" type="button"
data-bs-toggle="collapse" data-bs-target="#q1"
aria-expanded="true" aria-controls="q1">
How do I return an item?
</button>
</h2>
<div id="q1" class="accordion-collapse collapse show"
data-bs-parent="#faq">
<div class="accordion-body">
Visit our returns page and follow the instructions.
</div>
</div>
</div>
<!-- more .accordion-item blocks -->
</div>
The data-bs-parent="#faq" attribute is what makes opening one panel close the others. Remove it and panels open independently.
Interactive: Modals & Tooltips
Modal dialogs
A modal is a focused overlay that dims the page behind it — perfect for confirmations. A trigger button points at the modal by id; the modal markup lives elsewhere on the page.
<!-- Trigger -->
<button type="button" class="btn btn-primary"
data-bs-toggle="modal" data-bs-target="#confirmModal">
Delete item
</button>
<!-- Modal -->
<div class="modal fade" id="confirmModal" tabindex="-1"
aria-labelledby="confirmLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmLabel">Confirm delete</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">This cannot be undone. Continue?</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger">Delete</button>
</div>
</div>
</div>
</div>
Tooltips
Tooltips reveal a hint on hover or focus. For performance reasons Bootstrap does not auto-enable them — you opt in with a line of JavaScript.
<button type="button" class="btn btn-secondary"
data-bs-toggle="tooltip" data-bs-placement="top"
title="This action cannot be undone">
Delete account
</button>
// Initialize every tooltip on the page (Bootstrap 5)
const triggers = document.querySelectorAll('[data-bs-toggle="tooltip"]');
[...triggers].forEach((el) => new bootstrap.Tooltip(el));
⚠️ JS components need the bundle
Modals, tooltips, dropdowns, and the collapsing navbar only work if you load Bootstrap's JavaScript, usually just before </body>:
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
Form Components
Bootstrap styles every standard form control consistently across browsers. The form-label / form-control / form-text trio covers most inputs, and every input should have an associated <label>.
<form>
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" id="email"
aria-describedby="emailHelp">
<div id="emailHelp" class="form-text">We'll never share your email.</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="remember">
<label class="form-check-label" for="remember">Remember me</label>
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
Input groups
Input groups attach text or buttons to the edges of a control — currency symbols, units, or a search button.
<div class="input-group mb-3">
<span class="input-group-text">$</span>
<input type="text" class="form-control" aria-label="Amount">
<span class="input-group-text">.00</span>
</div>
Utility Classes
Utilities are tiny, single-purpose classes that apply one CSS declaration each. They're the adjustable wrench in your toolbox: instead of writing a stylesheet rule, you add mt-3 for margin-top or text-center to center text right in the markup.
Spacing: read the pattern
Spacing utilities follow the pattern {property}{side}-{size}:
- property:
m(margin) orp(padding) - side:
t/b(top/bottom),s/e(start/end),x/y(horizontal/vertical), or blank for all sides - size:
0through5, orauto
So mb-4 is a large bottom margin, px-2 is small left/right padding, and mt-auto pushes an element to the bottom of a flex column.
| Category | Examples | Effect |
|---|---|---|
| Flexbox | d-flex justify-content-between align-items-center | Row with items pushed apart and vertically centered |
| Text | text-center, fw-bold, text-uppercase | Alignment, weight, casing |
| Color | text-primary, bg-success | Theme text and background colors |
| Sizing | w-100, h-100 | Full width / height of the parent |
<div class="d-flex justify-content-between align-items-center">
<span>Left</span>
<span>Right</span>
</div>
<p class="text-center fw-bold text-primary">Centered bold primary text</p>
<div class="bg-success text-white p-2">Success banner</div>
Combining Both
The real power appears when you layer utilities onto a component. A plain card becomes a pricing card with a header color, a shadow, equal height, and a bottom-pinned button — all through utilities, no custom CSS.
<div class="card shadow-sm h-100">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">Premium plan</h5>
</div>
<div class="card-body d-flex flex-column">
<h2 class="text-center my-3">$29<span class="text-body-secondary fs-6">/month</span></h2>
<ul class="list-group list-group-flush mb-4">
<li class="list-group-item">Unlimited access</li>
<li class="list-group-item">Premium support</li>
<li class="list-group-item">Advanced features</li>
</ul>
<a href="#" class="btn btn-primary mt-auto">Subscribe</a>
</div>
</div>
The utilities doing the work here: shadow-sm (depth), h-100 (equal height in a row), d-flex flex-column (vertical layout), text-center, and mt-auto (pins the button to the bottom regardless of content length).
Hands-on: Feature Section
🏋️ Build a three-card features row
Objective: Combine the grid, the card component, and utilities into a professional "features" section — three cards on desktop, stacking to one column on mobile, with equal heights and centered content.
Instructions:
- Start with a
.container py-5and a centered heading. - Make a
rowthat shows 1 card per row on phones and 3 frommdup (userow-cols-*and a gutter). - In each
.col, place a borderless card with a soft shadow (border-0 shadow-sm h-100). - Center the card body content and add a title and a muted description.
- Confirm the three cards line up at equal height even when the text lengths differ.
💡 Hint
Put the responsive count on the row: row-cols-1 row-cols-md-3 g-4. Equal height comes from h-100 on each card. Center the body with text-center and gray the description with text-body-secondary.
✅ Solution
<div class="container py-5">
<h2 class="text-center mb-4">Product features</h2>
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center p-4">
<h4 class="card-title">Lightning fast</h4>
<p class="card-text text-body-secondary">
Optimized code paths keep everything responsive.
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center p-4">
<h4 class="card-title">Secure & private</h4>
<p class="card-text text-body-secondary">
Data is protected with strong encryption at rest and in transit.
</p>
</div>
</div>
</div>
<div class="col">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center p-4">
<h4 class="card-title">24/7 support</h4>
<p class="card-text text-body-secondary">
A dedicated team is available around the clock.
</p>
</div>
</div>
</div>
</div>
</div>
You just built a production-quality section with zero lines of custom CSS — grid for layout, card for structure, utilities for polish.
🎯 Quick Quiz
Question 1: Which component requires Bootstrap's JavaScript bundle to work?
Question 2: What does the utility class mt-auto do inside a d-flex flex-column card body?
Question 3: In the spacing convention {property}{side}-{size}, what does px-2 mean?
Accessibility & Best Practices
Bootstrap components are built with accessibility in mind, but that only holds if you fill in the attributes. Three habits cover most cases.
1. Keep the ARIA attributes
Interactive triggers rely on attributes like aria-expanded, aria-controls, and aria-label. When you copy a component, copy those too — they tell screen readers what a control does and whether it's open.
2. Icon-only buttons need a text label
<!-- Icon alone gives a screen reader nothing to announce -->
<button class="btn btn-danger">
<i class="bi bi-trash" aria-hidden="true"></i>
<span class="visually-hidden">Delete item</span>
</button>
The visually-hidden utility keeps the label off-screen but available to assistive tech, while aria-hidden="true" stops the decorative icon from being announced twice.
3. Prefer real interactive elements
Use <button> for actions and <a href> for navigation so keyboard focus and Enter/Space activation work for free. Styling a <div> to look like a button loses all of that.
✅ Do / Don't
- Do associate every form input with a
<label for>. - Do test the whole page with the keyboard alone — Tab, Enter, Esc.
- Don't strip focus outlines to "clean up" the design.
- Don't rely on color alone to convey state; pair it with text or an icon.
Summary & Quiz
🎉 Key Takeaways
- Components are ready-made interface blocks; utilities are one-line style tweaks.
- CSS-only components (cards, breadcrumbs) need just the stylesheet; JS components (modals, tooltips, dropdowns) need the bundle and
data-bs-*attributes. - Utility names follow readable patterns like
{property}{side}-{size}— learn the pattern, not a list. - The best results come from combining a component with a few utilities rather than writing custom CSS.
- Accessibility depends on you keeping the ARIA attributes, labeling icon buttons, and using real interactive elements.
📚 Further Reading
🚀 What's Next?
You've used Bootstrap's defaults; next you'll make them your own. Customizing Bootstrap walks from quick CSS-variable overrides all the way to a full Sass theme so your site stops looking like "a Bootstrap site."
🎉 Great progress!
Components plus utilities is the Bootstrap workflow. With the grid from the last lesson, you can now assemble almost any page layout by hand.