Components

Navbar, cards, modals and forms with Bootstrap 5, built entirely on vanilla JavaScript with no jQuery required.

HTML
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
    <div class="container-fluid">
        <a class="navbar-brand" href="#">NOA Labs</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navMenu">
            <ul class="navbar-nav ms-auto">
                <li class="nav-item"><a class="nav-link active" href="/">Home</a></li>
                <li class="nav-item"><a class="nav-link" href="/tutorials">Tutorials</a></li>
                <li class="nav-item"><a class="nav-link" href="/pricing">Pricing</a></li>
            </ul>
        </div>
    </div>
</nav>
  • navbar-expand-lg — the navbar collapses into a hamburger menu below the lg breakpoint, and expands into a horizontal bar from lg up.
  • data-bs-toggle="collapse" — Bootstrap 5's JavaScript components are driven entirely through data-bs-* HTML attributes, no manual JavaScript wiring required, and no jQuery involved.
  • ms-auto ("margin-start: auto") pushes the nav links to the right edge.

Cards

HTML
<div class="card" style="width: 18rem;">
    <img src="course-thumbnail.jpg" class="card-img-top" alt="">
    <div class="card-body">
        <h5 class="card-title">CSS Grid Deep Dive</h5>
        <p class="card-text">Learn two-dimensional layouts from the ground up.</p>
        <a href="/tutorials/css/grid" class="btn btn-primary">Start learning</a>
    </div>
</div>

A row of equal-width cards using the grid system:

HTML
<div class="row row-cols-1 row-cols-md-3 g-4">
    <div class="col">
        <div class="card h-100">
            <div class="card-body">
                <h5 class="card-title">HTML</h5>
                <p class="card-text">Structure and semantics.</p>
            </div>
        </div>
    </div>
    <div class="col">
        <div class="card h-100">
            <div class="card-body">
                <h5 class="card-title">CSS</h5>
                <p class="card-text">Layout and styling.</p>
            </div>
        </div>
    </div>
    <div class="col">
        <div class="card h-100">
            <div class="card-body">
                <h5 class="card-title">JavaScript</h5>
                <p class="card-text">Interactivity and logic.</p>
            </div>
        </div>
    </div>
</div>

row-cols-md-3 sets three equal cards per row from the md breakpoint up, and h-100 on each card makes every card in the row match the tallest one.

Modals (vanilla JS in Bootstrap 5)

HTML
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#confirmModal">
    Delete account
</button>

<div class="modal fade" id="confirmModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Are you sure?</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                This will permanently delete your account. This action cannot be undone.
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
                <button type="button" class="btn btn-danger">Delete</button>
            </div>
        </div>
    </div>
</div>

In Bootstrap 4, triggering a modal from JavaScript required jQuery ($('#myModal').modal('show')). In Bootstrap 5, everything is either driven declaratively with data-bs-* attributes (no JS needed at all, as above) or through the vanilla JS API directly:

Javascript
const modalEl = document.getElementById('confirmModal');
const modal = new bootstrap.Modal(modalEl);
modal.show();

Forms

HTML
<form>
    <div class="mb-3">
        <label for="email" class="form-label">Email address</label>
        <input type="email" class="form-control" id="email" placeholder="name@example.com">
    </div>

    <div class="mb-3">
        <label for="plan" class="form-label">Plan</label>
        <select class="form-select" id="plan">
            <option>Free</option>
            <option>Pro</option>
        </select>
    </div>

    <div class="form-check mb-3">
        <input class="form-check-input" type="checkbox" id="terms">
        <label class="form-check-label" for="terms">I agree to the terms</label>
    </div>

    <button type="submit" class="btn btn-primary">Sign up</button>
</form>
  • .form-control — the base class for text-like inputs and textareas.
  • .form-select — styles a native <select> consistently with the rest of the form.
  • .form-check / .form-check-input / .form-check-label — the trio needed for a correctly-aligned checkbox or radio.
  • .mb-3 — a spacing utility (margin-bottom) commonly used to separate form groups vertically.

Common mistakes

  • Forgetting tabindex="-1" and the required inner structure (.modal-dialog.modal-content.modal-header/.modal-body/.modal-footer) on a modal — Bootstrap's modal JS expects this exact nesting to position and trap focus correctly.
  • Writing raw <input class="form-control"> without the .mb-3 (or similar) spacing utilities between fields, resulting in cramped forms — Bootstrap's form components don't add their own vertical spacing by default.
  • Assuming Bootstrap 5 still needs jQuery for interactive components — it doesn't; loading jQuery alongside Bootstrap 5 is unnecessary unless something else in the project specifically requires it.