Skip to main content

🅱️ Bootstrap Fundamentals

Bootstrap is the world's most-used component framework — a complete toolkit of responsive grid, pre-styled components, and utility classes that lets a small team ship a polished interface fast. This lesson takes you from "how do I even add it" to building a real responsive layout with navbars, cards, forms, and modals, using the modern, jQuery-free Bootstrap 5.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Include Bootstrap in a project via CDN or a package manager and know when to use each
  • Build responsive layouts with the 12-column grid, containers, rows, and breakpoints
  • Assemble interfaces from core components — navbar, cards, buttons, forms, and modals
  • Apply utility classes for spacing, color, display, and flexbox without writing custom CSS
  • Wire up interactive components using data attributes or the vanilla-JS API

Estimated Time: 40–50 minutes  •  Difficulty: Intermediate

Hands-on: Build a responsive "team page" layout from a starter template using the grid and cards.

In This Lesson

What Bootstrap Is (and Bootstrap 5)

Bootstrap is a front-end component framework for building responsive, mobile-first websites. Created at Twitter in 2011, it bundles a responsive grid, dozens of pre-styled components, a large utility system, and a handful of interactive JavaScript widgets — all designed to work together and speed up development.

📖 Analogy: Bootstrap as a Furniture Kit

Bootstrap is like flat-pack furniture. The pieces come pre-designed with standard dimensions, assembly follows consistent patterns, and everything is built to fit together. You can customize it — paint it, swap the hardware — but within the kit's constraints. And like a well-known furniture line, many sites are recognizably "Bootstrap" at a glance.

What changed in Bootstrap 5

Bootstrap 5 (the current major line, 5.3 at time of writing) modernized the framework:

  • Dropped jQuery — components now run on vanilla JavaScript
  • CSS custom properties throughout, making runtime theming far easier
  • An added xxl breakpoint and a refined grid
  • Refreshed forms and validation, plus built-in RTL (right-to-left) support
  • An expanded utility API and a built-in color-mode / dark-mode system in 5.3
flowchart TD A[Bootstrap 5] --> B[Layout] A --> C[Content] A --> D[Forms] A --> E[Components] A --> F[Utilities] B --> B1[Grid system] B --> B2[Containers] B --> B3[Breakpoints] C --> C1[Typography] C --> C2[Tables & images] D --> D1[Controls] D --> D2[Validation] E --> E1[Navbar] E --> E2[Cards] E --> E3[Modal] F --> F1[Spacing] F --> F2[Colors] F --> F3[Flex & display]

Adding Bootstrap to a Project

There are two approaches you'll use most: a quick CDN drop-in for prototypes and simple sites, and a package-manager install for anything with a build step.

Option 1 — CDN (fastest start)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Bootstrap Example</title>

  <!-- Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <!-- Your content here -->

  <!-- Bootstrap bundle (includes Popper) for interactive components -->
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Option 2 — Package manager (for build-based projects)

# Install with your package manager of choice
npm install bootstrap@5.3.3
# or: yarn add bootstrap
# or: pnpm add bootstrap
// In your entry file (e.g. main.js)
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';

💡 Which should you pick?

Use the CDN for demos, tutorials, and small static pages — zero setup, cached across the web. Use a package install when you have a bundler (Vite, webpack) so you can import Bootstrap's Sass and override its variables to customize the theme rather than fight it with overrides.

A minimal starter page

<body>
  <nav class="navbar navbar-expand-lg bg-body-tertiary">
    <div class="container">
      <a class="navbar-brand" href="#">Brand</a>
    </div>
  </nav>

  <main class="container my-5">
    <div class="row">
      <div class="col-md-8">
        <h1>Hello, Bootstrap!</h1>
        <p class="lead">A minimal Bootstrap page.</p>
        <button class="btn btn-primary">Learn More</button>
      </div>
      <div class="col-md-4">
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Sidebar</h5>
            <p class="card-text">A card used as a sidebar widget.</p>
          </div>
        </div>
      </div>
    </div>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>

The 12-Column Grid System

The grid is Bootstrap's backbone. It's a 12-column layout built on Flexbox, controlled by three nested pieces: a container that centers and pads your content, a row that groups columns, and columns that span some number of the 12 tracks.

flowchart TD A[".container / .container-fluid"] --> B[".row"] B --> C[".col-* — spans 1–12"] B --> D[".col — auto equal width"] B --> E[".col-{breakpoint}-* — responsive"]

The six breakpoints

BreakpointClass prefixApplies at
Extra smallcol- (no prefix)< 576px
Smallcol-sm-≥ 576px
Mediumcol-md-≥ 768px
Largecol-lg-≥ 992px
Extra largecol-xl-≥ 1200px
Extra extra largecol-xxl-≥ 1400px

📖 Mobile-first, cascading up

A class like col-md-6 means "half width from medium up." Below that breakpoint it falls back to full width. That's why you stack breakpoints — col-12 col-md-6 col-lg-4 reads as: full width on phones, half on tablets, one-third on desktops.

