Frontend

Bootstrap 4 Advanced Layouts Without Custom CSS

A practical guide to building complex responsive layouts using only Bootstrap 4 utility classes and grid system without writing custom CSS.

Bootstrap 4 Advanced Layouts Without Custom CSS

Overview

Most developers treat Bootstrap as a starting point and immediately start writing custom CSS on top of it. That is usually a mistake. Bootstrap 4 ships with a utility class system that is far more powerful than most teams realize. Between the grid, flexbox utilities, spacing helpers, display classes, and responsive modifiers, you can build production-quality dashboards, landing pages, and application shells without writing a single line of custom CSS.

I have built dozens of internal tools and admin panels using nothing but Bootstrap 4 classes. The result is faster development, zero CSS specificity battles, and layouts that are trivially maintainable because every decision is visible in the markup. This article walks through the techniques that make that possible — from grid fundamentals through complex dashboard layouts.

Prerequisites

  • Working knowledge of HTML5
  • Basic understanding of CSS flexbox concepts
  • Familiarity with responsive design principles (breakpoints, mobile-first)
  • Bootstrap 4.6.x loaded via CDN or npm (Bootstrap 5 changes some class names — this article targets v4)

The Grid System Deep Dive

Bootstrap 4's grid is built on CSS flexbox. Every layout starts with three elements: a container, a row, and columns.

Containers, Rows, and Columns

The .container class provides a centered, max-width wrapper. Use .container-fluid when you want edge-to-edge content.

<!-- Fixed-width centered container -->
<div class="container">
  <div class="row">
    <div class="col-md-8">Main content area</div>
    <div class="col-md-4">Sidebar</div>
  </div>
</div>

<!-- Full-width container -->
<div class="container-fluid">
  <div class="row">
    <div class="col-lg-3">Navigation</div>
    <div class="col-lg-9">Content</div>
  </div>
</div>

Breakpoints

Bootstrap 4 uses five breakpoints. Every column class follows the pattern col-{breakpoint}-{size}:

Breakpoint Class prefix Min width
Extra small col- 0px
Small col-sm- 576px
Medium col-md- 768px
Large col-lg- 992px
Extra large col-xl- 1200px

The key insight is that these are mobile-first. A class like col-md-6 means "6 columns wide at medium and above." Below medium, it defaults to full width unless you set a smaller breakpoint.

<div class="container">
  <div class="row">
    <!-- Full width on mobile, half on tablet, one-third on desktop -->
    <div class="col-12 col-md-6 col-lg-4">
      <div class="bg-light p-3 mb-3">Card 1</div>
    </div>
    <div class="col-12 col-md-6 col-lg-4">
      <div class="bg-light p-3 mb-3">Card 2</div>
    </div>
    <div class="col-12 col-md-12 col-lg-4">
      <div class="bg-light p-3 mb-3">Card 3</div>
    </div>
  </div>
</div>

Auto-Width Columns

Use col without a number to let columns share space equally. Use col-auto to size a column to its content.

<div class="row">
  <div class="col">Equal width</div>
  <div class="col">Equal width</div>
  <div class="col">Equal width</div>
</div>

<div class="row">
  <div class="col-auto">Sized to content</div>
  <div class="col">Takes remaining space</div>
</div>

Responsive Column Ordering

The order classes let you rearrange columns at different breakpoints without changing your HTML structure. This is critical for layouts where the visual order on mobile differs from desktop.

<div class="row">
  <!-- On mobile: sidebar appears second. On desktop: sidebar appears first -->
  <div class="col-12 col-md-4 order-2 order-md-1">
    <div class="bg-secondary text-white p-3">Sidebar (appears first on desktop)</div>
  </div>
  <div class="col-12 col-md-8 order-1 order-md-2">
    <div class="bg-primary text-white p-3">Main content (appears first on mobile)</div>
  </div>
</div>

You can use order-first and order-last as shortcuts:

<div class="row">
  <div class="col order-last order-md-first">I move to the front on desktop</div>
  <div class="col">Middle</div>
  <div class="col">Last on desktop</div>
</div>

Column Offsetting and Alignment

Offsets

Offset classes push columns to the right by a specified number of grid columns:

<div class="row">
  <div class="col-md-6 offset-md-3">
    <div class="bg-light p-4 text-center">Centered 6-column block</div>
  </div>
