Bootstrap 5 Tutorial
v5.3.0Bootstrap 5 Tutorial
Z-index Utilities in Bootstrap 5
Z-index Utilities: Control the stacking order of positioned elements with predefined z-index values.
What is Z-index?
Z-index controls the vertical stacking order of positioned elements (elements with position: relative, absolute, fixed, or sticky). Higher z-index values appear in front of lower values.
Z-index Scale
Predefined Z-index Values
.z-n1z-index: -1
.z-0z-index: 0
.z-1z-index: 1
.z-2z-index: 2
.z-3z-index: 3
<!-- Z-index utilities --> <div class="z-n1">z-index: -1</div> <div class="z-0">z-index: 0</div> <div class="z-1">z-index: 1</div> <div class="z-2">z-index: 2</div> <div class="z-3">z-index: 3</div> <div class="z-4">z-index: 4</div> <div class="z-5">z-index: 5</div> <!-- Bootstrap component z-index defaults --> <nav class="navbar fixed-top z-3">z-index: 1030</div> <div class="modal-backdrop z-4">z-index: 1040</div> <div class="modal z-5">z-index: 1050</div> <div class="dropdown-menu z-6">z-index: 1060</div> <div class="tooltip z-7">z-index: 1070</div> <div class="popover z-8">z-index: 1080</div> <div class="toast z-9">z-index: 1090</div> <!-- Negative z-index --> <div class="z-n1">Behind normal content</div> <!-- Auto z-index --> <div class="z-auto">z-index: auto (default)</div> <!-- Inline usage --> <span class="position-relative z-1">Inline with z-index</span> <!-- With other positioning --> <div class="position-absolute top-0 start-0 z-2">Absolute with z-index</div> <div class="position-fixed top-0 z-3">Fixed with z-index</div> <div class="position-sticky top-0 z-2">Sticky with z-index</div>
Bootstrap Component Z-index
Default Z-index Values
| Component | Class | Default Z-index | Custom Class | Purpose |
|---|---|---|---|---|
| Navbar | .navbar | 1030 | .z-3 | Fixed navigation |
| Fixed/sticky elements | .fixed-top, .sticky-top | 1020 | .z-2 | Header elements |
| Dropdown | .dropdown-menu | 1000 | .z-1 | Dropdown menus |
| Modal backdrop | .modal-backdrop | 1040 | .z-4 | Modal overlay |
| Modal | .modal | 1050 | .z-5 | Dialog windows |
| Popover | .popover | 1070 | .z-7 | Tooltip-like elements |
| Tooltip | .tooltip | 1080 | .z-8 | Information tooltips |
| Toast | .toast | 1090 | .z-9 | Notification messages |
Important Notes:
- Bootstrap components have predefined z-index values that work together
- Custom z-index utilities (z-0 to z-5) are for your own elements
- Don't override Bootstrap component z-index unless necessary
- Always consider the stacking context when using z-index
/* Bootstrap default z-index values */
$zindex-dropdown: 1000;
$zindex-sticky: 1020;
$zindex-fixed: 1030;
$zindex-modal-backdrop: 1040;
$zindex-modal: 1050;
$zindex-popover: 1070;
$zindex-tooltip: 1080;
$zindex-toast: 1090;
/* Custom utility z-index scale */
$zindex-levels: (
n1: -1,
0: 0,
1: 1,
2: 2,
3: 3,
4: 4,
5: 5
);
/* Usage in SCSS */
.navbar {
z-index: $zindex-fixed; /* 1030 */
}
.modal {
z-index: $zindex-modal; /* 1050 */
}
.dropdown-menu {
z-index: $zindex-dropdown; /* 1000 */
}
/* Override if needed */
.custom-modal {
z-index: $zindex-modal + 10; /* 1060 */
}
/* Creating stacking context */
.stacking-context {
position: relative;
z-index: 0;
}
/* Nested z-index */
.parent {
position: relative;
z-index: 1;
}
.child {
position: absolute;
z-index: 10; /* Only competes with siblings, not outside parent */
}Stacking Context
Understanding Stacking Context
Stacking Context Example
Child z-10
position: relative; z-index: 0;Creates stacking context
Without Stacking Context
Child z-2
No stacking contextZ-index competes globally
What Creates Stacking Context?
position: relative/absolute/fixed/stickywithz-index ≠ autoopacity < 1transform ≠ nonefilter ≠ noneperspective ≠ nonemix-blend-mode ≠ normal
Stacking Context Rules:
- Elements only compete with siblings in same stacking context
- Child z-index is relative to parent's stacking context
- Higher z-index parent brings all children forward
- Isolate z-index issues with stacking contexts
<!-- Stacking context example -->
<!-- Parent creates stacking context -->
<div class="position-relative z-0">
<!-- Stacking context created -->
<!-- Child z-index only competes with siblings -->
<div class="position-absolute z-1">z-index: 1</div>
<div class="position-absolute z-2">z-index: 2 (wins)</div>
<!-- Nested with high z-index -->
<div class="position-relative">
<div class="position-absolute z-10">
<!-- Still within parent's stacking context -->
</div>
</div>
</div>
<!-- Outside the stacking context -->
<div class="position-absolute z-3">
<!-- This competes with the parent, not the children -->
</div>
<!-- Creating stacking context without visual change -->
.isolate {
position: relative;
z-index: 0;
}
/* In SCSS */
.stacking-context {
// Any of these creates stacking context
position: relative;
z-index: 0;
// OR
opacity: 0.99;
// OR
transform: translateZ(0);
// OR
filter: blur(0);
}
/* Practical isolation */
.modal-content {
position: relative;
z-index: 0; /* Creates stacking context */
}
.modal-header {
position: relative;
z-index: 1; /* Stays above modal body */
}
.modal-body {
position: relative;
z-index: 0; /* Default */
}
/* Fixing z-index issues */
.z-index-fix {
// Isolate problematic elements
position: relative;
z-index: 0;
}
/* Nested dropdown fix */
.dropdown {
position: relative; /* Creates stacking context */
}
.dropdown-menu {
z-index: 1000; /* Within dropdown's context */
}Practical Examples
Overlapping Elements
Card 1
.z-1
Card 2
.z-2 (on top)
Card 3
.z-0 (behind)
3
<!-- Overlapping cards -->
<div class="position-relative" style="height: 250px;">
<!-- Background -->
<div class="position-absolute top-0 start-0 w-100 h-100 bg-light"></div>
<!-- Card 1 -->
<div class="position-absolute top-0 start-0 w-50 h-50 bg-white z-1">
<code>.z-1</code>
</div>
<!-- Card 2 (on top) -->
<div class="position-absolute top-10 start-25 w-50 h-50 bg-white z-2">
<code>.z-2</code>
</div>
<!-- Card 3 (behind) -->
<div class="position-absolute top-20 start-50 w-50 h-50 bg-white z-0">
<code>.z-0</code>
</div>
<!-- Badge (on top of everything) -->
<div class="position-absolute top-5 start-75 rounded-circle z-3">
Badge
</div>
</div>
<!-- Dropdown with z-index -->
<div class="position-relative">
<button class="btn btn-primary z-1">Button</button>
<div class="position-absolute top-100 start-0 bg-white shadow-lg z-2">
Dropdown content
<!-- Badge on dropdown -->
<div class="position-absolute top-0 end-0 rounded-circle z-3">
New
</div>
</div>
</div>Modal & Overlay Patterns
Page Content
This represents your webpage content.
Modal Title
Modal content goes here.
✓Action completed successfully!
Tooltip Example
Hover over me
This is a popover with more detailed information.
<!-- Modal pattern -->
<!-- Page content -->
<div class="position-absolute top-0 start-0 w-100 h-100 bg-light">
Page content
</div>
<!-- Modal backdrop -->
<div class="position-absolute top-0 start-0 w-100 h-100
bg-dark bg-opacity-50 z-4">
<!-- Overlay -->
</div>
<!-- Modal -->
<div class="position-absolute top-50 start-50 translate-middle
bg-white rounded shadow-lg z-5">
<div class="p-3">
Modal content
<!-- Action buttons -->
<div class="position-absolute bottom-0 end-0 m-3">
<button class="btn btn-primary">Action</button>
</div>
</div>
</div>
<!-- Toast (on top of modal) -->
<div class="position-absolute top-0 end-0 m-3
bg-success text-white rounded shadow z-6">
Notification
</div>
<!-- Tooltip -->
<button class="btn position-relative">
Button
<div class="position-absolute bottom-100 start-50 translate-middle-x
bg-dark text-white rounded p-2 z-8">
Tooltip content
</div>
</button>
<!-- Popover -->
<div class="position-relative d-inline-block">
<span class="text-primary">
Trigger
<div class="position-absolute bottom-100 start-0
bg-dark text-white rounded p-2 z-7">
Popover content
</div>
</span>
</div>
<!-- Fixed header with dropdown -->
<nav class="navbar fixed-top bg-light z-3">
<div class="container-fluid">
<!-- Nav content -->
<div class="dropdown">
<button class="btn dropdown-toggle">Menu</button>
<div class="dropdown-menu z-4">
<!-- Dropdown above other content -->
</div>
</div>
</div>
</nav>Responsive Z-index
Responsive Z-index Example
.z-1 .z-md-3Higher on desktop
.z-2 .z-md-1Lower on desktop
Breakpoint Table
| Breakpoint | Class Prefix | Example | Behavior |
|---|---|---|---|
| All | z- | .z-1 | Always applies |
| ≥576px | z-sm- | .z-sm-2 | On sm+ screens |
| ≥768px | z-md- | .z-md-3 | On md+ screens |
| ≥992px | z-lg- | .z-lg-0 | On lg+ screens |
| ≥1200px | z-xl- | .z-xl-5 | On xl+ screens |
Use Cases for Responsive Z-index
- Mobile-only overlays that hide on desktop
- Different stacking orders for mobile vs desktop layouts
- Responsive navigation menus
- Mobile-optimized modals and drawers
- Adaptive tooltips and popovers
Example:
.z-3 .z-md-0Element is on top on mobile but behaves normally on desktop
<!-- Responsive z-index -->
<div class="z-1 z-md-3 z-lg-5">
<!--
z-index: 1 on mobile
z-index: 3 on tablet
z-index: 5 on desktop
-->
</div>
<div class="z-3 z-md-1">
<!--
Higher on mobile, lower on desktop
-->
</div>
<div class="z-0 z-md-2 z-lg-0">
<!--
Default on mobile
Higher on tablet
Default on desktop
-->
</div>
<!-- Mobile-only overlay -->
<div class="position-fixed top-0 start-0 vw-100 vh-100 bg-dark bg-opacity-50
z-5 d-md-none">
<!-- Only visible on mobile -->
</div>
<!-- Responsive navigation -->
<nav class="navbar fixed-top z-3 z-md-2">
<!-- Higher on mobile, normal on desktop -->
</nav>
<!-- Responsive dropdown -->
<div class="dropdown">
<button class="btn">Menu</button>
<div class="dropdown-menu z-4 z-md-3">
<!-- Higher on mobile -->
</div>
</div>
<!-- Mobile drawer -->
<div class="position-fixed top-0 start-0 vh-100 bg-white shadow
z-5 w-75 d-md-none">
<!-- Mobile-only drawer -->
</div>
<!-- Responsive modals -->
<div class="modal z-5 z-md-4">
<!-- Different z-index per breakpoint -->
</div>
<!-- Practical example: mobile-optimized UI -->
<div class="position-relative">
<!-- Main content -->
<div class="z-0">Content</div>
<!-- Mobile menu button (always on top on mobile) -->
<button class="btn btn-primary z-3 z-md-0 d-md-none">
Menu
</button>
<!-- Desktop sidebar (normal stacking) -->
<aside class="z-1 d-none d-md-block">Sidebar</aside>
</div>Common Z-index Issues & Solutions
Troubleshooting Z-index
Common Problems
| Problem | Cause | Solution |
|---|---|---|
| Z-index not working | Element not positioned | Add position: relative/absolute/fixed |
| Child can't go above parent | Parent has lower z-index | Increase parent z-index or create new stacking context |
| Unexpected stacking | Multiple stacking contexts | Check parent elements for stacking contexts |
| Bootstrap component overlap | Custom z-index conflicts | Use higher values or adjust Bootstrap defaults |
| Mobile/desktop differences | Responsive issues | Use responsive z-index utilities |
Debugging Techniques
1. Check Positioning
/* Z-index only works on positioned elements */
.element {
position: relative; /* or absolute/fixed/sticky */
z-index: 1;
}2. Inspect Stacking Contexts
Use browser dev tools to identify stacking contexts (look for opacity, transform, filter properties)
3. Isolation Technique
/* Create isolated stacking context */
.isolate {
position: relative;
z-index: 0;
/* OR */
opacity: 0.99;
/* OR */
transform: translateZ(0);
}Best Practices for Z-index Management
- Use a z-index scale (0-5 for custom, 1000+ for components)
- Document your z-index values in a design system
- Keep z-index values as low as possible
- Use stacking contexts to isolate complexity
- Test on all target devices and browsers
Recommended Z-index Scale
0: Default/base content1-10: Overlays, dropdowns11-100: Modals, notifications101-1000: Special cases1000+: Bootstrap components
/* Z-index management system */
/* Base scale (for custom elements) */
:root {
--z-index-dropdown: 10;
--z-index-sticky: 20;
--z-index-fixed: 30;
--z-index-modal-backdrop: 40;
--z-index-modal: 50;
--z-index-popover: 60;
--z-index-tooltip: 70;
--z-index-toast: 80;
--z-index-super: 100;
}
/* Usage */
.dropdown {
z-index: var(--z-index-dropdown);
}
.modal {
z-index: var(--z-index-modal);
}
/* Bootstrap override if needed */
.bootstrap-modal {
z-index: 1050 !important; /* Bootstrap default */
}
/* Custom higher value */
.custom-super-modal {
z-index: calc(var(--z-index-modal) + 100);
}
/* Debugging classes */
.debug-z-index {
outline: 2px solid red;
background: rgba(255, 0, 0, 0.1);
}
.debug-z-index::before {
content: 'z-index: ' attr(data-z-index);
position: absolute;
top: 0;
left: 0;
background: red;
color: white;
padding: 2px 4px;
font-size: 10px;
z-index: 9999;
}
/* Usage in HTML */
<div class="debug-z-index" data-z-index="1" style="z-index: 1;">
Debug element
</div>
/* Z-index reset for specific contexts */
.reset-z-index {
position: static !important;
z-index: auto !important;
}
/* Print styles - remove z-index */
@media print {
* {
z-index: auto !important;
position: static !important;
}
}
/* Safe z-index increment function */
@function safe-z-index($base, $increment: 1) {
@return $base + $increment;
}
/* Usage in SCSS */
.modal-backdrop {
z-index: safe-z-index($zindex-modal, -10);
}
.modal {
z-index: $zindex-modal;
}
.toast {
z-index: safe-z-index($zindex-modal, 10);
}Best Practices
Z-index Guidelines
- ✅ Use z-index only when necessary
- ✅ Keep z-index values as low as possible
- ✅ Use a consistent z-index scale
- ✅ Understand stacking contexts
- ✅ Test z-index behavior on all target devices
- ✅ Document complex z-index relationships
- ✅ Use responsive z-index for mobile/desktop differences
- ✅ Avoid z-index wars - refactor instead of increasing values
Accessibility Considerations
Accessibility & Z-index
- Focus order: Ensure keyboard focus follows visual stacking order
- Screen readers: Z-index doesn't affect screen reader announcement order
- Modal dialogs: Use appropriate z-index to trap focus correctly
- Overlays: Ensure overlays don't hide interactive content unexpectedly
- High contrast mode: Test z-index behavior in Windows High Contrast Mode
- Zoom: Ensure z-index works correctly when page is zoomed