A responsive three-column layout

<div class="container">
  <div class="row">
    <div class="col-12 col-md-6 col-lg-4">Column 1</div>
    <div class="col-12 col-md-6 col-lg-4">Column 2</div>
    <div class="col-12 col-md-12 col-lg-4">Column 3</div>
  </div>
</div>
How the same columns reflow across breakpoints On mobile the three columns stack full width; on tablet two sit side by side with the third below; on desktop all three share the row equally. Mobile col-12 col-12 col-12 Tablet (md) col-md-6 col-md-6 col-md-12 Desktop (lg) col-lg-4 col-lg-4 col-lg-4
Figure 1 — The same three columns reflow automatically: stacked on phones, two-plus-one on tablets, three across on desktops.

Handy grid features

<!-- Auto-layout: equal-width columns, no numbers needed -->
<div class="row">
  <div class="col">Equal</div>
  <div class="col">Equal</div>
  <div class="col">Equal</div>
</div>

<!-- Offset: push a column to the right -->
<div class="row">
  <div class="col-md-4">Column 1</div>
  <div class="col-md-4 offset-md-4">Column 2 (offset by 4)</div>
</div>

<!-- Reorder visually without changing the HTML order -->
<div class="row">
  <div class="col order-2">Shown second</div>
  <div class="col order-1">Shown first</div>
</div>

Essential Components

Components are the reason most people reach for Bootstrap. Here are the ones you'll use on nearly every project.

Navbar — responsive navigation

<nav class="navbar navbar-expand-lg bg-body-tertiary">
  <div class="container-fluid">
    <a class="navbar-brand" href="#">Brand</a>

    <!-- Collapses into a hamburger below the lg breakpoint -->
    <button class="navbar-toggler" type="button"
            data-bs-toggle="collapse" data-bs-target="#navMain"
            aria-controls="navMain" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navMain">
      <ul class="navbar-nav me-auto">
        <li class="nav-item"><a class="nav-link active" aria-current="page" href="#">Home</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Features</a></li>
      </ul>
      <form class="d-flex" role="search">
        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success" type="submit">Search</button>
      </form>
    </div>
  </div>
</nav>

Cards — flexible content containers

<div class="card" style="width: 18rem;">
  <img src="card-image.jpg" class="card-img-top" alt="Descriptive text">
  <div class="card-body">
    <h5 class="card-title">Card title</h5>
    <p class="card-text">Some quick example text to build on the card title.</p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
  </div>
</div>

Buttons — styles and sizes

<!-- Semantic color variants -->
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-outline-primary">Outline</button>

<!-- Sizes -->
<button type="button" class="btn btn-primary btn-lg">Large</button>
<button type="button" class="btn btn-primary btn-sm">Small</button>

Forms with validation

<form class="row g-3 needs-validation" novalidate>
  <div class="col-md-6">
    <label for="firstName" class="form-label">First name</label>
    <input type="text" class="form-control" id="firstName" required>
    <div class="valid-feedback">Looks good!</div>
    <div class="invalid-feedback">Please enter your first name.</div>
  </div>
  <div class="col-12">
    <button class="btn btn-primary" type="submit">Submit</button>
  </div>
</form>
// Bootstrap-style client-side validation (vanilla JS, no jQuery)
document.querySelectorAll('.needs-validation').forEach((form) => {
  form.addEventListener('submit', (event) => {
    if (!form.checkValidity()) {
      event.preventDefault();
      event.stopPropagation();
    }
    form.classList.add('was-validated');
  });
});

Modal — a dialog with zero JavaScript

<!-- Trigger -->
<button type="button" class="btn btn-primary"
        data-bs-toggle="modal" data-bs-target="#demoModal">
  Launch modal
</button>

<!-- Modal -->
<div class="modal fade" id="demoModal" tabindex="-1" aria-labelledby="demoModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="demoModalLabel">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">Modal body text goes here.</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>

Utility Classes

Beyond components, Bootstrap ships a rich set of utility classes for small adjustments — spacing, color, display, flexbox, position — so you rarely need custom CSS for one-off tweaks.

Spacing — the pattern to memorize

Spacing utilities follow {property}{sides}-{size}:

  • property: m (margin) or p (padding)
  • sides: t top, b bottom, s start, e end, x horizontal, y vertical, or blank for all sides
  • size: 05 (0 to 3rem), or auto
<div class="mt-3">Margin-top 1rem</div>
<div class="p-5">Padding 3rem all around</div>
<div class="mx-auto">Horizontally centered</div>
<div class="py-2 mb-4">Vertical padding 0.5rem, margin-bottom 1.5rem</div>

Text, color, and display

<!-- Text -->
<p class="text-center fw-bold">Centered, bold</p>
<p class="text-uppercase fst-italic">Uppercase italic</p>

