I've shipped a lot of Bootstrap projects over the years. Here are the practices that actually matter — things that have saved me time, prevented bugs and kept codebases maintainable.
1. Always Use the Bundle JS
This is so basic but I see it wrong constantly.
<!-- ❌ Wrong — dropdowns and collapse won't work -->
<script src="bootstrap.min.js"></script>
<!-- ✅ Correct — includes Popper.js -->
<script src="bootstrap.bundle.min.js"></script>
bootstrap.bundle.min.js bundles Popper.js. Without it, dropdowns, tooltips, popovers and the navbar collapse won't function.
2. Include the Viewport Meta Tag
<!-- ❌ Missing — mobile layout breaks completely -->
<head>
<link href="bootstrap.min.css" rel="stylesheet">
</head>
<!-- ✅ Always include this -->
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="bootstrap.min.css" rel="stylesheet">
</head>
Bootstrap is mobile-first. Without the viewport tag, your responsive grid does nothing on mobile.
3. Use Sass Variables, Not !important
/* ❌ Fighting Bootstrap with !important */
.btn-primary {
background-color: #fd4766 !important;
border-color: #fd4766 !important;
}
/* ✅ Override before Bootstrap compiles */
$primary: #fd4766;
@import "bootstrap/scss/bootstrap";
Override Sass variables once and Bootstrap applies your colors consistently everywhere — buttons, badges, focus rings, active states. One line instead of hunting down every component.
4. Don't Nest Containers
<!-- ❌ Double container — adds double padding -->
<div class="container">
<div class="container">
<p>Content</p>
</div>
</div>
<!-- ✅ One container per section -->
<div class="container">
<p>Content</p>
</div>
Every container adds horizontal padding. Nesting them doubles it and limits your content width unnecessarily.
5. Use Semantic HTML, Not Just Divs
<!-- ❌ Divs for everything -->
<div class="nav">
<div class="nav-item">
<div class="nav-link">Home</div>
</div>
</div>
<!-- ✅ Proper semantic elements -->
<nav class="navbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
</ul>
</nav>
Bootstrap's classes are designed for semantic HTML. Using the right elements improves accessibility, SEO and the behavior of assistive technologies.
6. Lazy Load Images
<!-- ❌ All images load immediately -->
<img src="product.jpg" class="img-fluid">
<!-- ✅ Native lazy loading -->
<img src="product.jpg" class="img-fluid" loading="lazy" alt="Product name">
Bootstrap 5 removed lozad.js support — use the native loading="lazy" attribute. Also always include alt text.
7. Initialize JS Components Once
/* ❌ Creates a new instance every click — memory leak */
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
el.addEventListener('click', () => new bootstrap.Tooltip(el))
})
/* ✅ Initialize once on page load */
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
new bootstrap.Tooltip(el)
})
Bootstrap's tooltip, popover and modal instances should be created once. If you need to interact with them later, use getInstance.
8. Use Gap Utilities Instead of Margin Hacks
<!-- ❌ Manual margin on every child -->
<div class="d-flex">
<button class="btn btn-primary me-2">One</button>
<button class="btn btn-secondary me-2">Two</button>
<button class="btn btn-success">Three</button>
</div>
<!-- ✅ Gap on the parent -->
<div class="d-flex gap-2">
<button class="btn btn-primary">One</button>
<button class="btn btn-secondary">Two</button>
<button class="btn btn-success">Three</button>
</div>
gap-2 on a flex container spaces all children evenly without you managing individual margins. Works on grid containers too.
9. Use Component States Correctly
<!-- ❌ Hardcoded active class, never updates -->
<a class="nav-link active" href="/">Home</a>
<a class="nav-link active" href="/about">About</a>
<!-- ✅ Only current page gets active -->
<a class="nav-link active" aria-current="page" href="/">Home</a>
<a class="nav-link" href="/about">About</a>
active should only be on the current page/item. Include aria-current="page" for accessibility. In frameworks like Angular and React, derive the active state from the router instead of hardcoding it.
10. Use Custom Properties for Theming
Bootstrap 5.2+ ships with CSS custom properties on every component. Use them instead of hardcoding colors:
/* ❌ Hardcoded color */
.my-card { background-color: #ffffff; border-color: #dee2e6; }
/* ✅ Uses Bootstrap's theme variables — switches with dark mode */
.my-card {
background-color: var(--bs-body-bg);
border-color: var(--bs-border-color);
}
This matters enormously if you implement dark mode. Hardcoded colors break in dark mode. CSS variables switch automatically.
Frequently Asked Questions
Need a Full Bootstrap 5 Admin Dashboard?
Get a complete Angular 21 + Bootstrap 5 dashboard with 50+ components — built by the same team behind BootstrapPlanet.
Browse Templates →Use code FIRST30 for 30% off your first purchase.