Customizing Bootstrap 5 with Sass Variables
This guide shows you how to customize Bootstrap 5 using Sass variables. You'll learn how to modify colors, typography, spacing, and components…
This guide covers the two primary methods of adding Bootstrap 5 to your projects: Content Delivery Network (CDN) and Node Package Manager (NPM). We'll explore implementation details, compare the approaches across different frameworks, and examine performance implications to help you choose the right setup method for your specific use case.
One of the quickest ways to add Bootstrap 5 to a project is by using a Content Delivery Network (CDN). A CDN hosts Bootstrap’s files on servers around the world, delivering them quickly to users. Using a CDN requires no installation – you simply include <link> and <script> tags in your HTML pointing to the Bootstrap assets hosted online.
How to Include via CDN: In your HTML file, add the Bootstrap CDN links for the CSS and JS. The official Bootstrap 5 CDN (via jsDelivr or similar) can be used. For example, in the <head> include the Bootstrap CSS, and before the closing </body> include the Bootstrap bundle JS (which contains Bootstrap’s JS + Popper for tooltips/popovers):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bootstrap 5 CDN Example</title>
<!-- Bootstrap 5 CSS (CDN) -->
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1 class="text-center">Hello, Bootstrap 5!</h1>
<p>This page is using Bootstrap via CDN.</p>
<button class="btn btn-primary">A Bootstrap Button</button>
</div>
<!-- Bootstrap 5 JS Bundle with Popper (CDN) -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
</body>
</html>
In the example above, we include bootstrap.min.css in the <head> and bootstrap.bundle.min.js just before </body>. The bundle includes all of Bootstrap’s JS plugins plus Popper (needed for dropdowns, tooltips, popovers, etc.) This means you don’t have to include Popper separately as long as you use the bundle. (If you choose to include separate JS files instead, remember that Popper must be included before Bootstrap’s JS if you need those components )
A few notes on using the CDN approach:
integrity attribute in the <link> and <script> tags is a security feature that ensures the file hasn’t been tampered with. Always use the integrity hash provided by Bootstrap’s CDN for better security This will cause browsers to verify the file’s content against the hash.crossorigin="anonymous" attribute is used in conjunction with SRI to ensure the CDN asset can be fetched anonymously (without affecting user credentials) so the integrity check can be performed.Using the CDN approach is great for quick prototypes, simple static sites, or when you want to get started without any build process. As long as you include the links correctly, you can immediately use Bootstrap’s classes in your HTML. Just ensure you also include a meta viewport tag (<meta name="viewport" content="width=device-width, initial-scale=1"> as shown above) – this is required for Bootstrap’s responsive features to work correctly on mobile devices.
Example: In the code snippet above, after including the CDN links, we used some Bootstrap classes (container, text-center, btn, btn-primary). Once the CSS and JS are loaded, those classes automatically apply Bootstrap’s styling and behavior (for instance, the button gets styled with the primary theme color, and the container provides proper responsive margins).
For larger projects and more control, you’ll likely use NPM (Node Package Manager) to install Bootstrap locally. Using NPM fits into modern web development workflows where you manage front-end dependencies and bundle assets using tools like Webpack or Vite. This approach gives you the ability to customize Bootstrap (e.g., via Sass), better integrate with frameworks, and avoid external dependencies in production.
Installing Bootstrap via NPM: Ensure you have Node.js and NPM set up in your project. Then run:
npm install bootstrap
This will download the Bootstrap package into your project’s node_modules. (If your project uses Yarn, you can do yarn add bootstrap similarly.) The Bootstrap package includes the CSS (precompiled CSS and Sass source) and JS. By default, Bootstrap’s package does not include Popper, so if you plan to use components like tooltips, popovers, or dropdowns, you should also install Popper:
npm install @popperjs/core
Now that Bootstrap is installed, you need to incorporate it into your build. How this is done depends on your setup and build tools:
Using Import in JavaScript: If you have a bundler (Webpack, Vite, Parcel, etc.), you can import Bootstrap directly in your JS entry file. For example, in your main JavaScript file (e.g. index.js or main.js):
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap';
The first import brings in Bootstrap’s CSS into your bundle, and the second import loads Bootstrap’s JS plugins onto the page. When you import the "bootstrap" module, it will automatically load all of Bootstrap’s JavaScript plugins onto a global bootstrap object (Behind the scenes, this is equivalent to including the bootstrap bundle script.) If Popper is installed, it will be picked up for the components that need it. You can also choose to import specific plugins instead of everything, by importing individual files from bootstrap/js/dist/* as needed – this can slightly optimize your bundle if you only need some of the plugins
Including CSS via Sass: Alternatively, you might choose to import the Bootstrap Sass source in your own Sass file to customize it. Bootstrap’s package provides a Sass entry at node_modules/bootstrap/scss/bootstrap.scss. You could create a file (e.g. styles.scss) in your project with:
// Your custom variables overrides here (optional)
@import "bootstrap";
and then use your bundler’s Sass loader to compile it. This allows you to change Bootstrap’s default theme colors, spacings, etc., by setting Sass variables before the import. (Using Sass requires configuring your build with a Sass compiler, like sass-loader in Webpack.)
After importing, run your build (e.g., npm run build or npm run dev for webpack/vite setups). The output will include Bootstrap’s styles and scripts bundled with your own code.
If your project is using Webpack (for example, a project bootstrapped with Create React App or a custom Webpack setup), integrating Bootstrap via NPM is straightforward. Webpack treats CSS and JS imports as modules (with the right loaders configured). As shown above, you can import the CSS and JS in your entry file. Ensure that Webpack is configured to handle CSS—usually this means you have style-loader and css-loader set up for .css files. Most boilerplates do this by default. For example, Bootstrap’s documentation notes that to use the compiled CSS, you can simply add the import and use existing CSS loaders:
// index.js (entry file)
import 'bootstrap/dist/css/bootstrap.min.css';
“In this case you may use your existing rule for CSS without any special modifications to webpack config, except you don’t need
sass-loader—juststyle-loaderandcss-loader.”
If you also want Bootstrap’s JS, addimport 'bootstrap';as well (this will include the bundle). With those imports, when you run Webpack it will bundle the Bootstrap code into your output (e.g., into your app’s JS and CSS files).
Example: In a typical Webpack config, you might have something like:
// webpack.config.js snippet
module.exports = {
// ... entry, output, etc.
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'] // allows importing CSS
},
// ... other loaders like Babel for JS
]
}
};
With this in place, the import 'bootstrap/dist/css/bootstrap.min.css' line in your JS will cause Bootstrap’s CSS to be processed and injected into the page via the style-loader. Similarly, importing 'bootstrap' will include the JS. You don't need to manually include script tags in HTML; everything becomes part of your bundled files.
Vite is a modern build tool that offers fast bundling with ESM (modern JavaScript modules). Using Bootstrap with Vite is even simpler in some ways, because Vite supports CSS imports out of the box (no extra config needed for basic use). After installing Bootstrap via NPM, you can import it in your main application file:
// main.js (or main.ts for TypeScript)
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap';
This does the same as with Webpack – it pulls in the CSS and the JS. Vite will bundle these when you run it. Because Vite uses ESM and modern browser support, you don’t need additional polyfills or anything special. If you plan to customize Bootstrap via Sass, you can still do so by configuring Vite to use a Sass plugin or by just importing the compiled CSS as shown.
Behind the scenes, when you import Bootstrap’s JS in an ESM environment, Bootstrap will automatically import Popper from the installed @popperjs/core (if you installed it) for components that need it. The official Bootstrap Vite guide demonstrates creating a Sass entry point and configuring vite.config.js for Sass, but if you’re not customizing styles, the approach above (importing the pre-built CSS) is perfectly fine for using Bootstrap in a Vite project.
Development vs Production: When bundling via NPM for production, it’s good practice to minify and treeshake. Tools like Webpack and Vite handle this in production mode (removing unused JS, minifying code). For CSS, you might consider using a tool like PurgeCSS (or the built-in optimization in Vite or frameworks) to remove unused CSS classes from Bootstrap if your app only uses a subset. The Bootstrap team even provides a starter that includes PurgeCSS integration This can greatly reduce the final CSS size by stripping out classes you didn’t use.
Now that we’ve looked at both methods, let’s compare using Bootstrap via CDN versus using it via NPM (bundled locally) on a few key points:
Ease of Setup: Using a CDN is extremely simple – just drop in the <link> and <script> tags and you’re done. No build process is required. NPM requires setting up a Node.js project and a bundler, which is more involved. For a quick demo or a simple page, CDN is often the quickest way to get Bootstrap running For a complex app, the initial setup of NPM might be justified by other needs (like using a framework or custom build).
Performance & Caching: A CDN can leverage browser caching across websites. If a user has visited any site using the same Bootstrap CDN link, they may already have it cached, so your site will load it from cache (instant load) Also, CDNs serve files from servers geographically close to the user, potentially reducing latency. On the flip side, bundling Bootstrap via NPM means your users download it as part of your app’s own files – this could be one additional chunk in your build. If you combine your CSS/JS, you may reduce the number of HTTP requests (e.g., one big CSS file including Bootstrap + your styles), which can be good for performance, especially with HTTP/1.1. With HTTP/2, multiple small requests are handled in parallel, so the performance difference is minor. In summary, if the CDN is not cached, there’s a slight overhead in DNS and connection; if it is cached, it’s a win. With NPM, you have full control to optimize delivery (combine files, etc.). Both approaches can lead to excellent performance if used properly.
Reliability & Control: With local (NPM) bundling, you host Bootstrap yourself as part of your app. This means you are in control of the version and availability. With a CDN, you rely on a third-party host. CDNs are very reliable, but as one developer noted, “It is a resource you have no control over. Maybe they will clean up or remove resources... maybe the CDN is blocked for some users” For example, a corporate network might block certain CDN domains, or an outage at the CDN could impact your site’s CSS. If your project is an enterprise application or must run in a tightly firewalled environment, hosting Bootstrap yourself via NPM is usually preferred On the other hand, for public-facing sites, CDNs from reputable providers are generally dependable.
Security: When using a CDN, always use the HTTPS version of the links and include Subresource Integrity hashes This ensures that even though the file is hosted elsewhere, it hasn’t been modified maliciously. One concern with external resources is if the CDN were compromised or an attacker intercepts the request – SRI mitigates that by verifying the file content. With NPM, the Bootstrap code is part of your bundle, which users download from your server (or cloud hosting). This can simplify Content Security Policy (CSP) configurations since you’re not loading code from external domains. Both methods are secure if best practices are followed, but NPM gives you fewer external points of failure. (Also note: Bootstrap’s npm package is open source, but when you include it in your bundle, you should still monitor for security updates in case vulnerabilities are discovered – the same goes for CDN but you’d update the URL.)
Dependency Management: Using NPM shines for projects where you have multiple dependencies. Your package.json can lock the Bootstrap version, and you can manage upgrades in a controlled way. You also get the benefit of module bundlers that can do static analysis. As one developer commented, packaging via NPM “gives you dependency management, source control, static checks/analysis” With a CDN, you’re essentially just trusting an URL to point to the correct version. Upgrading means changing the URL to a new version (which is manual and easy to forget). With NPM, you can use tools like npm update and have consistent versions across your team.
Development Workflow: If you are building a web app with tools like React, Angular, or Vue (which typically use NPM), it’s most convenient to also bring Bootstrap in via NPM so it fits into the same build pipeline. This way, you can import Bootstrap in your code, and perhaps even import only parts of it (like specific SCSS or JS plugins). A CDN inclusion, by contrast, is outside of your application code – it just dumps global styles/scripts on the page. This could be fine for simple usage, but it doesn’t integrate with, say, a React component’s module scope. Using NPM also avoids polluting the global namespace; you can import what you need. In short, CDN is great for simple drop-in usage, NPM is better for integrated usage with a build step.
When to Choose What: A common guideline is to use CDN for quick prototypes, demos, or simple sites, and use NPM (or other package managers) for serious applications. “I’d recommend using CDN when you’re just playing around... but rely on packaging when you’re deploying to something important (production)” Another developer noted they use CDN for personal projects or proofs-of-concept, but for products that are shipped, they prefer to self-host via NPM In corporate or enterprise settings, there may also be policy reasons to not use external CDNs (concerns about uptime, compliance, or licensing). If your project requires a lot of customization of Bootstrap, the NPM route is definitely better, since you can tweak the source. If, however, you just need the default Bootstrap and want to drop it into a WordPress site or a static HTML page quickly, CDN is perfectly fine and very convenient.
To summarize the comparison: CDN is simple and leverages global caching, but gives up a bit of control. NPM (local bundling) gives you maximum control and integration at the cost of needing a build process. Both can be performant and secure if used properly. Often, the choice comes down to the project’s complexity and deployment environment. You can even start with a CDN link for speed during prototyping, then move to NPM as the project grows – the change is usually straightforward.
Bootstrap can be used in virtually any web stack. Let's look at how to integrate Bootstrap 5 in a few common scenarios and frameworks, and any special considerations for each.
If you’re working with plain HTML (no specific frontend framework), you can use either the CDN method or a local method:
Via CDN: As shown earlier, include the <link> and <script> tags in your HTML. This works for any static site or even a backend-rendered site (like a PHP, Ruby, or Python web page) – you just need to insert those tags in the rendered HTML. Once included, you can use Bootstrap classes in your HTML elements. For example:
<div class="container">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">SiteName</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarContent" aria-controls="navbarContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link active" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Link</a></li>
</ul>
</div>
</nav>
</div>
In this snippet, we use a Bootstrap 5 Navbar component. The classes and data-bs-* attributes will automatically be activated by Bootstrap’s JS (assuming the JS bundle is included at the bottom of the page). Using data-bs-toggle="collapse" and other data-bs- attributes is the standard way to trigger Bootstrap JS behavior in plain HTML (no additional JavaScript code needed for basic interactions).
Via Downloaded Files (Local without NPM): Another approach if you don’t want to use a CDN but also aren’t using NPM, is to download the Bootstrap files and include them locally. You can download the compiled CSS and JS from the Bootstrap website (or via npm download if you wish). You would then place the bootstrap.min.css and bootstrap.bundle.min.js files in your project directory (say, in a css/ and js/ folder). Then include them with local paths:
<link rel="stylesheet" href="css/bootstrap.min.css">
...
<script src="js/bootstrap.bundle.min.js"></script>
This way, you aren’t relying on an external CDN but also not using a package manager. It’s a manual approach, but works fine. Just remember that if you ever need to update Bootstrap, you’ll have to replace these files with the new version.
For plain HTML usage, a key best practice is to include the Bootstrap JS bundle if you use any interactive components (dropdowns, modals, accordions, tooltips, etc.). If you omit the JS, those components will not function. A common mistake is including only the CSS and then wondering why, for example, a collapse isn’t toggling or a modal isn’t opening. Include bootstrap.bundle.min.js (with Popper included) and those components will work. Also, ensure that script is placed after your HTML (usually right before </body>), so the elements exist by the time the script runs.
Another important practice: include the recommended viewport meta tag in your HTML <head> (as shown in the CDN example). Without <meta name="viewport" content="width=device-width, initial-scale=1">, the responsive grid and components won’t behave correctly on mobile devices.
You can use Bootstrap in React applications to style your components. There are two main ways to integrate Bootstrap with React: using the raw CSS/JS (just like any other CSS/JS library) or using a library of Bootstrap components for React (like React-Bootstrap or reactstrap). Here, we’ll focus on the former (raw integration), as it relates to the CDN vs NPM discussion.
Adding Bootstrap via NPM (recommended for React): If you started a React app with Create React App (CRA) or a similar tool, you already have a build system in place (Webpack). The simplest way to add Bootstrap is to install it and import the CSS in your React entry point:
npm install bootstrap (and optionally Popper via npm install @popperjs/core).src/index.js (or src/index.tsx if TypeScript). Add:
import 'bootstrap/dist/css/bootstrap.min.css';
This will include Bootstrap’s styles globally for your app
import 'bootstrap'; in your index.js. This will ensure components like modals or dropdowns work if you use them (e.g., via data attributes or by calling the Bootstrap JS API).After step 2 (importing the CSS), you can start using Bootstrap classes in your JSX. For example, you can write:
function App() {
return (
<div className="container py-5">
<h1 className="text-center">Welcome to my App</h1>
<button className="btn btn-success">Click Me</button>
</div>
);
}
Note: In JSX, use the attribute className instead of class to apply CSS classes, since class is a reserved word in JavaScript. This is a common React quirk – “use className as attribute instead of class” If you forget and use class, your styles won’t apply because React will ignore that attribute.
At runtime, those classNames will correspond to Bootstrap’s styles, so the above would render a centered heading and a green button with Bootstrap’s styling.
If you imported import 'bootstrap', then any <button> with data-bs-toggle="modal" etc., would also function because Bootstrap’s JS is initialized. However, in React you might often manage the state of components through React itself rather than data attributes. For example, you might not use data-bs-toggle="modal" at all, instead controlling a modal’s visibility through React state and possibly using a library like React-Bootstrap which provides <Modal> components.
Using Bootstrap via CDN in React: It’s also possible to just add the CDN links in the public HTML (for CRA, in public/index.html). For instance, you could add the Bootstrap CSS CDN link in the <head> of that file, and the bundle JS before </body>. The React app will then have Bootstrap loaded. This works, but is generally less ideal for React apps because it introduces an outside dependency (and you’d still need to ensure availability of the CSS when deploying). In development, CRA might not automatically inject those, so using imports is cleaner.
React-Bootstrap / Reactstrap (optional mention): Libraries like React-Bootstrap provide Bootstrap components as React components (e.g. <Button> component that renders a Bootstrap-styled button). These libraries still require Bootstrap’s CSS (you can use CDN or import as above for the CSS), but they manage the JS behavior via React. If you are using such a library, you typically wouldn’t import Bootstrap’s own JS (to avoid conflicts), but you still need the CSS. For the context of our topic: if you use React-Bootstrap, you’d still likely add Bootstrap via NPM for the CSS, or via CDN. The choice of CDN vs NPM for the CSS is similar – NPM import is often preferred in a React build.
Summary for React: Import Bootstrap CSS (and possibly JS) via your bundler. Use className to apply styles. Bootstrap integrates nicely for styling, but for complex components you might leverage React libraries or manually call Bootstrap’s JS APIs using refs if needed. The NPM approach is recommended for React apps because it aligns with the typical React project structure and build pipeline.
Vue.js (Vue 3) can use Bootstrap for styling just like any other project. With Vue, you also have a couple of options: using raw Bootstrap or a Vue-specific integration (like BootstrapVue for Vue 2, or BootstrapVue3 for Vue 3, which provide Vue components). Here we’ll describe using raw Bootstrap 5 in a Vue 3 project.
Assuming you have a Vue project (perhaps created with Vue CLI or Vite):
Install Bootstrap (and Popper) via NPM:
npm install bootstrap @popperjs/core
This installs the packages into your project.
Import Bootstrap in your main entry file. In Vue 3, that is typically src/main.js:
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
This will globally include Bootstrap’s CSS and JS in your app By doing it in main.js, you ensure it's loaded before your Vue app mounts.
Use Bootstrap classes in your Vue templates as needed, just as you would in plain HTML:
<template>
<div class="container mt-4">
<button class="btn btn-primary" data-bs-toggle="collapse" data-bs-target="#myCollapse">
Toggle Content
</button>
<div id="myCollapse" class="collapse">
<p>This content is collapsible.</p>
</div>
</div>
</template>
In this example (within a Vue component's template), we use a Bootstrap collapse. The data-bs-toggle="collapse" and data-bs-target="#myCollapse" attributes will be processed by Bootstrap’s JS (which we imported in main.js) to make the <div id="myCollapse"> collapse when the button is clicked. Vue itself doesn’t interfere with these attributes – they work as if it were plain HTML.
Because Bootstrap 5’s JS has no jQuery dependency, it can run alongside Vue without issues. The approach above leverages Bootstrap’s own scripts to handle the interactive parts (via the data attributes). Alternatively, you could explicitly use Bootstrap’s JS APIs in Vue’s lifecycle hooks if needed (for example, using import { Modal } from 'bootstrap'; to programmatically control a modal component).
Using CDN in Vue: If you prefer not to bundle, you could include CDN links in the index.html file of your Vue project (if using Vue CLI, in public/index.html). But when using a build tool, it’s usually just as easy to use NPM. CDN might be used if you are adding Bootstrap to a simple Vue app via a <script> include of Vue (like using Vue from CDN and Bootstrap from CDN in a single HTML page), but for single-file-component projects, bundling is easier.
BootstrapVue: It’s worth noting that for Vue 3, a community project BootstrapVue3 is under way (BootstrapVue for Vue 2 was popular for Bootstrap 4, providing Vue components). If you use that, it abstracts some of this – but as of Bootstrap 5, many are just using Bootstrap directly or using headless UI libraries. In most cases, adding the CSS and using classes is sufficient.
Vue integration summary: Install via NPM, import in main.js, then use classes or data attributes. This simple approach is effective – for example, a Stack Overflow answer demonstrates that after importing, “the simplest way to use Bootstrap components is via the data-bs- attributes” on your elements, which Bootstrap’s JS will respond to.
Angular (particularly Angular 12+ which is modern Angular, not to be confused with AngularJS) can also use Bootstrap. There are two primary ways: including Bootstrap’s CSS/JS in the Angular project, or using Angular-specific Bootstrap libraries like ng-bootstrap or NGX Bootstrap which provide Angular components.
To include Bootstrap directly in an Angular (CLI) project, you typically do the following:
Install Bootstrap via NPM:
npm install bootstrap @popperjs/core
(Popper for completeness, though if you use only the bundle, popper is included in it.)
Add Bootstrap’s CSS to your Angular build. Angular CLI projects have an angular.json file where global styles and scripts are defined. You can add the Bootstrap files there:
// angular.json snippet
{
...,
"projects": {
"your-app": {
...,
"architect": {
"build": {
"options": {
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
"scripts": [
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
]
},
...
}
In the above, we add the Bootstrap CSS to the styles array and the Bootstrap bundle JS to the scripts array (Angular will then include these in the final build automatically.) With this, Bootstrap’s styles are global in your app, and the JS bundle runs at startup.
Alternatively, instead of editing angular.json, you could import Bootstrap’s CSS in your global styles.scss and include the script in index.html. For example, in styles.scss:
@import "~bootstrap/dist/css/bootstrap.min.css";
and in src/index.html add the script:
<script src="node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
But the angular.json method is recommended because it ensures Angular knows about these assets and can bundle them appropriately or inject them. The Angular CLI build will place the CSS into the global styles bundle and the JS into the scripts bundle.
Once Bootstrap is included, you can use its classes in your Angular component templates just like normal HTML. Angular’s templating does not conflict with Bootstrap classes. For example, in an Angular component template you can do:
<div class="card">
<div class="card-body">
<h5 class="card-title">Hello Angular</h5>
<p class="card-text">This is styled with Bootstrap 5.</p>
<button class="btn btn-primary" (click)="doSomething()">Click</button>
</div>
</div>
The (click)="doSomething()" is Angular’s way of binding a click event, which can coexist on a Bootstrap-styled button without issue.
Angular and Bootstrap JS: One thing to consider is that Bootstrap’s JS is imperative, while Angular prefers a declarative, data-driven approach. If you include the bundle as above, things like a dropdown or modal triggered by data attributes will work, but managing them via Angular could be tricky. For example, if you want to open a modal from an Angular component, you might end up calling Bootstrap’s JS methods or using jQuery (not recommended). Instead, many Angular devs choose ng-bootstrap (the Angular library for Bootstrap, which does not depend on Bootstrap’s JS or jQuery; it reimplements the components in Angular). If you use ng-bootstrap, you would not include the bootstrap.bundle.js at all (ng-bootstrap takes care of the behavior) but you still use Bootstrap’s CSS.
So, if you just want to use the CSS and maybe simple data attributes, the direct include approach works. If you want deeper integration (like controlling modals via Angular), consider installing ng-bootstrap: ng add @ng-bootstrap/ng-bootstrap which will set up Bootstrap’s CSS and give you components.
Using CDN in Angular: If you have no build constraints, you could include Bootstrap CDN links in index.html of the Angular app. This is similar to including any external library. But generally, since Angular already has a build process, it’s cleaner to manage Bootstrap as an NPM dependency.
In summary for Angular:
angular.json as shown above will load the files (ensure they are in the "build:options" section, not mistakenly in "test" or elsewhere .ViewChild to get a reference to an element and then calling new bootstrap.Modal(element) in code). This is an advanced use case though.WordPress is a hugely popular CMS, and many WordPress themes utilize Bootstrap for layout and components. You can integrate Bootstrap into a WordPress theme in a couple of ways:
Using CDN in a Theme: The quickest way in a WordPress theme or plugin is to enqueue the Bootstrap CDN links. In your theme’s functions.php, you can add something like:
function mytheme_enqueue_bootstrap() {
// Bootstrap CSS from CDN
wp_enqueue_style('bootstrap-css', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css');
// Bootstrap JS (Bundle) from CDN
wp_enqueue_script('bootstrap-js', 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js', array(), null, true);
}
add_action('wp_enqueue_scripts', 'mytheme_enqueue_bootstrap');
This PHP code uses WordPress’s wp_enqueue_style and wp_enqueue_script functions to include the Bootstrap assets We specify 'bootstrap-css' and 'bootstrap-js' as handles, give the CDN URL, and in the script enqueue we pass true as the last argument to load it in the footer (after the body, which is typically what we want for JS). We did not list any dependencies in the wp_enqueue_script (the array is empty here) because Bootstrap 5’s bundle doesn’t require jQuery (for Bootstrap 4 you would put array('jquery') to ensure jQuery loads first, but with v5 this isn’t necessary unless other scripts depend on jQuery).
Once enqueued, WordPress will output the <link> and <script> tags in the appropriate place. After that, you can use Bootstrap classes in your theme’s template files (PHP files with HTML). For example, in a template you could have <div class="container"> ... </div> and it will be styled by Bootstrap. This method is very straightforward.
Bundling Bootstrap with a Theme (Local files): Some theme developers prefer to include the Bootstrap files in the theme itself (so it doesn’t rely on an external CDN and can be packaged offline). In this case, you would download Bootstrap (or use npm in your development workflow to get it) and put the bootstrap.min.css and bootstrap.bundle.min.js files in your theme directory, perhaps in assets/css/ and assets/js/. Then you enqueue them with wp_enqueue_style and wp_enqueue_script using get_template_directory_uri() to point to those files:
function mytheme_enqueue_bootstrap_local() {
// Local Bootstrap CSS
wp_enqueue_style('bootstrap-css', get_template_directory_uri() . '/assets/css/bootstrap.min.css');
// Local Bootstrap JS
wp_enqueue_script('bootstrap-js', get_template_directory_uri() . '/assets/js/bootstrap.bundle.min.js', array(), null, true);
}
add_action('wp_enqueue_scripts', 'mytheme_enqueue_bootstrap_local');
This assumes you’ve placed the files in those directories. Now Bootstrap is part of your theme. The advantage is you’re not dependent on a CDN, and you can control the version by updating the files. The disadvantage is the user might not have it cached, and it slightly increases your theme size. Many premium themes include Bootstrap in this manner.
With WordPress, you should avoid directly linking scripts in the header or footer manually; using wp_enqueue_script/style is the proper method (it prevents conflicts, allows WordPress to manage dependencies, and can avoid duplicate loading).
If you’re not developing a custom theme but just want to add Bootstrap to a WordPress site, you could use a plugin or add the CDN links in the theme settings if available. There are plugins that specifically enqueue Bootstrap for you. But if you can edit theme files, the above methods are quite straightforward.
Using Bootstrap in WordPress content: Once Bootstrap is loaded by the theme, you can also use Bootstrap classes in the WordPress post content (in the editor) if you’re using the Classic Editor or a custom HTML block in Gutenberg. For example, you could add <div class="alert alert-success">Hello</div> in the post HTML and it would be styled as a Bootstrap alert on the front-end. Just be cautious that not all content editors allow all classes, and ensure that the CSS is indeed loaded on pages where content is shown (the theme usually enqueues globally).
WordPress and jQuery: By default, WordPress supplies jQuery to themes, and many themes use it. For Bootstrap 5, jQuery is not needed. You might still see some theme code enqueuing Bootstrap’s JS with array('jquery') as a dependency – this was a pattern from Bootstrap 4 to ensure jQuery loaded first. In Bootstrap 5, it’s safe to drop that, as we did in our example (we passed an empty dependency array). Removing jQuery if not needed can slightly improve performance. However, if other parts of the theme do need jQuery (very common in WP), you can leave it as a dependency or otherwise ensure jQuery is loaded. It won’t harm Bootstrap 5, it’s just not utilized by it.
WordPress Example: If you had the enqueue function as above in your functions.php, after loading the site, you could press F12 (DevTools) and see <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" /> in the head and the script tag in the footer. Then, you can use components. For instance, in a theme template:
<div class="container">
<h1><?php the_title(); ?></h1>
<p class="lead">Welcome to my Bootstrap-powered theme.</p>
<button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#demoCollapse">
Toggle Details
</button>
<div id="demoCollapse" class="collapse">
<div class="card card-body">
This content is revealed by Bootstrap's collapse component.
</div>
</div>
</div>
This would output a button and a collapsible card. Thanks to the enqueued Bootstrap JS, the collapse toggling would work on click.
In WordPress, using Bootstrap is very common and many starter themes like _underscores or others have variants that include Bootstrap. Just ensure you don’t accidentally load Bootstrap twice (for example via a plugin and your theme). That could cause conflicts or unnecessary bloat.
When setting up and using Bootstrap 5, here are some best practices to follow and pitfalls to avoid:
Choose One Integration Method: Do not mix CDN and local installs in the same project. For example, if you enqueue Bootstrap via NPM in an Angular app, don’t also include a CDN link in the HTML. This could lead to conflicts or duplicated code loading. Pick one approach and stick with it for consistency.
Keep Bootstrap Updated: Whether using CDN or NPM, use a relatively recent version of Bootstrap 5 and monitor for updates (especially minor releases that fix bugs/security issues). With CDN, update the URL when a new version comes out. With NPM, update your package version and rebuild. Using a slightly older version (like 5.1 vs 5.2) usually isn’t a huge issue, but staying updated means you get the latest features and fixes.
Include Required JS: As mentioned, a very common pitfall is forgetting the JavaScript. Bootstrap’s CSS will style things, but without the JS, components that require interactivity will not function. Ensure that the bootstrap.bundle.min.js (which includes Popper) is included, or if using module imports, that you import 'bootstrap' somewhere so the JS is executed. Missing this will cause things like dropdown menus or modals to do nothing when clicked, which can be frustrating until you realize what’s wrong. In the context of separate scripts, remember the rule: if not using the bundle, include Popper first, then Bootstrap’s JS If using the bundle or module import, this is handled for you. Also, only include one copy of Bootstrap JS – another mistake is accidentally including the bundle twice (e.g., via CDN and via a script tag in a theme).
Placement and Order: Load the Bootstrap CSS before your own custom CSS (unless you intentionally want to override Bootstrap with higher specificity). This ensures Bootstrap styles apply, and you can override them in your own CSS if needed. As for JS, load Bootstrap’s JS after any libraries it depends on (Popper, though in v5 Popper is included in bundle or imported) and generally after the HTML content. If you have other scripts that rely on Bootstrap (for example, a custom script that triggers a modal), ensure Bootstrap’s JS is loaded before those.
Using the Grid Correctly: Utilize the Bootstrap grid and container classes as intended. A common beginner mistake is forgetting to wrap .row elements inside a .container (or .container-fluid), which can lead to unexpected alignment issues. Also, ensure that direct children of .row have .col-* classes. Misusing the grid can result in broken layouts. Following the grid documentation will save a lot of headache. Ignoring the grid system is considered a common mistake – always start with a container, then rows, then columns for proper structure.
Customizing Bootstrap: Bootstrap is designed to be customized, but do it in the right way. Best practice is not to edit Bootstrap’s core files (don’t modify bootstrap.min.css directly). Instead, override styles in a separate CSS file or better, use Sass to change variables and recompile. If you just need a few tweaks, you can add your own stylesheet after Bootstrap’s CSS to override specific classes. Use equal or higher specificity selectors to override (or CSS variables provided by Bootstrap). For larger theme changes, use the Sass source: e.g., set $primary: #yourColor; @import "bootstrap";. This way, upgrading Bootstrap is easier (since you aren’t maintaining a fork). A pitfall is sprinkling too many !important in your overrides – try to avoid that by understanding CSS specificity. Also, if you find yourself overriding a lot, consider whether you should simply use a different Bootstrap theme or modify the Sass variables.
Not Every Site Should Look "Bootstrap-y": Bootstrap’s default look is recognizable. It’s not a mistake per se, but be aware you can customize it to match your brand. Adjust the color scheme (via the Sass variables or using Bootswatch themes or custom CSS) so that your site doesn’t look like a stock Bootstrap template unless that’s what you want. Using default styles without any customization can make your site look generic A little custom CSS can go a long way to give uniqueness while still leveraging Bootstrap’s framework.
Utility Classes vs Semantic HTML: Bootstrap provides tons of utility classes (spacing, text colors, flexbox helpers, etc.). They are convenient, but don’t overuse them to the point your HTML is cluttered with dozens of classes. Balance using Bootstrap’s classes with writing your own small CSS when appropriate. For example, adding 5 different margin/padding utility classes on an element might be better served by a single custom CSS class in some cases (for maintainability). Keep your markup readable.
Testing and Responsiveness: Test your layout on different screen sizes. Bootstrap makes it easy to be responsive, but you should still verify that your content works on mobile, tablet, etc. Sometimes a combination of classes may not produce exactly what you expect on a smaller breakpoint. Use your browser’s dev tools to simulate smaller screens, and adjust your use of grid breakpoints (col-, col-md-, etc.) as needed. Also test across browsers, though Bootstrap itself is thoroughly tested on modern browsers, your usage of it might need tweaks.
Accessibility: Bootstrap 5 is generally good with accessibility (e.g., it leverages proper ARIA attributes in components), but the responsibility also lies with you. Ensure that if you use components like dropdowns, you structure them according to Bootstrap’s examples (they often include aria-haspopup, aria-expanded, etc., in the example markup). If you modify components or create custom ones, maintain semantic HTML for accessibility. Don’t remove focus outlines without providing an alternative, for example. Using Bootstrap doesn’t automatically guarantee your site is fully accessible – follow best practices (like using proper tags for lists, using labels on forms, etc.).
Avoid Conflicts with Other Libraries: If your project uses multiple CSS/JS frameworks, be careful about conflicts. For instance, using Bootstrap alongside another CSS framework (like Foundation or Tailwind) can lead to style conflicts (common class names, etc.). If you must, namespace one of them or limit scope. With JS, avoid including multiple versions of jQuery/other libs that could clash. In WordPress, for example, if a theme and a plugin both include different Bootstrap versions, things might break or styles override each other unpredictably. Ideally, standardize on one version of Bootstrap in a given project.
Popper and other dependencies: While Bootstrap 5 dropped jQuery, Popper is still needed for tooltip and popover positioning (and dropdowns for placement). If you use those, ensure Popper is included. The Bootstrap bundle includes it, so use that to simplify. If you find a tooltip isn’t positioning, it likely means Popper wasn’t loaded. This is solved by using the bundle or the module import (which auto-imports Popper) Also note that Bootstrap 5’s dropdowns, modals, etc., use native DOM events under the hood. If you are using a framework like React, you may sometimes need to tell React to not interfere (for example, using ref to access a DOM node to initialize a Bootstrap JS plugin).
Using the Right Version of Bootstrap Docs: Ensure you’re looking at Bootstrap 5 documentation when implementing. A pitfall for some is accidentally following Bootstrap 4 or 3 examples when using Bootstrap 5, which might have different class names or attributes. (For instance, in Bootstrap 5, the data attributes changed from data-toggle to data-bs-toggle to avoid conflicts ) Using mismatched code can lead to things not working. So double-check that the snippets you copy are for v5.
Purge Unused CSS in Production: If you use only a fraction of Bootstrap’s features and are concerned about performance, consider removing unused styles in production. Tools like PurgeCSS can scan your HTML/JSX and remove Bootstrap classes that aren’t used. Bootstrap’s CSS is around ~150-200KB (minified) which is not terrible, but trimming it can improve load time on slow connections. Just be careful to configure these tools correctly so they don’t remove classes that are used dynamically (like via JS). This is an optional optimization but worth mentioning as a best practice for large apps.
Debugging Tips: If something isn’t looking right:
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com