</div>

<div class="row">
  <div class="col-md-4">Left column</div>
  <div class="col-md-4 offset-md-4">Right-aligned column</div>
</div>

Vertical and Horizontal Alignment

Row-level alignment uses flexbox utilities directly on the .row:

<!-- Vertically center all columns in the row -->
<div class="row align-items-center" style="min-height: 200px;">
  <div class="col-4">
    <div class="bg-info p-2">Short</div>
  </div>
  <div class="col-4">
    <div class="bg-warning p-2">Taller content that wraps across multiple lines</div>
  </div>
</div>

<!-- Horizontally center columns that don't fill the row -->
<div class="row justify-content-center">
  <div class="col-4">
    <div class="bg-light p-3">Centered block</div>
  </div>
</div>

<!-- Space columns evenly -->
<div class="row justify-content-between">
  <div class="col-3"><div class="bg-light p-2">Left</div></div>
  <div class="col-3"><div class="bg-light p-2">Right</div></div>
</div>

Nested Grids for Complex Layouts

Any column can contain its own .row and child columns. The nested row creates a new 12-column context within its parent column.

<div class="container">
  <div class="row">
    <div class="col-md-8">
      <h5>Main Content</h5>
      <!-- Nested grid inside the 8-column parent -->
      <div class="row">
        <div class="col-md-6">
          <div class="bg-light p-3 mb-3">Nested left (50% of parent)</div>
        </div>
        <div class="col-md-6">
          <div class="bg-light p-3 mb-3">Nested right (50% of parent)</div>
        </div>
      </div>
      <div class="row">
        <div class="col-md-4">
          <div class="bg-light p-3">Third</div>
        </div>
        <div class="col-md-4">
          <div class="bg-light p-3">Third</div>
        </div>
        <div class="col-md-4">
          <div class="bg-light p-3">Third</div>
        </div>
      </div>
    </div>
    <div class="col-md-4">
      <div class="bg-secondary text-white p-3 h-100">Sidebar</div>
    </div>
  </div>
</div>

Flexbox Utilities

Bootstrap 4 exposes the full power of flexbox through utility classes. These work on any element, not just rows and columns.

Direction and Wrapping

<!-- Horizontal layout (default) -->
<div class="d-flex">
  <div class="p-2 bg-light border">Item 1</div>
  <div class="p-2 bg-light border">Item 2</div>
  <div class="p-2 bg-light border">Item 3</div>
</div>

<!-- Vertical stack -->
<div class="d-flex flex-column">
  <div class="p-2 bg-light border">Top</div>
  <div class="p-2 bg-light border">Middle</div>
  <div class="p-2 bg-light border">Bottom</div>
</div>

<!-- Row on desktop, column on mobile -->
<div class="d-flex flex-column flex-md-row">
  <div class="p-2 bg-light border">Adapts to screen</div>
  <div class="p-2 bg-light border">Adapts to screen</div>
</div>

Justify Content and Align Items

<!-- Space items evenly with equal gaps -->
<div class="d-flex justify-content-around p-3 bg-dark">
  <span class="badge badge-primary p-2">Home</span>
  <span class="badge badge-primary p-2">About</span>
  <span class="badge badge-primary p-2">Contact</span>
</div>

<!-- Push last item to the right -->
<div class="d-flex">
  <div class="p-2">Brand</div>
  <div class="p-2 ml-auto">Login</div>
</div>

<!-- Center both axes -->
<div class="d-flex justify-content-center align-items-center bg-light" style="min-height: 150px;">
  <div class="text-center">
    <h4>Perfectly Centered</h4>
    <p class="mb-0">Both horizontally and vertically</p>
  </div>
</div>

Flex Grow and Shrink

The flex-grow-1 class makes an element expand to fill available space. This is essential for sticky footer patterns and sidebar layouts.

<div class="d-flex">
  <div class="p-2 bg-secondary text-white">Fixed sidebar</div>
  <div class="p-2 flex-grow-1 bg-light">This expands to fill remaining space</div>
</div>

Spacing Utilities

Bootstrap 4's spacing utilities follow the pattern {property}{sides}-{breakpoint}-{size}. Properties are m (margin) and p (padding). Sides include t (top), b (bottom), l (left), r (right), x (horizontal), y (vertical). Sizes range from 0 to 5, plus auto.

