🔥 4 dead simple ways of customizing Bootstrap
Tags: css, webdev, beginners, bootstrap
Published: 2023-12-05 04:12:51

In this article, I'll demonstrate various techniques for customizing Bootstrap themes, whether for projects using only CSS or those utilizing Sass.

## Table of Contents
- [My project uses just HTML and CSS](#htmlecss)
  - [I'm using Bootstrap 5](#htmlecssbs5)
  - [I'm using Bootstrap 4](#htmlecssbs4)
    - [Using modern CSS](#mod)
- [My project uses Sass](#sass)
  - [I'm using Bootstrap 4 or 5](#sass5)
- [Could it be better](#better)

<br />

---

<br />

## My project uses just HTML and CSS <a id="htmlecss" href="#htmlecss">&#128279;</a>
<small>And I used a `<link>` to include `bootstrap.min.css` in my HTML</small>

&nbsp;

### I'm using Bootstrap 5 <a id="htmlecssbs5" href="#htmlecss">&#128279;</a>

Bootstrap 5 uses CSS variables to style its components. The base variables are in `:root`, and the specific component ones are declared within them. For instance, `.btn-primary`:

```css
.btn-primary {
  --bs-btn-color: #fff;
  --bs-btn-bg: #0d6efd;
  --bs-btn-border-color: #0d6efd;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: #0b5ed7;
  --bs-btn-hover-border-color: #0a58ca;
  --bs-btn-focus-shadow-rgb: 49, 132, 253;
  --bs-btn-active-color: #fff;
  --bs-btn-active-bg: #0a58ca;
  --bs-btn-active-border-color: #0a53be;
  --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
  --bs-btn-disabled-color: #fff;
  --bs-btn-disabled-bg: #0d6efd;
  --bs-btn-disabled-border-color: #0d6efd;
}
```

&nbsp;

You can create your own CSS variables representing the new colors of this theme. Despite being many variables, they follow a repetition pattern.

![Creating new variables based on existing ones](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tgglmohy31iuummpgya7.png)

&nbsp;

To do this, simply create a new style sheet just below the Bootstrap one. The CSS gives preference to the one loaded last:

```html
<!-- Bootstrap stylesheet -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- Your stylesheet -->
<link rel="stylesheet" href="style.css" />
```

&nbsp;

Then, adjust their values as desired, preferably using your default variables. This way, you can replicate them across other elements using the same theme.

```css
.btn-primary {
  --bs-btn-color: var(--primary-text-base);
  --bs-btn-bg: var(--primary-bg-base);
  --bs-btn-border-color: var(--primary-border-base);
  --bs-btn-hover-color: var(--primary-text-base);
  /* ... etc ... */
}
```

&nbsp;

### I'm using Bootstrap 4 <a id="htmlecssbs4" href="#htmlecss">&#128279;</a>

With pure CSS, you can utilize specificity to override class content. Bootstrap classes function as utility classes, without co-dependency, having a specificity of `0.0.1.0`, allowing them to be overridden by another class declared later in the code.

> 💡 If specificity is still a mystery to you, I recommend [this article on specificity and cascade by Amelia Wanttenberger](https://2019.wattenberger.com/blog/css-cascade).

&nbsp;

Bootstrap classes have a base class containing properties common to their variants and another containing properties specific to their variants.

{% collapsible Example %}

```css
.alert {
  position: relative;
  padding: 0.75rem 1.25rem;
  margin-bottom: 1rem;
  border: 1px solid transparent;
  border-radius: 0.25rem;
}

.alert-primary {
  color: #004085;
  background-color: #cce5ff;
  border-color: #b8daff;
}
```
{% endcollapsible %}

Knowing this, you can create a class with a namespace, e.g., `.custom-alert-primary`, with styles overriding the `.alert` theme.

Example:

```html
<div class="alert custom-alert-primary" role="alert">
  A simple primary alert—check it out!
</div>
```

&nbsp;

**◾Using modern CSS** <a id="mod" href="#mod">&#128279;</a>

We can utilize cascade layers to separate Bootstrap and CSS into different layers, giving more priority to the layer with authored code.

Below is an example by Stephanie Eckles using Bootstrap [from Smashing Magazine](https://www.smashingmagazine.com/2022/01/introduction-css-cascade-layers/#defining-cascade-layers):

```css
@layer bootstrap, base, application;

@import url(bootstrap.css) layer(bootstrap);

@layer base {
  body {...}
  .alert {...}
  .btn-primary {...}
}
```

&nbsp;

The priority using `@layer` is defined from left to right, from least to most priority, ensuring that your styles' specificity remains higher than Bootstrap's.

CSS Layers have a global compatibility of 93%, [according to Caniuse data](https://caniuse.com/css-cascade-layers).

| Chrome | Edge | Firefox | Safari |
| --- | --- | --- | --- |
| 99 | 99 | 97 | 15.4 |

<br />

---

<br />


## My project uses Sass <a id="sass" href="#sass">&#128279;</a>
<small>And I used `@import "bootstrap"` to set up Bootstrap</small>

&nbsp;

### I'm using Bootstrap 4 or 5 <a id="sass5" href="#sass5">&#128279;</a>

The [Customize &rarr; Variable Defaults chapter of Bootstrap 5 documentation](https://getbootstrap.com/docs/5.3/customize/sass/#variable-defaults) shows that it's possible to redeclare configuration variables from the `variables.scss` file directly in your import file (usually `index.scss`). The procedure is similar for Bootstrap 4, but ensure you check your version's documentation for declared variables and their usage.

```scss
// Requerido
@import "../node_modules/bootstrap/scss/functions";

/* Sobrescreve os valores padrão das variáveis padrão */
$body-bg: #000;
$body-color: #111;

@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/variables-dark";

/* Remove do objeto $theme-colors do arquivo
variables.scss as chaves de 'info', 'light' e 'dark' */
$theme-colors: map-remove($theme-colors, "info", "light", "dark");

@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";

// Componentes opcionais
@import "../node_modules/bootstrap/scss/reboot";
@import "../node_modules/bootstrap/scss/type";
// etc
```

&nbsp;

For customization, variables declared in the Bootstrap source code are marked with the `!default` flag. This means that if you declare a Bootstrap variable **before** `variables.scss`, it won't be overwritten, keeping your alteration as the default value.

> The `!default` flag allows a variable to be created only if it doesn't exist yet. For more details, [refer to the Sass documentation on default values](https://sass-lang.com/documentation/variables/#default-values).

<br />

---

<br />


## Could it be better <a id="better" href="#better">&#128279;</a>
<small>Wow, but is it more work than Tailwind!?</small>

Yes, definitely, but they serve different purposes. Bootstrap is used by [21% of sites surveyed by W3Techs](https://w3techs.com/technologies/details/js-bootstrap), with over [6 million weekly downloads, according to npm's website](https://www.npmjs.com/package/bootstrap). Since its inception in 2011, Bootstrap has been fundamental in setting standards and concepts that changed the way we do front-end today.

Being found in pure HTML/CSS sites, WordPress pages in PHP, or SPAs built with modern frameworks, Bootstrap's framework development focus was on **retro-compatibility and robustness**.

Incorporating a compilation step as Tailwind does with PostCSS wouldn't be feasible, as it would make the project dependent on a build tool like Webpack, Rollup, or even Vite in every project, which isn't always necessary.

Another point is that despite using JavaScript, if its functionalities aren't needed, it's extremely opt-in, allowing Bootstrap to be used independently of technologies, even in pure HTML/CSS projects.