<!-- Color (background + text) -->
<div class="bg-primary text-white p-2">Primary background</div>
<p class="text-danger">Danger-colored text</p>
<p class="text-muted">Muted text</p>

<!-- Responsive display: hide on phones, show from md up -->
<div class="d-none d-md-block">Visible on medium screens and larger</div>

Flexbox utilities

<div class="d-flex justify-content-between align-items-center">
  <span>Left</span>
  <span>Right</span>
</div>

✅ Utilities keep your CSS file tiny

Reaching for d-flex justify-content-between instead of writing a bespoke rule keeps behavior consistent and your stylesheet small. Save custom CSS for the genuinely unique parts of your design.

JavaScript Components

Bootstrap's interactive widgets — modals, dropdowns, tooltips, popovers, collapse, carousel, toasts, tabs, scrollspy — run on vanilla JavaScript in Bootstrap 5. You can drive them two ways.

Data attributes (no JavaScript to write)

<!-- Toggle a collapse purely with attributes -->
<button class="btn btn-primary" type="button"
        data-bs-toggle="collapse" data-bs-target="#panel">
  Toggle panel
</button>
<div class="collapse" id="panel">
  <div class="card card-body">Now you see me.</div>
</div>

The JavaScript API (for programmatic control)

// Create and control a modal in code
const modal = new bootstrap.Modal(document.getElementById('demoModal'));
modal.show();
// modal.hide();

// Initialize every tooltip on the page (they're opt-in)
const triggers = document.querySelectorAll('[data-bs-toggle="tooltip"]');
[...triggers].forEach((el) => new bootstrap.Tooltip(el));

⚠️ Two gotchas

Tooltips and popovers are opt-in for performance — you must initialize them with JavaScript; data attributes alone won't fire them. And make sure you load the bundle (bootstrap.bundle.min.js) or include Popper separately, or dropdowns, tooltips, and popovers won't position correctly.

Hands-on Exercise

🏋️ Build a Responsive Team Page

Objective: Combine the grid and cards into a real responsive layout.

Instructions

  1. Start from the CDN starter template above.
  2. Add a navbar with a brand and two links that collapses on mobile.
  3. Below it, add a section of team member cards — each with a title and a short bio.
  4. Make the cards show 1 per row on phones, 2 on tablets, and 3 on desktops using grid classes, with consistent spacing between rows.
💡 Hint

Wrap the cards in a single .row and give each card's column col-12 col-md-6 col-lg-4. Add a bottom margin utility like mb-4 to each column so rows breathe when they wrap. A g-4 gutter class on the row also works.

✅ Sample solution
<main class="container my-5">
  <h1 class="text-center mb-4">Meet the Team</h1>
  <div class="row g-4">
    <div class="col-12 col-md-6 col-lg-4">
      <div class="card h-100">
        <div class="card-body">
          <h5 class="card-title">Ana Reyes</h5>
          <h6 class="card-subtitle mb-2 text-muted">Product Designer</h6>
          <p class="card-text">Leads UX research and the design system.</p>
        </div>
      </div>
    </div>
    <div class="col-12 col-md-6 col-lg-4">
      <div class="card h-100">
        <div class="card-body">
          <h5 class="card-title">Ben Cruz</h5>
          <h6 class="card-subtitle mb-2 text-muted">Backend Engineer</h6>
          <p class="card-text">Builds the API and database layer.</p>
        </div>
      </div>
    </div>
    <div class="col-12 col-md-6 col-lg-4">
      <div class="card h-100">
        <div class="card-body">
          <h5 class="card-title">Carla Lim</h5>
          <h6 class="card-subtitle mb-2 text-muted">Frontend Engineer</h6>
          <p class="card-text">Owns the component library and accessibility.</p>
        </div>
      </div>
    </div>
  </div>
</main>

The h-100 on each card makes every card in a row the same height even when bios differ in length — a small but professional touch.

🎯 Quick Quiz

Question 1: How many columns is the Bootstrap grid divided into?

Question 2: What does col-12 col-md-6 mean?

Question 3: What major change did Bootstrap 5 make to its JavaScript?

Summary & Quiz

🎉 Key Takeaways

  • Bootstrap is a component framework: grid + pre-styled components + utilities, mobile-first.
  • Include it via CDN for quick work or a package install when you want to theme it through Sass.
  • The 12-column grid (container → row → columns) with six breakpoints drives responsive layout; classes cascade upward from the smallest screen.
  • Core components — navbar, cards, buttons, forms, modals — cover most UI needs out of the box.
  • Utility classes handle spacing, color, display, and flex without custom CSS.
  • Bootstrap 5 dropped jQuery; interactive widgets run on vanilla JS via data attributes or the JavaScript API.

📚 Further Reading

🚀 What's Next?

You've met the component approach. Next we flip to the opposite philosophy: Tailwind CSS and the utility-first approach, where you build designs from atomic classes right in your markup.

🎉 Great progress!

You can now scaffold a responsive, component-rich page with Bootstrap. Time to see the utility-first counterpoint.