<!-- Common spacing patterns -->
<div class="mt-3">Margin top 1rem</div>
<div class="px-4">Padding left and right 1.5rem</div>
<div class="mb-0">No bottom margin</div>
<div class="py-5">Large vertical padding</div>

<!-- Responsive spacing: tight on mobile, spacious on desktop -->
<div class="p-2 p-md-4 p-lg-5">
  Content with responsive padding
</div>

<!-- Center a block horizontally with auto margins -->
<div class="mx-auto" style="width: 300px;">
  Centered block
</div>

These replace the vast majority of one-off CSS declarations teams write. Instead of .my-custom-header { margin-bottom: 2rem; padding: 1rem; }, you write class="mb-4 p-3" directly in the markup.

Display Utilities for Responsive Visibility

Control what appears at each breakpoint with d-{breakpoint}-{value} classes:

<!-- Show only on mobile (hidden md and up) -->
<div class="d-block d-md-none">
  <p>Mobile-only navigation</p>
</div>

<!-- Hidden on mobile, visible on desktop -->
<div class="d-none d-md-block">
  <p>Desktop sidebar</p>
</div>

<!-- Inline on desktop, block on mobile -->
<span class="d-block d-lg-inline">Item 1</span>
<span class="d-block d-lg-inline">Item 2</span>
<span class="d-block d-lg-inline">Item 3</span>

This replaces media queries for visibility toggling entirely.

Card Decks and Card Columns

Equal-Height Cards with Card Decks

<div class="card-deck">
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Short Card</h5>
      <p class="card-text">Brief content.</p>
    </div>
    <div class="card-footer bg-transparent">
      <small class="text-muted">Footer aligned</small>
    </div>
  </div>
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Tall Card</h5>
      <p class="card-text">This card has significantly more content, pushing it taller than the others. The card-deck ensures all cards match this height.</p>
    </div>
    <div class="card-footer bg-transparent">
      <small class="text-muted">Footer aligned</small>
    </div>
  </div>
  <div class="card">
    <div class="card-body">
      <h5 class="card-title">Medium Card</h5>
      <p class="card-text">Moderate content here.</p>
    </div>
    <div class="card-footer bg-transparent">
      <small class="text-muted">Footer aligned</small>
    </div>
  </div>
</div>

Masonry-Style with Card Columns

<div class="card-columns">
  <div class="card bg-primary text-white p-3">Short card</div>
  <div class="card bg-success text-white p-3">Card with more content that wraps to demonstrate the masonry layout behavior</div>
  <div class="card bg-info text-white p-3">Medium card</div>
  <div class="card bg-warning p-3">Another card</div>
  <div class="card bg-danger text-white p-3">Card with a lot of content to show the staggered column effect that card-columns creates automatically</div>
  <div class="card bg-dark text-white p-3">Final card</div>
</div>

Navbar and Responsive Collapse

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <a class="navbar-brand" href="#">Dashboard</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navContent">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navContent">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active"><a class="nav-link" href="#">Home</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Reports</a></li>
      <li class="nav-item"><a class="nav-link" href="#">Settings</a></li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search">
      <button class="btn btn-outline-light my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

Sticky Footer Pattern

A sticky footer sticks to the bottom of the viewport when content is short, but moves down naturally when content is long. This uses flexbox on the body.

<body class="d-flex flex-column" style="min-height: 100vh;">
  <nav class="navbar navbar-dark bg-dark">
    <a class="navbar-brand" href="#">App</a>
  </nav>

  <main class="flex-grow-1 container py-4">
    <h1>Page Content</h1>
    <p>Even with minimal content, the footer stays at the bottom.</p>
  </main>

  <footer class="bg-dark text-white text-center py-3">
    <p class="mb-0">&copy; 2026 My Application</p>
  </footer>
</body>

The combination of d-flex flex-column on the body and flex-grow-1 on main is all it takes. The main area expands to push the footer down.

Sidebar Layout with Content Area

