Bulma Tabs
Bulma Tabs provide a simple yet powerful way to create tabbed navigation interfaces. They are highly customizable and work perfectly for organizing content into separate panels.
Basic Tabs
Simple horizontal tabs:
<div class="tabs">
<ul>
<li class="is-active"><a>Pictures</a></li>
<li><a>Music</a></li>
<li><a>Videos</a></li>
<li><a>Documents</a></li>
</ul>
</div>Tab Alignment
Position tabs within their container:
<!-- Centered tabs -->
<div class="tabs is-centered">
<ul>
<li class="is-active"><a>Centered</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Right aligned tabs -->
<div class="tabs is-right">
<ul>
<li class="is-active"><a>Right</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Full width tabs -->
<div class="tabs is-fullwidth">
<ul>
<li class="is-active"><a>Full</a></li>
<li><a>Width</a></li>
</ul>
</div>Tab Styles
Apply different styling to tabs:
<!-- Boxed tabs -->
<div class="tabs is-boxed">
<ul>
<li class="is-active"><a>Boxed</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Toggle (rounded) tabs -->
<div class="tabs is-toggle">
<ul>
<li class="is-active"><a>Toggle</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Toggle rounded tabs -->
<div class="tabs is-toggle is-toggle-rounded">
<ul>
<li class="is-active"><a>Rounded</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>Tab Sizes
<!-- Small tabs -->
<div class="tabs is-small">
<ul>
<li class="is-active"><a>Small</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Medium tabs -->
<div class="tabs is-medium">
<ul>
<li class="is-active"><a>Medium</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>
<!-- Large tabs -->
<div class="tabs is-large">
<ul>
<li class="is-active"><a>Large</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>Tabs with Icons
<div class="tabs">
<ul>
<li class="is-active">
<a>
<span class="icon is-small"><i class="fas fa-image"></i></span>
<span>Pictures</span>
</a>
</li>
<li>
<a>
<span class="icon is-small"><i class="fas fa-music"></i></span>
<span>Music</span>
</a>
</li>
<li>
<a>
<span class="icon is-small"><i class="fas fa-film"></i></span>
<span>Videos</span>
</a>
</li>
<li>
<a>
<span class="icon is-small"><i class="fas fa-file-alt"></i></span>
<span>Documents</span>
</a>
</li>
</ul>
</div>Tabs with Badges
<div class="tabs">
<ul>
<li class="is-active">
<a>
<span>Inbox</span>
<span class="tag is-primary ml-2">3</span>
</a>
</li>
<li>
<a>
<span>Drafts</span>
<span class="tag is-light ml-2">5</span>
</a>
</li>
<li>
<a>
<span>Sent</span>
</a>
</li>
<li>
<a>
<span>Trash</span>
<span class="tag is-danger ml-2">12</span>
</a>
</li>
</ul>
</div>Vertical Tabs
Create vertical tab navigation:
<div class="tabs is-vertical">
<ul>
<li class="is-active"><a>Vertical</a></li>
<li><a>Tab 2</a></li>
<li><a>Tab 3</a></li>
</ul>
</div>
<!-- Vertical tabs on the right -->
<div class="tabs is-vertical is-right">
<ul>
<li class="is-active"><a>Right</a></li>
<li><a>Tab 2</a></li>
</ul>
</div>Tab Content Panels
Connect tabs with content areas:
<div class="tabs">
<ul>
<li class="is-active" data-target="panel-1"><a>Tab 1</a></li>
<li data-target="panel-2"><a>Tab 2</a></li>
<li data-target="panel-3"><a>Tab 3</a></li>
</ul>
</div>
<div class="tab-content">
<div class="tab-panel is-active" id="panel-1">
<p>Content for Tab 1</p>
</div>
<div class="tab-panel" id="panel-2">
<p>Content for Tab 2</p>
</div>
<div class="tab-panel" id="panel-3">
<p>Content for Tab 3</p>
</div>
</div>
<style>
.tab-panel {
display: none;
padding: 1rem;
border: 1px solid #dbdbdb;
border-top: none;
}
.tab-panel.is-active {
display: block;
}
</style>JavaScript Integration
Make tabs interactive:
// Basic tab switching
document.addEventListener('DOMContentLoaded', () => {
const tabs = document.querySelectorAll('.tabs li');
const tabContents = document.querySelectorAll('.tab-content');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
// Remove active class from all tabs
tabs.forEach(t => t.classList.remove('is-active'));
// Add active class to clicked tab
tab.classList.add('is-active');
// Hide all tab content
tabContents.forEach(content => {
content.style.display = 'none';
});
// Show corresponding tab content
const target = tab.dataset.target;
if (target) {
document.getElementById(target).style.display = 'block';
}
});
});
});
// Advanced tab system with animation
class TabSystem {
constructor(container) {
this.container = container;
this.tabs = container.querySelectorAll('.tab');
this.panels = container.querySelectorAll('.tab-panel');
this.init();
}
init() {
this.tabs.forEach(tab => {
tab.addEventListener('click', (e) => {
e.preventDefault();
this.switchTab(tab.dataset.tab);
});
});
}
switchTab(tabName) {
// Update tabs
this.tabs.forEach(tab => {
if (tab.dataset.tab === tabName) {
tab.classList.add('is-active');
} else {
tab.classList.remove('is-active');
}
});
// Update panels with animation
this.panels.forEach(panel => {
if (panel.id === `panel-${tabName}`) {
panel.classList.remove('is-hidden');
panel.classList.add('is-active');
setTimeout(() => {
panel.style.opacity = '1';
panel.style.transform = 'translateY(0)';
}, 10);
} else {
panel.style.opacity = '0';
panel.style.transform = 'translateY(10px)';
setTimeout(() => {
panel.classList.add('is-hidden');
panel.classList.remove('is-active');
}, 300);
}
});
}
}
// Initialize tab system
const tabSystems = document.querySelectorAll('.tab-system');
tabSystems.forEach(system => new TabSystem(system));URL Hash Navigation
Make tabs bookmarkable with URL hashes:
<div class="tabs">
<ul>
<li class="is-active"><a href="#profile">Profile</a></li>
<li><a href="#settings">Settings</a></li>
<li><a href="#billing">Billing</a></li>
</ul>
</div>
<div class="tab-content">
<div class="tab-panel is-active" id="profile">
<p>Profile content</p>
</div>
<div class="tab-panel" id="settings">
<p>Settings content</p>
</div>
<div class="tab-panel" id="billing">
<p>Billing content</p>
</div>
</div>
<script>
// Handle hash changes
window.addEventListener('hashchange', switchTabFromHash);
window.addEventListener('load', switchTabFromHash);
function switchTabFromHash() {
const hash = window.location.hash.substring(1);
if (hash) {
// Remove active class from all tabs
document.querySelectorAll('.tabs li').forEach(li => {
li.classList.remove('is-active');
});
// Add active class to corresponding tab
const activeTab = document.querySelector(`.tabs a[href="#${hash}"]`);
if (activeTab) {
activeTab.parentElement.classList.add('is-active');
}
// Show corresponding content
document.querySelectorAll('.tab-panel').forEach(panel => {
panel.classList.remove('is-active');
});
const activePanel = document.getElementById(hash);
if (activePanel) {
activePanel.classList.add('is-active');
}
}
}
</script>Practical Examples
Settings Page Tabs
<div class="columns">
<div class="column is-3">
<div class="tabs is-vertical is-fullheight">
<ul>
<li class="is-active" data-tab="profile">
<a>
<span class="icon"><i class="fas fa-user"></i></span>
<span>Profile</span>
</a>
</li>
<li data-tab="security">
<a>
<span class="icon"><i class="fas fa-lock"></i></span>
<span>Security</span>
</a>
</li>
<li data-tab="notifications">
<a>
<span class="icon"><i class="fas fa-bell"></i></span>
<span>Notifications</span>
<span class="tag is-warning ml-2">3</span>
</a>
</li>
<li data-tab="billing">
<a>
<span class="icon"><i class="fas fa-credit-card"></i></span>
<span>Billing</span>
</a>
</li>
</ul>
</div>
</div>
<div class="column is-9">
<div class="tab-content">
<div class="tab-panel is-active" id="panel-profile">
<h2 class="title is-4">Profile Settings</h2>
<!-- Profile form -->
</div>
<div class="tab-panel" id="panel-security">
<h2 class="title is-4">Security Settings</h2>
<!-- Security form -->
</div>
<div class="tab-panel" id="panel-notifications">
<h2 class="title is-4">Notification Settings</h2>
<!-- Notification settings -->
</div>
<div class="tab-panel" id="panel-billing">
<h2 class="title is-4">Billing Information</h2>
<!-- Billing form -->
</div>
</div>
</div>
</div>Product Detail Tabs
<div class="box">
<div class="tabs is-boxed">
<ul>
<li class="is-active" data-tab="description">
<a>Description</a>
</li>
<li data-tab="specifications">
<a>Specifications</a>
</li>
<li data-tab="reviews">
<a>
<span>Reviews</span>
<span class="tag is-primary ml-2">24</span>
</a>
</li>
<li data-tab="qna">
<a>
<span>Q&A</span>
<span class="tag is-info ml-2">8</span>
</a>
</li>
</ul>
</div>
<div class="tab-content p-4">
<div class="tab-panel is-active" id="panel-description">
<h3 class="title is-5">Product Description</h3>
<p>Detailed product description goes here...</p>
</div>
<div class="tab-panel" id="panel-specifications">
<h3 class="title is-5">Technical Specifications</h3>
<table class="table is-striped">
<!-- Specifications table -->
</table>
</div>
<div class="tab-panel" id="panel-reviews">
<h3 class="title is-5">Customer Reviews</h3>
<!-- Reviews list -->
</div>
<div class="tab-panel" id="panel-qna">
<h3 class="title is-5">Questions & Answers</h3>
<!-- Q&A list -->
</div>
</div>
</div>Dashboard Tabs with Statistics
<div class="card">
<div class="card-header">
<div class="card-header-title">
<div class="tabs is-toggle is-fullwidth">
<ul>
<li class="is-active" data-tab="daily">
<a>
<span class="icon is-small"><i class="fas fa-calendar-day"></i></span>
<span>Daily</span>
</a>
</li>
<li data-tab="weekly">
<a>
<span class="icon is-small"><i class="fas fa-calendar-week"></i></span>
<span>Weekly</span>
</a>
</li>
<li data-tab="monthly">
<a>
<span class="icon is-small"><i class="fas fa-calendar-alt"></i></span>
<span>Monthly</span>
</a>
</li>
<li data-tab="yearly">
<a>
<span class="icon is-small"><i class="fas fa-calendar"></i></span>
<span>Yearly</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="card-content">
<div class="tab-content">
<div class="tab-panel is-active" id="panel-daily">
<h3 class="title is-5">Daily Statistics</h3>
<!-- Daily stats chart -->
</div>
<div class="tab-panel" id="panel-weekly">
<h3 class="title is-5">Weekly Statistics</h3>
<!-- Weekly stats chart -->
</div>
<div class="tab-panel" id="panel-monthly">
<h3 class="title is-5">Monthly Statistics</h3>
<!-- Monthly stats chart -->
</div>
<div class="tab-panel" id="panel-yearly">
<h3 class="title is-5">Yearly Statistics</h3>
<!-- Yearly stats chart -->
</div>
</div>
</div>
</div>Best Practices
- Use descriptive tab labels that clearly indicate the content
- Include icons for better visual recognition
- Use badges to show counts or status indicators
- Make tabs accessible with proper keyboard navigation
- Consider URL hash navigation for bookmarkable tabs
- Use vertical tabs for sidebar navigation
- Implement smooth transitions between tab panels
- Ensure active tab is clearly distinguishable
- Test tabs on mobile devices - consider responsive alternatives
Accessibility: Add proper ARIA attributes to tabs and panels. Use
role="tablist", role="tab", role="tabpanel", and manage focus with JavaScript for keyboard navigation.Congratulations! You've completed the Bulma CSS tutorial series. Review all components at Bulma Overview