Back to Blog
CSSisolationz-indexStacking Context

CSS isolation Property Guide

Master the CSS isolation property for controlling stacking contexts and z-index behavior.

B
Bootspring Team
Engineering
November 11, 2019
6 min read

The isolation property creates a new stacking context, helping manage z-index conflicts. Here's how to use it.

Basic Usage#

1/* Create isolated stacking context */ 2.component { 3 isolation: isolate; 4} 5 6/* Values */ 7.auto { 8 isolation: auto; /* Default - no new context */ 9} 10 11.isolate { 12 isolation: isolate; /* Creates new stacking context */ 13}

Solving z-index Conflicts#

1/* Without isolation - z-index leaks */ 2.card { 3 position: relative; 4} 5 6.card-image { 7 position: relative; 8 z-index: 1; 9} 10 11.card-overlay { 12 position: absolute; 13 z-index: 2; 14} 15 16/* Modal appears behind card elements! */ 17.modal { 18 position: fixed; 19 z-index: 100; 20} 21 22/* With isolation - contained z-index */ 23.card { 24 isolation: isolate; /* Contains z-index within */ 25} 26 27.card-image { 28 position: relative; 29 z-index: 1; /* Only relative to .card */ 30} 31 32.card-overlay { 33 position: absolute; 34 z-index: 2; /* Only relative to .card */ 35} 36 37/* Modal now works correctly */ 38.modal { 39 position: fixed; 40 z-index: 100; /* Above the entire .card */ 41}

Component Isolation#

1/* Isolate each component */ 2.header { 3 isolation: isolate; 4 position: relative; 5} 6 7.sidebar { 8 isolation: isolate; 9 position: relative; 10} 11 12.main-content { 13 isolation: isolate; 14 position: relative; 15} 16 17.footer { 18 isolation: isolate; 19 position: relative; 20} 21 22/* Internal z-index doesn't affect others */ 23.header .dropdown { 24 z-index: 10; /* Only within header context */ 25} 26 27.sidebar .submenu { 28 z-index: 10; /* Only within sidebar context */ 29}
1/* Navigation with dropdowns */ 2.nav { 3 isolation: isolate; 4 display: flex; 5} 6 7.nav-item { 8 position: relative; 9} 10 11.dropdown-menu { 12 position: absolute; 13 top: 100%; 14 z-index: 10; 15 /* z-index works within nav context */ 16} 17 18/* Mega menu */ 19.mega-menu { 20 isolation: isolate; 21 position: absolute; 22 top: 100%; 23 left: 0; 24 right: 0; 25 z-index: 100; 26} 27 28.mega-menu-section { 29 position: relative; 30 z-index: 1; 31} 32 33.mega-menu-highlight { 34 position: absolute; 35 z-index: 2; 36}
1/* Modal container */ 2.modal-container { 3 isolation: isolate; 4 position: fixed; 5 inset: 0; 6 z-index: 1000; 7} 8 9.modal-backdrop { 10 position: absolute; 11 inset: 0; 12 background: rgba(0, 0, 0, 0.5); 13 z-index: 1; 14} 15 16.modal-content { 17 position: relative; 18 z-index: 2; 19 /* Always above backdrop */ 20} 21 22.modal-close { 23 position: absolute; 24 top: 10px; 25 right: 10px; 26 z-index: 3; 27 /* Always above content */ 28}

Card Component#

1/* Card with internal layering */ 2.card { 3 isolation: isolate; 4 position: relative; 5 border-radius: 8px; 6 overflow: hidden; 7} 8 9.card-background { 10 position: absolute; 11 inset: 0; 12 z-index: 1; 13} 14 15.card-image { 16 position: relative; 17 z-index: 2; 18} 19 20.card-gradient { 21 position: absolute; 22 bottom: 0; 23 left: 0; 24 right: 0; 25 height: 50%; 26 background: linear-gradient(transparent, rgba(0, 0, 0, 0.8)); 27 z-index: 3; 28} 29 30.card-content { 31 position: relative; 32 z-index: 4; 33} 34 35.card-badge { 36 position: absolute; 37 top: 10px; 38 right: 10px; 39 z-index: 5; 40}

Tooltip System#

