CSS position: sticky works in Chrome 56+, Edge 16+, Firefox 32+, Opera 42+, Samsung Internet 6.2+, and Safari 13+. Learn browser support, how it works, and fixes.

Prince Dewani
May 1, 2026
CSS Sticky is a position value in the W3C Positioned Layout spec that keeps an element in flow until a scroll threshold, then pins it to its scrolling ancestor. It works in Chrome 56+, Edge 16+, Firefox 32+, Opera 42+, Samsung Internet 6.2+, and Safari 13+ on macOS and iOS, while Internet Explorer never supported it.
This guide covers what CSS Sticky is, the browsers that support it, how it works, why it fails, and the best use cases.
CSS Sticky is the position: sticky value defined in the W3C CSS Positioned Layout Module Level 3 specification. An element with this value flows with the page like a relatively positioned box, then sticks to its nearest scrolling ancestor once the scroll position crosses a threshold set by top, right, bottom, or left.
CSS Sticky works in every major modern browser, with full unprefixed support in Chrome 56+, Edge 16+, Firefox 32+, Safari 13+ on macOS and iOS, Opera 42+, and Samsung Internet 6.2+. Internet Explorer never added it.
Chrome supports position: sticky from Chrome 56 on Windows, macOS, Linux, ChromeOS, and Android. The unprefixed value works without any flags. Chrome 56 to 90 supported sticky on most elements but not on table cells, table headers, or table rows; full table-element support landed in Chrome 91 and later.
Microsoft Edge supports position: sticky from legacy EdgeHTML 16+ and from Chromium Edge 79+ on Windows, macOS, and Linux. Legacy EdgeHTML 12 to 15 did not support it. Edge 16 to 18 and Chromium Edge 79 to 90 had the same table-element gap as Chrome; full sticky on table cells works from Edge 91 and later.
Firefox supports position: sticky from Firefox 32 on Windows, macOS, Linux, and Android. Firefox shipped the unprefixed value first among major browsers. Firefox 32 to 58 did not support sticky on table headers, table cells, or table rows; Firefox 59 and later support sticky on every element type, including inside CSS tables.
Safari supports position: sticky from Safari 13 on macOS and from Safari on iOS 13. Earlier versions, Safari 6.1 to 12 on macOS and iOS 6.1 to 12, supported the property only with the -webkit-sticky prefix declared before the unprefixed value. Safari is the only modern browser that ever required this prefix, so any site that targets older Apple devices should ship both lines.
Opera supports position: sticky from Opera 42 with the -webkit-sticky prefix and from Opera 78 unprefixed on Windows, macOS, and Linux. Modern Opera is built on Chromium, so it follows the same table-element timeline as Chrome and supports sticky on every element from Opera 78 and later. Opera Mobile supports sticky from Opera Mobile 80 on Android.
Samsung Internet supports position: sticky from Samsung Internet 6.2 on Galaxy phones and tablets. It is built on Chromium, so it follows the same table-element rules as Chrome for Android. Use the unprefixed value in modern Samsung Internet builds; the -webkit-sticky prefix is no longer required.
Chrome for Android supports position: sticky from Chrome for Android 56 on Android 5 and later. Android WebView, the engine behind hybrid apps, supports sticky from WebView 56 on the same Android floor. The legacy stock Android Browser shipped with the AOSP build never added position: sticky support and is no longer maintained.
Internet Explorer 11 and every earlier version do not support position: sticky. IE treats sticky as an invalid value and falls back to position: static, which leaves the element in normal flow with no scroll pinning. Microsoft has retired Internet Explorer, so audiences on IE should use a JavaScript polyfill such as Stickyfill or be migrated to Edge.
Note: CSS Sticky breaks across older Safari, Internet Explorer, and many overflow-trapped layouts. Test it on real browsers and OS with TestMu AI. Try TestMu AI free!
A sticky element behaves like a relatively positioned element until its computed scroll position crosses the threshold you set, and then the browser pins it to that side of the nearest scrolling ancestor for the rest of the scroll.
The browser walks up the DOM tree to find the nearest ancestor whose overflow property is scroll, auto, hidden, or overlay. That ancestor becomes the sticky element's scrolling container, and the element is pinned inside that container only, not the entire viewport. When the user scrolls past the bottom of the container, the sticky element scrolls away with it because it never leaves normal document flow.
A sticky element always creates a new stacking context, which keeps z-index conflicts predictable. At least one of top, right, bottom, or left must be set to a non-auto value for the axis you want to stick on; if both inset properties on an axis are auto, the element behaves like position: relative on that axis.
Use this snippet in the DevTools console to confirm that the current browser supports position: sticky:
// Run in the DevTools console to test position: sticky support.
const probe = document.createElement("div");
const test = (value) => {
probe.style.position = "";
probe.style.position = value;
return probe.style.position === value;
};
const unprefixed = test("sticky");
const webkitPrefixed = test("-webkit-sticky");
console.log("Unprefixed sticky:", unprefixed ? "yes" : "no");
console.log("-webkit-sticky:", webkitPrefixed ? "yes" : "no");
if (!unprefixed && !webkitPrefixed) {
console.warn("This browser falls back to position: static.");
}If both checks return no, the browser will silently fall back to position: static and ignore the inset values. The most common false-negative is a typo in the property string, so always log both the unprefixed and the -webkit-sticky probes when you debug.
Most position: sticky failures are layout problems, not browser bugs. The element stays in normal flow because one of the conditions the spec requires is not met by the parent chain or the inset values.
In my experience, the overflow trap is the failure that wastes the most engineering time. A reset stylesheet from a UI kit or a layout grid often sets overflow: hidden on a wrapper three or four levels up the tree, and DevTools will not flag it as the cause because the sticky element itself looks correct. When sticky silently fails, walk every ancestor up to the body and check each computed overflow value before changing anything else.
CSS Sticky replaces a long list of JavaScript scroll listeners with a single CSS declaration, which is why product teams reach for it in nearly every modern interface. The pattern delivers smooth scroll-pinning at native frame rates with no event handlers.
All CSS Sticky version numbers and platform notes in this guide come from these primary sources:
Did you find this page helpful?
More Related Hubs
TestMu AI forEnterprise
Get access to solutions built on Enterprise
grade security, privacy, & compliance