<div class="container-fluid">
  <div class="row">
    <!-- Sidebar: hidden on mobile, visible on medium+ -->
    <nav class="col-md-3 col-lg-2 d-none d-md-block bg-light sidebar">
      <div class="position-sticky pt-3">
        <ul class="nav flex-column">
          <li class="nav-item"><a class="nav-link active" href="#">Dashboard</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Orders</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Products</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Customers</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Reports</a></li>
        </ul>
      </div>
    </nav>

    <!-- Main content -->
    <main class="col-md-9 ml-sm-auto col-lg-10 px-md-4 py-3">
      <h2>Dashboard</h2>
      <p>Main content goes here. On mobile, this takes the full width and the sidebar disappears.</p>
    </main>
  </div>
</div>

Holy Grail Layout

The classic three-column layout with header, footer, left sidebar, right sidebar, and main content:

<body class="d-flex flex-column" style="min-height: 100vh;">
  <!-- Header -->
  <header class="bg-dark text-white p-3">
    <h4 class="mb-0">Site Header</h4>
  </header>

  <!-- Middle section -->
  <div class="container-fluid flex-grow-1">
    <div class="row h-100">
      <!-- Left sidebar -->
      <aside class="col-md-2 bg-light py-3 d-none d-md-block">
        <h6>Navigation</h6>
        <ul class="nav flex-column">
          <li class="nav-item"><a class="nav-link" href="#">Link 1</a></li>
          <li class="nav-item"><a class="nav-link" href="#">Link 2</a></li>
        </ul>
      </aside>

      <!-- Main content -->
      <main class="col-md-8 py-3">
        <h2>Main Content</h2>
        <p>The holy grail layout achieved with Bootstrap grid classes only.</p>
      </main>

      <!-- Right sidebar -->
      <aside class="col-md-2 bg-light py-3 d-none d-md-block">
        <h6>Widgets</h6>
        <p class="small">Recent posts, ads, or related content.</p>
      </aside>
    </div>
  </div>

  <!-- Footer -->
  <footer class="bg-dark text-white text-center p-3">
    <p class="mb-0">Footer Content</p>
  </footer>
</body>

Media Object for Comment and Feed Layouts

Bootstrap 4's media object is purpose-built for comment threads, social feeds, and notification lists:

<div class="media p-3 border-bottom">
  <img src="https://via.placeholder.com/48" class="mr-3 rounded-circle" alt="User">
  <div class="media-body">
    <h6 class="mt-0 mb-1">Jane Smith <small class="text-muted">2 hours ago</small></h6>
    <p class="mb-1">This is a comment in a feed layout. The media object handles the image-beside-text pattern perfectly.</p>
    <!-- Nested media for replies -->
    <div class="media mt-3">
      <img src="https://via.placeholder.com/32" class="mr-3 rounded-circle" alt="User">
      <div class="media-body">
        <h6 class="mt-0 mb-1">John Doe <small class="text-muted">1 hour ago</small></h6>
        <p class="mb-0">Nested reply to the comment above.</p>
      </div>
    </div>
  </div>
</div>

Responsive Image Galleries

<div class="container">
  <div class="row no-gutters">
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
    <div class="col-6 col-md-4 col-lg-3 p-1">
      <img src="https://via.placeholder.com/400x300" class="img-fluid rounded" alt="Gallery image">
    </div>
  </div>
</div>

The no-gutters class removes the default gutter padding, and the p-1 on each column adds a minimal, uniform gap. At small screens you get 2 across, medium gives 3, and large gives 4.

Form Layouts

Inline Form

<form class="form-inline">
  <label class="sr-only" for="emailInput">Email</label>
  <input type="email" class="form-control mb-2 mr-sm-2" id="emailInput" placeholder="[email protected]">
  <button type="submit" class="btn btn-primary mb-2">Subscribe</button>
</form>

Horizontal Form with Grid

<form>
  <div class="form-group row">
    <label for="inputName" class="col-sm-3 col-form-label">Full Name</label>
    <div class="col-sm-9">
      <input type="text" class="form-control" id="inputName">
    </div>
  </div>
  <div class="form-group row">
    <label for="inputEmail" class="col-sm-3 col-form-label">Email</label>
    <div class="col-sm-9">
      <input type="email" class="form-control" id="inputEmail">
    </div>
  </div>
  <div class="form-group row">
    <div class="col-sm-9 offset-sm-3">
      <button type="submit" class="btn btn-primary">Save</button>
    </div>
  </div>
</form>

Multi-Column Grid Form

