bootstrap5-ui
Bootstrap 5 UI
Production patterns for building responsive, accessible web UIs with Bootstrap 5.3 in HTML and ASP.NET Core Razor Pages/Views. Target Bootstrap 5.3.x (current CDN: 5.3.8). Bootstrap 5 dropped jQuery dependency entirely.
Setup in ASP.NET Core
CDN (Quick Start)
In _Layout.cshtml or _Host.cshtml:
<!-- In <head> -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous">
<!-- Before closing </body> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI"
crossorigin="anonymous"></script>
LibMan (Recommended for Production)
// libman.json
{
"version": "1.0",
"defaultProvider": "jsdelivr",
"libraries": [
{
"library": "bootstrap@5.3.8",
"destination": "wwwroot/lib/bootstrap/"
}
]
}
Reference locally in layout:
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
Required Globals
Always include in <head>:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
Grid System
Bootstrap uses a 12-column flexbox grid with 6 responsive breakpoints:
| Breakpoint | Prefix | Min-width |
|---|---|---|
| Extra small | .col- |
<576px |
| Small | .col-sm- |
>=576px |
| Medium | .col-md- |
>=768px |
| Large | .col-lg- |
>=992px |
| Extra large | .col-xl- |
>=1200px |
| XXL | .col-xxl- |
>=1400px |
Core Pattern
<div class="container">
<div class="row">
<div class="col-md-8">Main content</div>
<div class="col-md-4">Sidebar</div>
</div>
</div>
Key Rules
- Always wrap columns in
.rowinside a.container(or.container-fluidfor full-width) - Columns must be direct children of rows
- Use
.g-*classes for gutters (.g-0removes gutters,.gx-*horizontal,.gy-*vertical) - Use
.row-cols-*on the row for uniform column counts:<div class="row row-cols-1 row-cols-md-3 g-4"> - Mix breakpoints:
<div class="col-6 col-md-4 col-lg-3">— stacks to 2-up on xs, 3-up on md, 4-up on lg
Container Types
.container— responsive fixed-width.container-fluid— full-width always.container-{breakpoint}— fluid until breakpoint, then fixed
Spacing Utilities
Format: {property}{sides}-{breakpoint}-{size}
Property: m (margin), p (padding)
Sides: t top, b bottom, s start(left), e end(right), x horizontal, y vertical, blank = all
Size: 0=0, 1=0.25rem, 2=0.5rem, 3=1rem, 4=1.5rem, 5=3rem, auto
<div class="mt-3 mb-4 px-2">Spaced element</div>
<div class="mx-auto" style="width: 200px;">Centered block</div>
<div class="py-md-5">Padding only on md+</div>
Color Modes (Dark/Light)
Bootstrap 5.3 supports data-bs-theme attribute for dark mode:
<!-- Global dark mode -->
<html lang="en" data-bs-theme="dark">
<!-- Per-component -->
<div class="card" data-bs-theme="dark">...</div>
<nav class="navbar bg-dark" data-bs-theme="dark">...</nav>
Use semantic color classes that adapt to color mode:
bg-body,bg-body-secondary,bg-body-tertiary— adapt to themetext-body,text-body-secondary,text-body-emphasis— adapt to themeborder-body— adapts to theme
Avoid hardcoded colors. Use bg-body-tertiary instead of bg-light for theme-aware backgrounds.
Common Component Patterns
Navbar
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Brand</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#mainNav"
aria-controls="mainNav" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mainNav">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<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="#">About</a>
</li>
</ul>
</div>
</div>
</nav>
Cards in Grid
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
<div class="col">
<div class="card h-100">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">Title</h5>
<p class="card-text">Description text.</p>
<a href="#" class="btn btn-primary">Action</a>
</div>
</div>
</div>
<!-- repeat -->
</div>
Forms
<form method="post">
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password">
</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>
Floating Labels
<div class="form-floating mb-3">
<input type="email" class="form-control" id="floatEmail" placeholder="name@example.com">
<label for="floatEmail">Email address</label>
</div>
Responsive Table
<div class="table-responsive">
<table class="table table-striped table-hover">
<thead class="table-dark">
<tr><th>Name</th><th>Email</th><th>Actions</th></tr>
</thead>
<tbody>
<tr><td>John</td><td>john@example.com</td><td><a class="btn btn-sm btn-outline-primary">Edit</a></td></tr>
</tbody>
</table>
</div>
Razor Pages Integration
For detailed ASP.NET Core Razor Pages integration patterns including tag helpers, validation, layouts, and partial views, see references/razor-integration.md.
Key points:
- Use
asp-for,asp-page,asp-actiontag helpers with Bootstrap classes - Combine
asp-validation-forwith.invalid-feedback/.is-invalidclasses - Place Bootstrap validation classes via jQuery Validation Unobtrusive or custom JS
- Use
@section Scriptsfor page-specific scripts in layout
Component Reference
For complete component patterns (modals, alerts, toasts, accordion, pagination, breadcrumbs, badges, offcanvas, spinners, progress bars), see references/components.md.
Utility Classes Quick Reference
Display
d-none, d-block, d-flex, d-grid, d-inline, d-inline-block
Responsive: d-md-none, d-lg-flex
Flexbox
justify-content-{start|center|end|between|around|evenly}
align-items-{start|center|end|stretch}
flex-{row|column}, flex-wrap, flex-grow-1
Text
text-{start|center|end}, text-{lowercase|uppercase|capitalize}
fw-{bold|semibold|normal|light}, fs-{1-6}
text-truncate, text-nowrap, text-break
Colors
text-{primary|secondary|success|danger|warning|info|light|dark}
bg-{primary|secondary|success|danger|warning|info|light|dark}
text-bg-{color} — sets matching text+bg together
Borders & Shadows
border, border-{top|bottom|start|end}, border-{color}, border-{1-5}
rounded, rounded-{0-5|circle|pill}
shadow, shadow-sm, shadow-lg, shadow-none
Sizing
w-{25|50|75|100|auto}, h-{25|50|75|100|auto}
mw-100, mh-100, vw-100, vh-100
min-vw-100, min-vh-100
Position
position-{static|relative|absolute|fixed|sticky}
top-{0|50|100}, start-{0|50|100}, translate-middle
Accessibility Requirements
- Always include
aria-labelon icon-only buttons and togglers - Use
aria-current="page"on active nav links - Use
aria-expandedon collapse/dropdown triggers - Provide
alttext on images; use.visually-hiddenfor screen-reader-only text - Ensure color contrast meets WCAG 2.1 AA (4.5:1 for text, 3:1 for large text)
- Use semantic HTML:
<nav>,<main>,<header>,<footer>,<section>,<article> - Never remove
:focusstyles; use Bootstrap's.focus-ringutility for custom focus
Anti-Patterns
- Using
col-*without a parent.row— breaks grid alignment - Nesting containers — only nest rows, never containers inside containers
- Using
<br>and inline styles for spacing — use spacing utilities (mt-3,mb-4) - Hardcoding
bg-light/bg-dark— usebg-body-tertiaryfor theme-aware backgrounds - Forgetting
navbar-expand-{breakpoint}— navbar won't collapse responsively - Mixing Bootstrap 4 classes (e.g.,
ml-3,mr-3) — usems-3,me-3(start/end logical properties) - Omitting
type="button"on non-submit buttons in forms — causes unintended form submission - Using
<a>for actions withouthref— use<button>for actions,<a>for navigation - Skipping
.form-labelon form inputs — hurts accessibility - Not wrapping tables in
.table-responsive— causes horizontal overflow on mobile