Bootstrap 5 Tutorial
v5.3.0Bootstrap 5 Tutorial
Visibility Utilities in Bootstrap 5
Visibility Utilities: Control the visibility of elements without removing them from the document flow.
Visibility vs Display
Comparison: .visible, .invisible, .d-none
Visible (Default)
Element 1
Element 2 (visible)
Element 3
.visibleDefault state, occupies space
Invisible
Element 1
Element 2 (invisible)
Element 3
.invisibleHidden but occupies space
Display None
Element 1
Element 2 (d-none)
Element 3
.d-noneCompletely removed from flow
Space Occupancy Comparison
| Property | Space Occupied | Interactive | Screen Readers | Use Case |
|---|---|---|---|---|
.visible | Yes | Yes | Announced | Default state |
.invisible | Yes | No | Not announced | Hide but keep layout |
.d-none | No | No | Not announced | Completely hide |
.d-sm-none | Conditional | Conditional | Conditional | Responsive hiding |
Visual Example
Before
Middle (invisible)
After
Before
Middle (d-none)
After
Invisible: Space preserved between elements
d-none: Elements collapse together
<!-- Visibility utilities -->
<div class="visible">Visible (default state)</div>
<div class="invisible">Invisible but occupies space</div>
<!-- Display utilities -->
<div class="d-none">Completely hidden, no space</div>
<div class="d-block">Display as block</div>
<div class="d-inline">Display as inline</div>
<!-- Comparison examples -->
<!-- Layout with invisible element -->
<div class="d-flex">
<div class="p-2 bg-primary text-white">Item 1</div>
<div class="p-2 invisible bg-success text-white">Item 2 (hidden space)</div>
<div class="p-2 bg-warning text-dark">Item 3</div>
</div>
<!-- Layout with d-none -->
<div class="d-flex">
<div class="p-2 bg-primary text-white">Item 1</div>
<div class="p-2 d-none bg-success text-white">Item 2 (no space)</div>
<div class="p-2 bg-warning text-dark">Item 3</div>
</div>
<!-- Toggle visibility -->
<div class="alert alert-success invisible" id="message">
Success message
</div>
<button onclick="document.getElementById('message').classList.remove('invisible')">
Show Message
</button>
<button onclick="document.getElementById('message').classList.add('invisible')">
Hide Message
</button>
<!-- Toggle display -->
<div class="alert alert-danger d-none" id="error">
Error message
</div>
<button onclick="document.getElementById('error').classList.remove('d-none')">
Show Error
</button>
<button onclick="document.getElementById('error').classList.add('d-none')">
Hide Error
</button>
<!-- Practical difference -->
<!-- Loading spinner (use invisible to maintain layout) -->
<div class="invisible" id="loading-spinner">
<div class="spinner-border"></div>
</div>
<!-- Conditional content (use d-none to collapse) -->
<div class="d-none" id="empty-state">
No data available
</div>Responsive Visibility
Breakpoint-based Visibility
Visible on Specific Breakpoints
.d-none .d-md-blockVisible on tablet and up
.d-block .d-md-noneVisible on mobile only
.d-none .d-lg-blockVisible on desktop and up
Invisible on Specific Breakpoints
.visible .invisible-mdVisible on mobile, invisible on tablet+
.invisible .invisible-lgInvisible on mobile, visible on desktop+
Complex Responsive Example
.d-none .d-sm-block .d-md-none .d-lg-blockHidden on mobile, visible on tablet, hidden on desktop, visible on large desktop
Breakpoint Table
| Breakpoint | Display Prefix | Visibility Prefix | Example |
|---|---|---|---|
| All | d- | visible-/invisible- | .d-none, .visible |
| ≥576px | d-sm- | visible-sm- | .d-sm-block |
| ≥768px | d-md- | visible-md- | .d-md-none |
| ≥992px | d-lg- | visible-lg- | .d-lg-inline |
| ≥1200px | d-xl- | visible-xl- | .d-xl-flex |
| ≥1400px | d-xxl- | visible-xxl- | .d-xxl-grid |
<!-- Responsive display -->
<div class="d-none d-md-block">
<!-- Hidden on mobile, block on tablet+ -->
</div>
<div class="d-block d-md-none">
<!-- Block on mobile, hidden on tablet+ -->
</div>
<div class="d-none d-sm-block d-md-none d-lg-block">
<!--
Hidden on mobile
Block on tablet
Hidden on desktop
Block on large desktop
-->
</div>
<!-- Responsive visibility -->
<div class="visible invisible-md">
<!-- Visible on mobile, invisible on tablet+ -->
</div>
<div class="invisible visible-lg">
<!-- Invisible on mobile, visible on desktop+ -->
</div>
<!-- Responsive table columns -->
<table class="table">
<thead>
<tr>
<th class="d-none d-md-table-cell">ID</th>
<th>Name</th>
<th class="d-none d-sm-table-cell">Email</th>
<th class="d-none d-lg-table-cell">Actions</th>
</tr>
</thead>
</table>
<!-- Responsive navigation -->
<nav class="navbar">
<div class="d-none d-md-block">
<!-- Desktop menu -->
</div>
<div class="d-md-none">
<!-- Mobile menu button -->
</div>
</nav>
<!-- Responsive content -->
<div class="row">
<div class="col-12 d-lg-none">
<!-- Mobile-only content -->
</div>
<div class="col-lg-8 d-none d-lg-block">
<!-- Desktop-only content -->
</div>
</div>Accessibility Considerations
Screen Reader Visibility
Important:
.invisible and .d-none hide content from screen readers. Use .visually-hidden or .sr-only for screen-reader-only content.Screen Reader Classes
This content is only available to screen readers
Accessibility Comparison
| Class | Visual | Screen Reader | Tab Focus | Use Case |
|---|---|---|---|---|
.invisible | Hidden | Hidden | No | Temporarily hide UI elements |
.d-none | Hidden | Hidden | No | Conditional content |
.visually-hidden | Hidden | Visible | No | Screen reader text |
.visually-hidden-focusable | Hidden | Visible | Yes (when focused) | Skip links |
<!-- Screen reader text --> <button class="btn btn-primary"> Search <span class="visually-hidden"> products</span> </button> <!-- Skip link --> <a href="#main-content" class="visually-hidden-focusable"> Skip to main content </a> <!-- Hidden but accessible content --> <div class="visually-hidden" id="instructions"> Use arrow keys to navigate the menu </div> <!-- Bad practice - hides from screen readers --> <div class="invisible"> Important screen reader content (inaccessible!) </div> <!-- Good practice - accessible alternative --> <div class="invisible" aria-hidden="true"> Decorative content </div> <div class="visually-hidden"> Descriptive text for screen readers </div>
Practical Examples
Real-world Use Cases
Loading States
Loading data...
Form Validation
Please enter a valid email
Responsive Components
Desktop Navigation
Mobile Menu Button
Sidebar (Desktop only)
Toast Notifications
Notification
Your changes have been saved.
Conditional Content
No data available. Add some items to get started.
- Item 1
- Item 2
<!-- Loading state -->
<div class="d-flex align-items-center">
<span>Processing...</span>
<div class="spinner-border spinner-border-sm ms-2 invisible" id="spinner"></div>
</div>
<script>
// Show spinner during AJAX call
document.getElementById('spinner').classList.remove('invisible');
// After completion
document.getElementById('spinner').classList.add('invisible');
</script>
<!-- Form validation -->
<div class="mb-3">
<label class="form-label">Password</label>
<input type="password" class="form-control" id="password">
<div class="invalid-feedback d-none" id="passwordError">
Password must be at least 8 characters
</div>
</div>
<script>
function validatePassword() {
const password = document.getElementById('password').value;
const error = document.getElementById('passwordError');
if (password.length < 8) {
error.classList.remove('d-none');
} else {
error.classList.add('d-none');
}
}
</script>
<!-- Responsive table -->
<table class="table">
<thead>
<tr>
<!-- Hidden on mobile, shown on tablet+ -->
<th class="d-none d-sm-table-cell">ID</th>
<th>Name</th>
<!-- Hidden on mobile and tablet, shown on desktop+ -->
<th class="d-none d-md-table-cell">Email</th>
<!-- Hidden on mobile, tablet, desktop, shown on large desktop+ -->
<th class="d-none d-xl-table-cell">Registration Date</th>
</tr>
</thead>
</table>
<!-- Tab interface -->
<div class="tab-content">
<div class="tab-pane fade show active" id="tab1">
Tab 1 content
</div>
<div class="tab-pane fade" id="tab2">
Tab 2 content
</div>
</div>
<!-- Modal visibility -->
<div class="modal fade" id="exampleModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal content -->
</div>
</div>
</div>
<script>
// Bootstrap 5 modal show/hide
const modal = new bootstrap.Modal(document.getElementById('exampleModal'));
modal.show(); // Shows the modal
modal.hide(); // Hides the modal
</script>Best Practices Summary
- Use
.invisiblewhen you need to preserve layout space - Use
.d-nonewhen you want elements to collapse - Always consider accessibility - use
.visually-hiddenfor screen reader text - Use responsive utilities to optimize content for different screen sizes
- Combine with JavaScript for interactive show/hide functionality
- Test both visual appearance and screen reader behavior