<form>
  <div class="form-row">
    <div class="form-group col-md-6">
      <label for="firstName">First Name</label>
      <input type="text" class="form-control" id="firstName">
    </div>
    <div class="form-group col-md-6">
      <label for="lastName">Last Name</label>
      <input type="text" class="form-control" id="lastName">
    </div>
  </div>
  <div class="form-row">
    <div class="form-group col-md-6">
      <label for="city">City</label>
      <input type="text" class="form-control" id="city">
    </div>
    <div class="form-group col-md-3">
      <label for="state">State</label>
      <select class="form-control" id="state">
        <option>Choose...</option>
        <option>CA</option>
        <option>NY</option>
      </select>
    </div>
    <div class="form-group col-md-3">
      <label for="zip">Zip</label>
      <input type="text" class="form-control" id="zip">
    </div>
  </div>
  <button type="submit" class="btn btn-primary">Submit</button>
</form>

Modal and Overlay Positioning

Bootstrap modals handle overlay positioning automatically, but you control the modal's internal layout with the same grid and utility classes:

<div class="modal fade" id="detailModal" tabindex="-1">
  <div class="modal-dialog modal-lg modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Product Details</h5>
        <button type="button" class="close" data-dismiss="modal">
          <span>&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <!-- Grid inside modal -->
        <div class="row">
          <div class="col-md-5">
            <img src="https://via.placeholder.com/400x400" class="img-fluid rounded" alt="Product">
          </div>
          <div class="col-md-7">
            <h4>Product Name</h4>
            <p class="text-muted">Category: Electronics</p>
            <p>Product description with full grid layout inside a modal dialog.</p>
            <h5 class="text-success">$149.99</h5>
          </div>
        </div>
      </div>
      <div class="modal-footer justify-content-between">
        <button class="btn btn-secondary" data-dismiss="modal">Close</button>
        <button class="btn btn-primary">Add to Cart</button>
      </div>
    </div>
  </div>
</div>

The modal-dialog-centered class vertically centers the modal. The modal-lg class widens it. The justify-content-between on the footer spaces the buttons apart.

Print-Friendly Layouts

Bootstrap 4 includes print-specific display utilities:

<!-- Hide navigation and sidebar when printing -->
<nav class="navbar d-print-none">
  <!-- Navigation content -->
</nav>

<div class="container">
  <div class="row">
    <aside class="col-md-3 d-print-none">
      Sidebar hidden in print
    </aside>
    <main class="col-md-9 col-print-12">
      <h1>Report Title</h1>
      <p>This content expands to full width when printed.</p>

      <!-- Show print-only content -->
      <div class="d-none d-print-block">
        <p>Printed on: <span id="printDate"></span></p>
        <p>Confidential - Internal Use Only</p>
      </div>
    </main>
  </div>
</div>

Combining Utility Classes Effectively

The real power comes from combining utilities. Here are patterns I use constantly:

<!-- Centered hero section -->
<div class="d-flex justify-content-center align-items-center bg-primary text-white text-center py-5">
  <div class="px-3">
    <h1 class="display-4 font-weight-bold">Welcome</h1>
    <p class="lead mb-4">Build layouts without CSS.</p>
    <a href="#" class="btn btn-light btn-lg">Get Started</a>
  </div>
</div>

<!-- Tag/chip layout -->
<div class="d-flex flex-wrap">
  <span class="badge badge-pill badge-primary mr-2 mb-2 p-2">JavaScript</span>
  <span class="badge badge-pill badge-primary mr-2 mb-2 p-2">Bootstrap</span>
  <span class="badge badge-pill badge-primary mr-2 mb-2 p-2">CSS Grid</span>
  <span class="badge badge-pill badge-primary mr-2 mb-2 p-2">Responsive</span>
</div>

<!-- Stat cards in a row -->
<div class="row text-center">
  <div class="col-6 col-md-3 mb-3">
    <div class="border rounded p-3">
      <h2 class="font-weight-bold text-primary mb-0">1,247</h2>
      <small class="text-muted text-uppercase">Users</small>
    </div>
  </div>
  <div class="col-6 col-md-3 mb-3">
    <div class="border rounded p-3">
      <h2 class="font-weight-bold text-success mb-0">$34K</h2>
      <small class="text-muted text-uppercase">Revenue</small>
    </div>
  </div>
  <div class="col-6 col-md-3 mb-3">
    <div class="border rounded p-3">
      <h2 class="font-weight-bold text-info mb-0">89%</h2>
      <small class="text-muted text-uppercase">Uptime</small>
    </div>
  </div>
  <div class="col-6 col-md-3 mb-3">
    <div class="border rounded p-3">
      <h2 class="font-weight-bold text-warning mb-0">42</h2>
      <small class="text-muted text-uppercase">Issues</small>
    </div>
  </div>
