Tooltips and Offcanvas in Bootstrap 5
Tooltips provide helpful hints and information when users hover over elements. Offcanvas is a powerful component introduced in Bootstrap 5 for creating sidebar panels and drawers that slide in from the edge of the viewport.
Tooltip Basics
Tooltips display small text overlays that appear on hover, focus, or click.
<!-- Basic Tooltip -->
<button type="button" class="btn btn-secondary"
data-bs-toggle="tooltip"
data-bs-title="This is a tooltip">
Hover Over Me
</button>
<!-- Initialize all tooltips -->
<script>
// Tooltips must be initialized
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl));
</script>
Important: Like popovers, tooltips require JavaScript initialization to work. Always include the initialization script.
Tooltip Directions
Control tooltip placement with data-bs-placement attribute.
<!-- Top (default) -->
<button type="button" class="btn btn-primary"
data-bs-toggle="tooltip"
data-bs-placement="top"
data-bs-title="Tooltip on top">
Tooltip on Top
</button>
<!-- Right -->
<button type="button" class="btn btn-success"
data-bs-toggle="tooltip"
data-bs-placement="right"
data-bs-title="Tooltip on right">
Tooltip on Right
</button>
<!-- Bottom -->
<button type="button" class="btn btn-warning"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-title="Tooltip on bottom">
Tooltip on Bottom
</button>
<!-- Left -->
<button type="button" class="btn btn-danger"
data-bs-toggle="tooltip"
data-bs-placement="left"
data-bs-title="Tooltip on left">
Tooltip on Left
</button>
Tooltip Customization
Customize tooltip appearance and behavior with JavaScript options.
<!-- HTML Content in Tooltip -->
<button type="button" class="btn btn-info"
data-bs-toggle="tooltip"
data-bs-html="true"
data-bs-title="<em>HTML</em> <strong>content</strong>">
Tooltip with HTML
</button>
<!-- Custom Trigger -->
<button type="button" class="btn btn-secondary"
data-bs-toggle="tooltip"
data-bs-trigger="click"
data-bs-title="Click to show">
Click Trigger
</button>
<!-- JavaScript Configuration -->
<script>
const tooltip = new bootstrap.Tooltip(element, {
animation: true, // Enable fade animation
delay: { show: 500, hide: 100 }, // Show/hide delays (ms)
html: false, // Allow HTML content
placement: 'top', // Tooltip position
trigger: 'hover focus', // How tooltip is triggered
title: 'Tooltip text', // Tooltip content
offset: [0, 8], // Offset from element
customClass: 'my-tooltip' // Custom CSS class
});
// Show tooltip
tooltip.show();
// Hide tooltip
tooltip.hide();
// Toggle tooltip
tooltip.toggle();
</script>
Tooltip on Disabled Elements
Disabled elements can't trigger tooltips directly. Use a wrapper element.
<!-- Wrap disabled button -->
<span class="d-inline-block" data-bs-toggle="tooltip" data-bs-title="Disabled button">
<button class="btn btn-primary" type="button" disabled>
Disabled Button
</button>
</span>
Tip: The wrapper element should have display: inline-block and the tabindex="0" attribute to enable keyboard focus.
Offcanvas Sidebar (New in Bootstrap 5)
Offcanvas creates hidden sidebars that slide into view, perfect for navigation menus and additional content.
<!-- Trigger Button -->
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample">
Open Offcanvas
</button>
<!-- Offcanvas -->
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
<div class="offcanvas-header">
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas Title</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body">
<p>This is the offcanvas content. You can add any content here.</p>
<div class="dropdown mt-3">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown">
Dropdown
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
</ul>
</div>
</div>
</div>
Offcanvas Placement
Offcanvas can slide in from any side of the viewport.
<!-- Left Side (default) -->
<div class="offcanvas offcanvas-start" id="offcanvasLeft">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Left Offcanvas</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
Content slides in from the left.
</div>
</div>
<!-- Right Side -->
<div class="offcanvas offcanvas-end" id="offcanvasRight">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Right Offcanvas</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
Content slides in from the right.
</div>
</div>
<!-- Top -->
<div class="offcanvas offcanvas-top" id="offcanvasTop">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Top Offcanvas</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
Content slides in from the top.
</div>
</div>
<!-- Bottom -->
<div class="offcanvas offcanvas-bottom" id="offcanvasBottom">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Bottom Offcanvas</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
Content slides in from the bottom.
</div>
</div>
Offcanvas Backdrop and Scrolling
Control backdrop behavior and body scrolling.
<!-- With Backdrop (default) -->
<div class="offcanvas offcanvas-start" data-bs-backdrop="true" data-bs-scroll="false" id="offcanvasWithBackdrop">
<!-- Content -->
</div>
<!-- Without Backdrop -->
<div class="offcanvas offcanvas-start" data-bs-backdrop="false" id="offcanvasWithoutBackdrop">
<!-- Content -->
</div>
<!-- Allow Body Scrolling -->
<div class="offcanvas offcanvas-start" data-bs-scroll="true" data-bs-backdrop="true" id="offcanvasWithScroll">
<!-- Content -->
</div>
<!-- Static Backdrop (can't dismiss by clicking outside) -->
<div class="offcanvas offcanvas-start" data-bs-backdrop="static" id="offcanvasStatic">
<!-- Content -->
</div>
Options:
data-bs-backdrop="true" - Show backdrop (default)
data-bs-backdrop="false" - No backdrop
data-bs-backdrop="static" - Backdrop but can't close by clicking it
data-bs-scroll="true" - Allow body scrolling while offcanvas is open
data-bs-scroll="false" - Disable body scrolling (default)
Offcanvas Navigation Menu
Common use case: responsive navigation menu.
<!-- Navbar with Offcanvas -->
<nav class="navbar navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">My Website</a>
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbar">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Menu</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
<li class="nav-item">
<a class="nav-link active" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
Services
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Web Design</a></li>
<li><a class="dropdown-item" href="#">Development</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact</a>
</li>
</ul>
<form class="d-flex mt-3" role="search">
<input class="form-control me-2" type="search" placeholder="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
</div>
</nav>
Offcanvas JavaScript API
Control offcanvas programmatically with JavaScript.
<script>
// Get offcanvas element
const offcanvasEl = document.getElementById('myOffcanvas');
// Create offcanvas instance with options
const offcanvas = new bootstrap.Offcanvas(offcanvasEl, {
backdrop: true, // Show backdrop
keyboard: true, // Close with ESC key
scroll: false // Disable body scroll
});
// Show offcanvas
offcanvas.show();
// Hide offcanvas
offcanvas.hide();
// Toggle offcanvas
offcanvas.toggle();
// Event listeners
offcanvasEl.addEventListener('show.bs.offcanvas', function (event) {
console.log('Offcanvas is about to show');
});
offcanvasEl.addEventListener('shown.bs.offcanvas', function (event) {
console.log('Offcanvas is fully shown');
});
offcanvasEl.addEventListener('hide.bs.offcanvas', function (event) {
console.log('Offcanvas is about to hide');
});
offcanvasEl.addEventListener('hidden.bs.offcanvas', function (event) {
console.log('Offcanvas is fully hidden');
});
</script>
Responsive Offcanvas
Bootstrap 5.2+ introduced responsive offcanvas that only activates below certain breakpoints.
<!-- Offcanvas only on small screens -->
<div class="offcanvas-lg offcanvas-start" id="responsiveOffcanvas">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Responsive Menu</h5>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<p>On large screens (≥992px), this appears as regular content.</p>
<p>On smaller screens, it behaves as an offcanvas.</p>
</div>
</div>
<!-- Available responsive classes -->
<!-- offcanvas-sm, offcanvas-md, offcanvas-lg, offcanvas-xl, offcanvas-xxl -->
Use Case: Responsive offcanvas is perfect for navigation that should be hidden in a sidebar on mobile but visible in the layout on desktop.
Practice Exercise
Task 1: Create a toolbar with icon buttons that show tooltips on hover:
- Create 6 icon buttons (use text like "📄", "✂️", "📋", "💾", "🖨️", "⚙️" as icons)
- Each button should have a descriptive tooltip (e.g., "New File", "Cut", "Copy", "Save", "Print", "Settings")
- Position tooltips on bottom
- Add a small delay (500ms) before showing tooltips
Task 2: Build a complete responsive dashboard layout with offcanvas:
- Header with logo and hamburger menu button
- Left offcanvas with navigation menu (Dashboard, Analytics, Reports, Settings)
- Include user profile section in offcanvas with avatar and name
- Add backdrop with static behavior
- Include a search form in the offcanvas
Bonus Challenge: Create a shopping cart offcanvas that slides in from the right with product items, quantities, total price, and checkout button. Add a badge on the cart icon showing item count.
Best Practices
- Use tooltips for brief, supplementary information only
- Keep tooltip text short and concise (1-2 sentences maximum)
- Don't put critical information in tooltips that users need to see
- Ensure tooltips don't cover interactive elements
- Use offcanvas for navigation menus on mobile devices
- Consider using responsive offcanvas classes for better desktop experiences
- Always provide a clear close button in offcanvas headers
- Use static backdrop for important offcanvas content that shouldn't be accidentally dismissed
- Test tooltip and offcanvas behavior on touch devices
- Ensure keyboard navigation works properly (Tab, Esc keys)