How CSS transform Creates a Stacking Context
Understand why adding CSS transform to an element unexpectedly changes z-index behavior by creating a new stacking context.
Detailed Explanation
The transform Stacking Context Trap
One of the most common z-index surprises occurs when you add a transform property to an element and suddenly its children's z-index behavior changes. This happens because any non-none transform value creates a new stacking context.
The Problem
/* Before: fixed header works fine */
.page { position: relative; }
.header { position: fixed; z-index: 100; top: 0; }
/* After: adding transform to .page breaks fixed positioning */
.page {
position: relative;
transform: translateX(0); /* creates stacking context! */
}
.header {
position: fixed; /* now fixed relative to .page, not viewport */
z-index: 100; /* only compared within .page's context */
}
Properties That Trigger This
transform: translateZ(0); /* GPU acceleration hack */
transform: translate3d(0,0,0); /* another GPU hack */
transform: scale(1); /* seemingly no-op */
transform: rotate(0deg); /* also seemingly no-op */
will-change: transform; /* even just declaring intent */
Common Scenarios
GPU acceleration hacks: Adding
transform: translateZ(0)orwill-change: transformto improve animation performance can break fixed-position children and z-index ordering.CSS animations: Elements with CSS keyframe animations using transform properties create stacking contexts while animating.
Hover effects: A hover transform on a parent can change the stacking order of its children unexpectedly.
Solutions
/* Instead of transform on parent, use isolation */
.page {
isolation: isolate; /* creates context without transform side effects */
}
/* Or move the transform to a wrapper that doesn't contain fixed elements */
.page-inner {
transform: translateX(0);
}
Detection
In your z-index system, mark any layer that uses transform, filter, opacity < 1, or will-change as creating a stacking context. This tool's "ctx" toggle helps you track these interactions.
Use Case
When a fixed-position header or sidebar suddenly stops being fixed after you add a CSS transform or animation to a parent element, understanding the stacking context creation helps you restructure the DOM or CSS to fix the issue.