</div>

Complete Working Example: Responsive Dashboard

Here is a fully functional dashboard page using only Bootstrap 4 classes. No custom CSS. Copy this into an HTML file and open it in a browser.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Dashboard - Bootstrap 4 Only</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body class="d-flex flex-column" style="min-height: 100vh;">

  <!-- Top Navigation -->
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <a class="navbar-brand font-weight-bold" href="#">AdminPanel</a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#topNav">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="topNav">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item active"><a class="nav-link" href="#">Dashboard</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Analytics</a></li>
        <li class="nav-item"><a class="nav-link" href="#">Settings</a></li>
      </ul>
      <form class="form-inline">
        <input class="form-control form-control-sm mr-2" type="search" placeholder="Search...">
        <button class="btn btn-outline-light btn-sm" type="submit">Search</button>
      </form>
      <ul class="navbar-nav ml-3">
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">
            Shane L.
          </a>
          <div class="dropdown-menu dropdown-menu-right">
            <a class="dropdown-item" href="#">Profile</a>
            <a class="dropdown-item" href="#">Settings</a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item" href="#">Logout</a>
          </div>
        </li>
      </ul>
    </div>
  </nav>

  <!-- Main Content Area -->
  <div class="container-fluid flex-grow-1">
    <div class="row h-100">

      <!-- Sidebar Navigation (hidden on mobile) -->
      <nav class="col-md-3 col-lg-2 d-none d-md-block bg-light border-right py-3">
        <h6 class="text-muted text-uppercase px-3 mb-3">
          <small class="font-weight-bold">Core</small>
        </h6>
        <ul class="nav flex-column">
          <li class="nav-item">
            <a class="nav-link active text-dark font-weight-bold" href="#">
              &#9632; Overview
            </a>
          </li>
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Reports</a>
          </li>
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Customers</a>
          </li>
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Products</a>
          </li>
        </ul>
        <h6 class="text-muted text-uppercase px-3 mt-4 mb-3">
          <small class="font-weight-bold">Tools</small>
        </h6>
        <ul class="nav flex-column">
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Import</a>
          </li>
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Export</a>
          </li>
          <li class="nav-item">
            <a class="nav-link text-secondary" href="#">&#9632; Integrations</a>
          </li>
        </ul>
      </nav>

      <!-- Dashboard Content -->
      <main class="col-md-9 ml-sm-auto col-lg-10 px-3 px-md-4 py-4">

        <!-- Page Header -->
        <div class="d-flex justify-content-between align-items-center flex-wrap mb-4">
          <h2 class="mb-0">Dashboard</h2>
          <div>
            <button class="btn btn-sm btn-outline-secondary mr-1">Export</button>
            <button class="btn btn-sm btn-primary">+ New Report</button>
          </div>
        </div>

        <!-- Stats Row -->
        <div class="row mb-4">
          <div class="col-6 col-lg-3 mb-3">
            <div class="card border-left-0 border-right-0 border-bottom-0 border-primary border-top">
              <div class="card-body py-3">
                <small class="text-muted text-uppercase font-weight-bold">Revenue</small>
                <h3 class="font-weight-bold mb-0">$42,580</h3>
                <small class="text-success">+12.5% from last month</small>
              </div>
            </div>
          </div>
          <div class="col-6 col-lg-3 mb-3">
            <div class="card border-left-0 border-right-0 border-bottom-0 border-success border-top">
              <div class="card-body py-3">
                <small class="text-muted text-uppercase font-weight-bold">Orders</small>
                <h3 class="font-weight-bold mb-0">1,893</h3>
                <small class="text-success">+3.2% from last month</small>
              </div>
            </div>
          </div>
          <div class="col-6 col-lg-3 mb-3">
            <div class="card border-left-0 border-right-0 border-bottom-0 border-info border-top">
              <div class="card-body py-3">
                <small class="text-muted text-uppercase font-weight-bold">Customers</small>
                <h3 class="font-weight-bold mb-0">8,461</h3>
                <small class="text-danger">-1.8% from last month</small>
              </div>
            </div>
          </div>
          <div class="col-6 col-lg-3 mb-3">
            <div class="card border-left-0 border-right-0 border-bottom-0 border-warning border-top">
              <div class="card-body py-3">
                <small class="text-muted text-uppercase font-weight-bold">Tickets</small>
                <h3 class="font-weight-bold mb-0">24</h3>
                <small class="text-success">-8 from last week</small>
              </div>
            </div>
          </div>
        </div>

        <!-- Content Cards Row -->
        <div class="row mb-4">
          <div class="col-lg-8 mb-3">
            <div class="card h-100">
              <div class="card-header bg-white d-flex justify-content-between align-items-center">
                <h6 class="mb-0 font-weight-bold">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">
                    <thead class="thead-light">
                      <tr>
                        <th>Order ID</th>
                        <th>Customer</th>
                        <th class="d-none d-sm-table-cell">Date</th>
                        <th>Amount</th>
                        <th>Status</th>
                      </tr>
                    </thead>
                    <tbody>
                      <tr>
                        <td><strong>#4281</strong></td>
                        <td>Alice Johnson</td>
                        <td class="d-none d-sm-table-cell">Feb 12, 2026</td>
                        <td>$320.00</td>
                        <td><span class="badge badge-success">Paid</span></td>
                      </tr>
                      <tr>
                        <td><strong>#4280</strong></td>
                        <td>Bob Williams</td>
                        <td class="d-none d-sm-table-cell">Feb 12, 2026</td>
                        <td>$185.00</td>
                        <td><span class="badge badge-warning">Pending</span></td>
                      </tr>
                      <tr>
                        <td><strong>#4279</strong></td>
                        <td>Carol Davis</td>
                        <td class="d-none d-sm-table-cell">Feb 11, 2026</td>
                        <td>$540.00</td>
                        <td><span class="badge badge-success">Paid</span></td>
                      </tr>
                      <tr>
                        <td><strong>#4278</strong></td>
                        <td>David Chen</td>
                        <td class="d-none d-sm-table-cell">Feb 11, 2026</td>
                        <td>$92.50</td>
                        <td><span class="badge badge-danger">Refunded</span></td>
                      </tr>
                      <tr>
                        <td><strong>#4277</strong></td>
                        <td>Eva Martinez</td>
                        <td class="d-none d-sm-table-cell">Feb 10, 2026</td>
                        <td>$267.00</td>
                        <td><span class="badge badge-success">Paid</span></td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </div>
          <div class="col-lg-4 mb-3">
            <div class="card h-100">
              <div class="card-header bg-white">
                <h6 class="mb-0 font-weight-bold">Quick Actions</h6>
              </div>
              <div class="card-body d-flex flex-column">
                <a href="#" class="btn btn-outline-primary btn-block mb-2">Create Invoice</a>
                <a href="#" class="btn btn-outline-primary btn-block mb-2">Add Customer</a>
                <a href="#" class="btn btn-outline-primary btn-block mb-2">New Product</a>
                <a href="#" class="btn btn-outline-primary btn-block mb-2">Generate Report</a>
                <div class="mt-auto pt-3 border-top">
                  <small class="text-muted">Last updated: Feb 13, 2026 at 9:41 AM</small>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- Activity Feed -->
        <div class="row">
          <div class="col-lg-6 mb-3">
            <div class="card">
              <div class="card-header bg-white">
                <h6 class="mb-0 font-weight-bold">Recent Activity</h6>
              </div>
              <div class="card-body">
                <div class="media mb-3">
                  <div class="bg-primary rounded-circle d-flex align-items-center justify-content-center mr-3 text-white font-weight-bold" style="width:40px; height:40px;">AJ</div>
                  <div class="media-body">
                    <p class="mb-0"><strong>Alice Johnson</strong> placed order #4281</p>
                    <small class="text-muted">2 hours ago</small>
                  </div>
                </div>
                <div class="media mb-3">
                  <div class="bg-success rounded-circle d-flex align-items-center justify-content-center mr-3 text-white font-weight-bold" style="width:40px; height:40px;">BW</div>
                  <div class="media-body">
                    <p class="mb-0"><strong>Bob Williams</strong> updated shipping address</p>
                    <small class="text-muted">4 hours ago</small>
                  </div>
                </div>
                <div class="media">
                  <div class="bg-info rounded-circle d-flex align-items-center justify-content-center mr-3 text-white font-weight-bold" style="width:40px; height:40px;">CD</div>
                  <div class="media-body">
                    <p class="mb-0"><strong>Carol Davis</strong> left a 5-star review</p>
                    <small class="text-muted">6 hours ago</small>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="col-lg-6 mb-3">
            <div class="card">
              <div class="card-header bg-white">
                <h6 class="mb-0 font-weight-bold">System Alerts</h6>
              </div>
              <div class="card-body">
                <div class="alert alert-success py-2 mb-2" role="alert">
                  <small><strong>Backup complete.</strong> Daily backup finished at 3:00 AM.</small>
                </div>
                <div class="alert alert-warning py-2 mb-2" role="alert">
                  <small><strong>Storage at 78%.</strong> Consider archiving old records.</small>
                </div>
                <div class="alert alert-info py-2 mb-0" role="alert">
                  <small><strong>Update available.</strong> Version 2.4.1 is ready to install.</small>
                </div>
              </div>
            </div>
          </div>
        </div>

      </main>
    </div>
  </div>

  <!-- Footer -->
  <footer class="bg-dark text-white text-center py-3 d-print-none">
    <small>&copy; 2026 AdminPanel. Built with Bootstrap 4 &mdash; zero custom CSS.</small>
  </footer>

  <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