1/* Tooltip wrapper */ 2.tooltip-wrapper { 3 isolation: isolate; 4 position: relative; 5 display: inline-block; 6} 7 8.tooltip { 9 position: absolute; 10 z-index: 10; 11 padding: 8px 12px; 12 background: #333; 13 color: white; 14 border-radius: 4px; 15 white-space: nowrap; 16 pointer-events: none; 17} 18 19/* Tooltip arrow */ 20.tooltip::before { 21 content: ''; 22 position: absolute; 23 z-index: 11; 24 /* Arrow styling */ 25} 26 27/* Global tooltip layer */ 28.tooltip-layer { 29 isolation: isolate; 30 position: fixed; 31 inset: 0; 32 pointer-events: none; 33 z-index: 9999; 34}
1/* Gallery with overlays */ 2.gallery { 3 display: grid; 4 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 5 gap: 16px; 6} 7 8.gallery-item { 9 isolation: isolate; 10 position: relative; 11 aspect-ratio: 1; 12 overflow: hidden; 13} 14 15.gallery-image { 16 width: 100%; 17 height: 100%; 18 object-fit: cover; 19 z-index: 1; 20} 21 22.gallery-overlay { 23 position: absolute; 24 inset: 0; 25 background: rgba(0, 0, 0, 0.6); 26 opacity: 0; 27 transition: opacity 0.3s; 28 z-index: 2; 29} 30 31.gallery-item:hover .gallery-overlay { 32 opacity: 1; 33} 34 35.gallery-actions { 36 position: absolute; 37 bottom: 10px; 38 left: 10px; 39 right: 10px; 40 z-index: 3; 41}

Tab Interface#

1/* Tabs with content */ 2.tabs { 3 isolation: isolate; 4 position: relative; 5} 6 7.tab-list { 8 display: flex; 9 position: relative; 10 z-index: 2; 11} 12 13.tab { 14 padding: 12px 24px; 15 background: #f5f5f5; 16 border: 1px solid #ddd; 17 cursor: pointer; 18} 19 20.tab.active { 21 background: white; 22 border-bottom-color: white; 23 position: relative; 24 z-index: 3; 25} 26 27.tab-content { 28 position: relative; 29 z-index: 1; 30 border: 1px solid #ddd; 31 border-top: none; 32 padding: 16px; 33 margin-top: -1px; 34}

Comparison with Other Methods#

1/* Other ways to create stacking context */ 2 3/* transform */ 4.method-1 { 5 transform: translateZ(0); 6 /* Creates stacking context + enables GPU */ 7} 8 9/* opacity < 1 */ 10.method-2 { 11 opacity: 0.99; 12 /* Creates stacking context but affects visuals */ 13} 14 15/* position + z-index */ 16.method-3 { 17 position: relative; 18 z-index: 0; 19 /* Creates stacking context */ 20} 21 22/* isolation - cleanest approach */ 23.method-4 { 24 isolation: isolate; 25 /* Creates stacking context without side effects */ 26} 27 28/* will-change */ 29.method-5 { 30 will-change: transform; 31 /* Creates stacking context + performance hint */ 32}

Mix-blend-mode Isolation#

1/* Isolate blend mode effects */ 2.blend-container { 3 isolation: isolate; 4 background: white; 5} 6 7.blend-element { 8 mix-blend-mode: multiply; 9 /* Only blends with container, not page background */ 10} 11 12/* Without isolation */ 13.no-isolate .blend-element { 14 mix-blend-mode: multiply; 15 /* Blends with everything behind it */ 16} 17 18/* Image with blend effect */ 19.image-blend { 20 isolation: isolate; 21 position: relative; 22} 23 24.image-blend img { 25 display: block; 26} 27 28.image-blend::after { 29 content: ''; 30 position: absolute; 31 inset: 0; 32 background: blue; 33 mix-blend-mode: multiply; 34}

JavaScript Detection#

1// Check stacking context 2function hasStackingContext(element) { 3 const style = getComputedStyle(element); 4 5 // Check isolation 6 if (style.isolation === 'isolate') return true; 7 8 // Check other properties that create stacking context 9 if (style.zIndex !== 'auto' && style.position !== 'static') return true; 10 if (style.opacity !== '1') return true; 11 if (style.transform !== 'none') return true; 12 if (style.filter !== 'none') return true; 13 14 return false; 15} 16 17// Debug z-index issues 18function logStackingContexts() { 19 document.querySelectorAll('*').forEach((el) => { 20 if (hasStackingContext(el)) { 21 console.log('Stacking context:', el, getComputedStyle(el).zIndex); 22 } 23 }); 24}

Best Practices#

Usage: ✓ Isolate components ✓ Contain z-index scope ✓ Fix blend mode bleeding ✓ Prevent z-index wars Benefits: ✓ No visual side effects ✓ Clean stacking context ✓ Predictable z-index ✓ Component encapsulation Patterns: ✓ Cards with overlays ✓ Modal containers ✓ Dropdown menus ✓ Tooltip systems Avoid: ✗ Using everywhere ✗ When not needed ✗ For performance only ✗ Instead of proper structure

Conclusion#

The isolation property creates stacking contexts without visual side effects. Use it to contain z-index values within components, preventing conflicts between independent UI elements. It's particularly useful for cards, modals, dropdowns, and any component with internal layering that shouldn't affect the page's global stacking order.

Share this article

Help spread the word about Bootspring