Skip to main content
Bootstrap
CHAPTER 18 Beginner

Building Admin Dashboards with Bootstrap

Updated: May 18, 2026
5 min read

# CHAPTER 18

Building Admin Dashboards with Bootstrap

1. Chapter Introduction

Admin dashboards are the most complex Bootstrap UI challenge — they combine fixed sidebars, scrollable main content, stat cards, data tables, charts, and modals into one coherent layout. This chapter builds a complete, production-quality admin dashboard applying every Bootstrap concept learned so far.

2. Learning Objectives

  • Build a fixed sidebar + scrollable content layout.
  • Create KPI stat cards.
  • Build a data table with badges and action buttons.
  • Integrate Chart.js with Bootstrap.
  • Make the dashboard responsive (collapsible sidebar on mobile).

3. Dashboard Layout Architecture

text
1234567891011121314151617
Admin Dashboard Structure:

+------------------+------------------------------------+
| SIDEBAR (fixed)  |  TOPBAR (sticky)                  |
|                  +------------------------------------|
| Logo             |  MAIN CONTENT                     |
| Nav links        |  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐|
| ── Analytics     |  │Stat1│ │Stat2│ │Stat3│ │Stat4││
| ── Users         |  └─────┘ └─────┘ └─────┘ └─────┘|
| ── Orders        |                                   |
| ── Settings      |  ┌─────────────┐ ┌───────────┐   |
|                  |  │   Chart     │ │ Top Items │   |
| User profile     |  └─────────────┘ └───────────┘   |
+------------------+  ┌─────────────────────────────┐  |
                   |  │       Data Table            │  |
                   |  └─────────────────────────────┘  |
                   +------------------------------------+

4. Complete Admin Dashboard