This dashboard demonstrates sidebar navigation that hides on mobile, a responsive header with search, stat cards that rearrange from 2-across on mobile to 4-across on desktop, a data table with hidden columns on small screens, an activity feed using media objects, and a sticky footer — all without a single line of custom CSS.

Common Issues and Troubleshooting

Columns not stacking on mobile. If you use col-6 without a breakpoint prefix, those columns are always 6 wide — even on phones. Use col-12 col-md-6 to get stacking on mobile and side-by-side on tablet.

Gutters causing horizontal overflow. Rows have negative margins that extend beyond their container. Make sure every .row is inside a .container or .container-fluid. If you see a horizontal scrollbar, a row is sitting outside a container.

Spacing utilities not responsive. Remember spacing utilities support breakpoints: mb-3 mb-md-0 removes the bottom margin on medium screens. Forgetting this leads to excessive whitespace on desktop or cramped layouts on mobile.

Card deck cards not wrapping. The .card-deck class renders all cards in a single flex row. If you need wrapping, use .row and .col-* with individual .card elements inside each column instead.

Flex items not stretching. When using d-flex on a parent, child elements do not automatically stretch to fill height. Add align-items-stretch to the parent or h-100 to child cards that need equal height.

Best Practices

  1. Start mobile-first. Define your base layout with unprefixed classes (col-12, d-block, mb-3), then add breakpoint-specific overrides. This matches Bootstrap's architecture and avoids fighting the framework.

  2. Avoid inline styles. The one exception in this article is min-height: 100vh on the body for sticky footer patterns. Nearly everything else should use utility classes. If you find yourself writing style=, check if a utility class exists first.

  3. Use container-fluid for dashboards, container for content. Dashboards and admin panels benefit from full-width layouts. Marketing pages and article content read better in a centered, max-width container.

  4. Combine h-100 with d-flex flex-column for equal-height card layouts. Set h-100 on the card, make the card body d-flex flex-column, and use mt-auto on the card footer element. This pushes footers to the bottom regardless of content height.

  5. Use no-gutters deliberately. The default 30px gutter works well for most layouts. Only remove gutters for image galleries or tile-based interfaces where you want edge-to-edge content.

  6. Lean on d-none d-{breakpoint}-block for responsive content. Instead of JavaScript-based show/hide logic, use display utilities. They are declarative, require no JS, and are trivially readable by any developer who knows Bootstrap.

  7. Prefer flex-wrap over nested rows for tag-like layouts. When rendering a variable number of small elements (tags, badges, chips), d-flex flex-wrap with margin utilities produces cleaner markup than grid columns.

References

Powered by Contentful