Using only Bootstrap 5 dropdown

Programming
Published on November 4, 2024

Introduction

In a certain project, UI components were already prepared, but a dropdown list was missing.

  • We want to use Bootstrap's Dropdown.
  • We do not want to use other Bootstrap components.
  • Bootstrap version is 5.3.

The reason for wanting to use Bootstrap's Dropdown is that it automatically adjusts the display position of the list (up or down, and also left or right) so that it doesn't go off-screen when scrolled. Reimplementing this functionality from scratch would be quite cumbersome 1, so we wanted to quickly introduce Bootstrap's Dropdown. However, there was a case where we didn't need other Bootstrap components, so this article introduces the steps to introduce Bootstrap's Dropdown only.

We will use React (TypeScript + Vite) as an example.

1Installing Bootstrap

npm install bootstrap

The source files for Dropdown are the following two:

  • node_modules/bootstrap/js/dist/dropdown.js
  • node_modules/bootstrap/scss/_dropdown.scss

2Importing dropdown.js

Import dropdown.js.

// main.tsx
import 'bootstrap/js/dist/dropdown.js'

For the HTML, we used the sample code from Dropdowns · Bootstrap v5.3 as is.

// app.tsx
function App() {
    return (
        <div className="dropdown">
            <button className="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                Dropdown button
            </button>
            <ul className="dropdown-menu">
                <li><a className="dropdown-item" href="#">Action</a></li>
                <li><a className="dropdown-item" href="#">Another action</a></li>
                <li><a className="dropdown-item" href="#">Something else here</a></li>
            </ul>
        </div>
    )
}

export default App

Since no styles are specified, the list is visible in its initial display state (Figure 1.).

Figure 1. List is visibleFigure 1. List is visible

However, the dropdown functionality is complete, and control is also in place to prevent the list from going off-screen.
While it's possible to create custom styles, here we'll apply Bootstrap's styles.

3Installing Sass (scss)

Install Sass for Vite to build scss files.

npm install --save-dev sass

Let's reference _dropdown.scss.

// main.tsx
import 'bootstrap/js/dist/dropdown.js'
import 'bootstrap/scss/_dropdown.scss'

When executed, the following error occurs:

[plugin:vite:css] [sass] Undefined mixin.
   ╷
15 │   @include caret();
   │   ^^^^^^^^^^^^^^^^
   ╵
  node_modules\bootstrap\scss\_dropdown.scss 15:3  root stylesheet

The reason is that _dropdown.scss is not intended to be used alone, but rather with other scss files imported.

4Creating an scss file

Create a new scss file that imports other necessary files so that the build passes.
The file name is src/dropdown.scss.

// src/dropdown.scss
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/dropdown";

With these 4 files, the build will now pass.
When executed, it will look like this (Figure 2.).

Figure 2. List is hiddenFigure 2. List is hidden


Clicking the button displays the list (Figure 3.).

Figure 3. List displayed on clickFigure 3. List displayed on click


If you reduce the browser size, the list appears above.
This is the expected behavior, but you can see that the list background is transparent (Figure 4.).

Figure 4.Figure 4.


Add root and maps.

// src/dropdown.scss
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/dropdown";

Now the list has a background (and border) set (Figure 5.).

Figure 5.Figure 5.


The button has btn btn-secondary specified.
To apply Bootstrap's button styles, add buttons.

// src/dropdown.scss
@import "../node_modules/bootstrap/scss/functions";
@import "../node_modules/bootstrap/scss/variables";
@import "../node_modules/bootstrap/scss/maps";
@import "../node_modules/bootstrap/scss/mixins";
@import "../node_modules/bootstrap/scss/root";
@import "../node_modules/bootstrap/scss/buttons";
@import "../node_modules/bootstrap/scss/dropdown";

Figure 6. Applying styles to the buttonFigure 6. Applying styles to the button

Now it will have the exact same design as Bootstrap.

Applying Custom Styles

You can also apply your own styles without using Bootstrap's scss files.

When the list is displayed, the show class is set on dropdown-menu, so you can toggle its visibility based on that.

// src/dropdown.scss
.dropdown-menu {
    display: none;

    &.show {
        display: block;
        background: white;
        border: 1px solid gray;
 
        li {
            list-style: none;
            text-align: left;
        }
    }
}

Although minimal styles are specified, it will look like the following (Figure 7.).

Figure 7. Result of applying custom stylesFigure 7. Result of applying custom styles

From here, you can further refine it to your preferred style.

Footnotes

  1. Bootstrap reportedly achieves this using a library called Popper.js.