html
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>AdminPro Dashboard</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" />
  <style>
    :root { --sidebar-width: 250px; }
    body { background: #f8f9fa; }
    .sidebar {
      width: var(--sidebar-width);
      min-height: 100vh;
      background: #1e293b;
      position: fixed;
      top: 0; left: 0;
      z-index: 1000;
      transition: transform .3s;
      overflow-y: auto;
    }
    .sidebar .nav-link { color: rgba(255,255,255,.6); padding: .6rem 1.25rem; border-radius: 8px; margin: 2px 8px; transition: .2s; }
    .sidebar .nav-link:hover, .sidebar .nav-link.active { color: #fff; background: rgba(255,255,255,.1); }
    .sidebar .nav-link.active { background: #3b82f6; color: #fff; }
    .main-content { margin-left: var(--sidebar-width); transition: margin .3s; }
    @media (max-width: 991px) {
      .sidebar { transform: translateX(-100%); }
      .sidebar.open { transform: translateX(0); }
      .main-content { margin-left: 0 !important; }
    }
    .stat-card { border-left: 4px solid; }
    .stat-card.revenue { border-color: #3b82f6; }
    .stat-card.users { border-color: #10b981; }
    .stat-card.orders { border-color: #f59e0b; }
    .stat-card.growth { border-color: #8b5cf6; }
    .topbar { height: 64px; background: #fff; border-bottom: 1px solid #e2e8f0; position: sticky; top: 0; z-index: 500; }
  </style>
</head>
<body>

  <!-- ===== SIDEBAR ===== -->
  <aside class="sidebar" id="sidebar">
    <!-- Logo -->
    <div class="p-4 border-bottom border-white border-opacity-10">
      <a href="#" class="text-white text-decoration-none fw-bold fs-5">
        <i class="bi bi-lightning-charge-fill text-primary me-2"></i>AdminPro
      </a>
    </div>

    <!-- Navigation -->
    <nav class="py-3">
      <p class="text-white-50 px-4 small text-uppercase fw-semibold mb-1">Main</p>
      <ul class="nav flex-column">
        <li><a class="nav-link active" href="#"><i class="bi bi-speedometer2 me-2"></i>Dashboard</a></li>
        <li><a class="nav-link" href="#"><i class="bi bi-bar-chart me-2"></i>Analytics</a></li>
        <li><a class="nav-link" href="#"><i class="bi bi-bag me-2"></i>Orders <span class="badge bg-warning text-dark ms-auto float-end">12</span></a></li>
      </ul>
      <p class="text-white-50 px-4 small text-uppercase fw-semibold mb-1 mt-3">Management</p>
      <ul class="nav flex-column">
        <li><a class="nav-link" href="#"><i class="bi bi-people me-2"></i>Users</a></li>
        <li><a class="nav-link" href="#"><i class="bi bi-box-seam me-2"></i>Products</a></li>
        <li><a class="nav-link" href="#"><i class="bi bi-gear me-2"></i>Settings</a></li>
      </ul>
    </nav>

    <!-- User Profile at bottom -->
    <div class="mt-auto p-3 border-top border-white border-opacity-10">
      <div class="d-flex align-items-center gap-2">
        <img src="https://picsum.photos/seed/adm/36/36" class="rounded-circle" width="36" />
        <div>
          <div class="text-white small fw-semibold">John Doe</div>
          <div class="text-white-50" style="font-size:.75rem">Super Admin</div>
        </div>
        <a href="#" class="ms-auto text-white-50"><i class="bi bi-box-arrow-right"></i></a>
      </div>
    </div>
  </aside>

  <!-- ===== MAIN CONTENT ===== -->
  <div class="main-content">

    <!-- Topbar -->
    <header class="topbar d-flex align-items-center px-3 px-lg-4 gap-3">
      <button class="btn btn-light btn-sm d-lg-none" onclick="document.getElementById(&#039;sidebar').classList.toggle('open')">
        <i class="bi bi-list fs-5"></i>
      </button>
      <h6 class="mb-0 fw-semibold">Dashboard</h6>
      <div class="ms-auto d-flex align-items-center gap-3">
        <button class="btn btn-light btn-sm position-relative">
          <i class="bi bi-bell"></i>
          <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" style="font-size:.65rem">4</span>
        </button>
        <img src="https://picsum.photos/seed/adm/32/32" class="rounded-circle" width="32" style="cursor:pointer;" />
      </div>
    </header>

    <!-- Page content -->
    <div class="p-3 p-lg-4">
      <!-- Page header -->
      <div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
        <div>
          <h4 class="mb-0 fw-bold">Overview</h4>
          <p class="text-muted mb-0 small">Welcome back, John. Here&#039;s what's happening.</p>
        </div>
        <div class="d-flex gap-2">
          <select class="form-select form-select-sm" style="width: auto;">
            <option>Last 30 days</option>
            <option>Last 7 days</option>
            <option>This year</option>
          </select>
          <button class="btn btn-primary btn-sm"><i class="bi bi-download me-1"></i>Export</button>
        </div>
      </div>

      <!-- Stat Cards -->
      <div class="row g-3 mb-4">
        <div class="col-12 col-sm-6 col-xl-3">
          <div class="card border-0 shadow-sm stat-card revenue">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-start">
                <div>
                  <p class="text-muted small mb-1">Total Revenue</p>
                  <h3 class="fw-bold mb-0">$48,295</h3>
                  <p class="text-success small mb-0"><i class="bi bi-arrow-up"></i> 12.5% vs last month</p>
                </div>
                <div class="bg-primary bg-opacity-10 text-primary rounded-3 p-3">
                  <i class="bi bi-currency-dollar fs-4"></i>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-xl-3">
          <div class="card border-0 shadow-sm stat-card users">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-start">
                <div>
                  <p class="text-muted small mb-1">Total Users</p>
                  <h3 class="fw-bold mb-0">2,847</h3>
                  <p class="text-success small mb-0"><i class="bi bi-arrow-up"></i> 8.2% vs last month</p>
                </div>
                <div class="bg-success bg-opacity-10 text-success rounded-3 p-3">
                  <i class="bi bi-people fs-4"></i>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-xl-3">
          <div class="card border-0 shadow-sm stat-card orders">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-start">
                <div>
                  <p class="text-muted small mb-1">Total Orders</p>
                  <h3 class="fw-bold mb-0">1,429</h3>
                  <p class="text-danger small mb-0"><i class="bi bi-arrow-down"></i> 3.1% vs last month</p>
                </div>
                <div class="bg-warning bg-opacity-10 text-warning rounded-3 p-3">
                  <i class="bi bi-bag fs-4"></i>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="col-12 col-sm-6 col-xl-3">
          <div class="card border-0 shadow-sm stat-card growth">
            <div class="card-body">
              <div class="d-flex justify-content-between align-items-start">
                <div>
                  <p class="text-muted small mb-1">Growth Rate</p>
                  <h3 class="fw-bold mb-0">24.8%</h3>
                  <p class="text-success small mb-0"><i class="bi bi-arrow-up"></i> 4.1% vs last month</p>
                </div>
                <div class="bg-purple bg-opacity-10 text-purple rounded-3 p-3" style="background: rgba(139,92,246,.1);">
                  <i class="bi bi-graph-up-arrow fs-4" style="color:#8b5cf6"></i>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Recent Orders Table -->
      <div class="card border-0 shadow-sm mb-4">
        <div class="card-header bg-white d-flex justify-content-between align-items-center py-3">
          <h6 class="mb-0 fw-semibold">Recent Orders</h6>
          <a href="#" class="btn btn-sm btn-outline-primary">View All</a>
        </div>
        <div class="card-body p-0">
          <div class="table-responsive">
            <table class="table table-hover mb-0 align-middle">
              <thead class="table-light">
                <tr>
                  <th>Order ID</th>
                  <th>Customer</th>
                  <th>Product</th>
                  <th>Amount</th>
                  <th>Status</th>
                  <th>Actions</th>
                </tr>
              </thead>
              <tbody>
                <tr>
                  <td><code>#ORD-001</code></td>
                  <td><div class="d-flex align-items-center gap-2"><img src="https://picsum.photos/seed/c1/28/28" class="rounded-circle" /><span>Alice Johnson</span></div></td>
                  <td>MacBook Pro 14"</td>
                  <td><strong>$1,999</strong></td>
                  <td><span class="badge rounded-pill bg-success">Delivered</span></td>
                  <td><div class="d-flex gap-1"><button class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i></button><button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button></div></td>
                </tr>
                <tr>
                  <td><code>#ORD-002</code></td>
                  <td><div class="d-flex align-items-center gap-2"><img src="https://picsum.photos/seed/c2/28/28" class="rounded-circle" /><span>Bob Smith</span></div></td>
                  <td>iPhone 15 Pro</td>
                  <td><strong>$999</strong></td>
                  <td><span class="badge rounded-pill bg-warning text-dark">Processing</span></td>
                  <td><div class="d-flex gap-1"><button class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i></button><button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button></div></td>
                </tr>
                <tr>
                  <td><code>#ORD-003</code></td>
                  <td><div class="d-flex align-items-center gap-2"><img src="https://picsum.photos/seed/c3/28/28" class="rounded-circle" /><span>Carol Davis</span></div></td>
                  <td>AirPods Pro</td>
                  <td><strong>$249</strong></td>
                  <td><span class="badge rounded-pill bg-danger">Cancelled</span></td>
                  <td><div class="d-flex gap-1"><button class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i></button><button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button></div></td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>

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

5. Common Mistakes

  • Not making sidebar scrollable: On small monitors, sidebar content may overflow. Add overflow-y: auto to the sidebar.
  • Using position: fixed sidebar without offset on main content: The main content must have margin-left: var(--sidebar-width) to not be hidden behind the sidebar.

6. MCQs

Question 1

Sidebar layout technique?

Question 2

position: sticky on topbar ensures?

Question 3

Mobile sidebar toggle?

Question 4

Stat card icons use?

Question 5

align-middle on table?

Question 6

Card table without padding at edges?

Question 7

Badge for order status best placed in?

Question 8

flex-grow-1 on main content?

Question 9

overflow-y: auto on sidebar ensures?

Question 10

ms-auto in topbar right-aligns what?

7. Interview Questions

  • Q: Design a Bootstrap admin dashboard layout with a fixed sidebar and sticky topbar. Explain your implementation.
  • Q: How do you make an admin sidebar collapsible on mobile screens?

8. Summary

An admin dashboard is the ultimate Bootstrap challenge — it combines every concept: fixed sidebar using position: fixed + content margin-left, sticky topbar, responsive stat cards, and a feature-rich data table. The mobile toggle pattern using CSS transform and a JS class toggle is the industry standard for responsive admin panels.

9. Next Chapter Recommendation

In Chapter 19: Bootstrap Interview Preparation, we compile 40 interview questions with detailed answers and 15 practical UI challenges to prepare you for any frontend interview.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·