<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pixel Recruiting LLC</title>
    <description>The latest articles on DEV Community by Pixel Recruiting LLC (@pixelrecruiting).</description>
    <link>https://dev.to/pixelrecruiting</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4209609%2Fc7e5d4fb-0d23-40b0-96ac-7c189e9bc927.png</url>
      <title>DEV Community: Pixel Recruiting LLC</title>
      <link>https://dev.to/pixelrecruiting</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pixelrecruiting"/>
    <language>en</language>
    <item>
      <title>position: sticky Does Nothing? Hunt Down the Hidden Overflow</title>
      <dc:creator>Pixel Recruiting LLC</dc:creator>
      <pubDate>Thu, 29 Oct 2026 03:46:16 +0000</pubDate>
      <link>https://dev.to/pixelrecruiting/position-sticky-does-nothing-hunt-down-the-hidden-overflow-1k07</link>
      <guid>https://dev.to/pixelrecruiting/position-sticky-does-nothing-hunt-down-the-hidden-overflow-1k07</guid>
      <description>&lt;p&gt;You add &lt;code&gt;position: sticky&lt;/code&gt; and &lt;code&gt;top: 0&lt;/code&gt; to your header. You scroll. The header scrolls away like nothing happened.&lt;/p&gt;

&lt;p&gt;No error in the console. No warning in DevTools. Just a header that won't stick.&lt;/p&gt;

&lt;p&gt;This post explains the usual reason, shows a fix you can paste in, and gives you a small script that finds the problem for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Someone posted this in a CSS forum. Here is the gist, in our own words.&lt;/p&gt;

&lt;p&gt;They wanted the header on their page to stay at the top while the user scrolled. They added &lt;code&gt;position: sticky&lt;/code&gt;. Nothing changed. They had already worked through a popular checklist of "why sticky isn't working": siblings, parent height, z-index, browser support. Still no luck.&lt;/p&gt;

&lt;p&gt;The answer that solved it was one line far away from the header: a wrapper higher up the page had &lt;code&gt;overflow: hidden&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick version of how sticky works
&lt;/h2&gt;

&lt;p&gt;A sticky element acts like a normal element until you scroll it to a set point. Then it "sticks" there, until its parent box scrolls out of view.&lt;/p&gt;

&lt;p&gt;Two key words here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scroll container:&lt;/strong&gt; a box that can scroll its content. Elements with &lt;code&gt;overflow&lt;/code&gt; set to &lt;code&gt;hidden&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, or &lt;code&gt;scroll&lt;/code&gt; can be one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containing block:&lt;/strong&gt; for our purposes, the parent box that the sticky element lives inside.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Root cause 1: an ancestor with &lt;code&gt;overflow: hidden&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;MDN says a sticky element sticks to its nearest ancestor that has a "scrolling mechanism." That is created when &lt;code&gt;overflow&lt;/code&gt; is &lt;code&gt;hidden&lt;/code&gt;, &lt;code&gt;scroll&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, or &lt;code&gt;overlay&lt;/code&gt;. It sticks to that ancestor &lt;strong&gt;even if that ancestor never actually scrolls&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So here is what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A wrapper has &lt;code&gt;overflow: hidden&lt;/code&gt;, maybe to clip a rounded corner or stop a sideways scrollbar.&lt;/li&gt;
&lt;li&gt;The sticky header now sticks to that &lt;strong&gt;wrapper&lt;/strong&gt;, not to the page.&lt;/li&gt;
&lt;li&gt;The wrapper never scrolls. The page does.&lt;/li&gt;
&lt;li&gt;The header rides along with the wrapper and scrolls off the screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a small example that shows it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"page"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;My site&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;…lots of content…&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c"&gt;/* the hidden culprit */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;z-index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We tested this in Chrome 156 and Firefox 157. After scrolling 500px, the header's top edge was at -500px. It scrolled away completely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix A: remove the overflow
&lt;/h3&gt;

&lt;p&gt;If the &lt;code&gt;overflow: hidden&lt;/code&gt; isn't doing anything important, delete it. In our test the header then stayed at the top (top edge at 0px).&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix B: use &lt;code&gt;overflow: clip&lt;/code&gt; instead
&lt;/h3&gt;

&lt;p&gt;Often the overflow is there for a reason, like hiding content that sticks out. In that case, use &lt;code&gt;clip&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MDN explains the difference. &lt;code&gt;hidden&lt;/code&gt; gives the element a scrolling mechanism, so sticky treats it as a scroll container. &lt;code&gt;clip&lt;/code&gt; also hides the overflow, but the element is &lt;strong&gt;not&lt;/strong&gt; a scroll container. So the sticky header skips it and sticks to the page. In our test this fixed the header in both browsers.&lt;/p&gt;

&lt;p&gt;The trade-off: with &lt;code&gt;clip&lt;/code&gt;, nothing inside can be scrolled into view, not even with code. MDN warns that if there are focusable elements in the clipped area, keyboard users may not be able to reach them. Only use &lt;code&gt;clip&lt;/code&gt; when the clipped part has nothing interactive.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;overflow: clip&lt;/code&gt; support, per MDN's browser data: Chrome 90, Firefox 81, Safari 16.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix C: move the overflow somewhere else
&lt;/h3&gt;

&lt;p&gt;If you need &lt;code&gt;hidden&lt;/code&gt; (for example, you scroll that box with code), put it on an element that is &lt;strong&gt;not&lt;/strong&gt; an ancestor of the sticky element. For example, wrap only the content that needs clipping, and keep the header outside that wrapper.&lt;/p&gt;

&lt;h2&gt;
  
  
  The sneaky one: &lt;code&gt;overflow-x: hidden&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Many sites add this to stop a sideways scrollbar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"But I only hid the x direction!" you say. Here is the catch. MDN explains that when one direction is &lt;code&gt;visible&lt;/code&gt; and the other is not &lt;code&gt;visible&lt;/code&gt; or &lt;code&gt;clip&lt;/code&gt;, the &lt;code&gt;visible&lt;/code&gt; one behaves as &lt;code&gt;auto&lt;/code&gt;. So &lt;code&gt;overflow-x: hidden&lt;/code&gt; quietly turns &lt;code&gt;overflow-y&lt;/code&gt; into &lt;code&gt;auto&lt;/code&gt;. Now the box is a scroll container, and sticky breaks.&lt;/p&gt;

&lt;p&gt;The fix is to use &lt;code&gt;clip&lt;/code&gt; for that direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.page&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;overflow-x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;clip&lt;/code&gt; paired with &lt;code&gt;visible&lt;/code&gt; stays as is, so no scroll container is made. We tested both: &lt;code&gt;overflow-x: hidden&lt;/code&gt; broke the header, and &lt;code&gt;overflow-x: clip&lt;/code&gt; fixed it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about &lt;code&gt;html&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;This one surprised us, so we tested it too:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;th&gt;Header sticks? (Chrome 156, Firefox 157)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;overflow-x: hidden&lt;/code&gt; on &lt;code&gt;body&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;overflow-x: hidden&lt;/code&gt; on both &lt;code&gt;html&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;overflow-x: clip&lt;/code&gt; on both &lt;code&gt;html&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When only &lt;code&gt;body&lt;/code&gt; has it, browsers apply that overflow to the viewport (the browser window) instead, so sticky still works. When &lt;code&gt;html&lt;/code&gt; has it too, &lt;code&gt;body&lt;/code&gt; keeps its own overflow and becomes the trap. If you want a rule you never have to think about, use &lt;code&gt;overflow-x: clip&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Root cause 2: no offset set
&lt;/h2&gt;

&lt;p&gt;MDN notes that at least one inset (like &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, or &lt;code&gt;right&lt;/code&gt;) must be set to something other than &lt;code&gt;auto&lt;/code&gt;. Without it, &lt;code&gt;sticky&lt;/code&gt; acts just like &lt;code&gt;relative&lt;/code&gt;. We removed &lt;code&gt;top: 0&lt;/code&gt; in our test, and the header scrolled away.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sticky&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* required */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Root cause 3: the parent is too short
&lt;/h2&gt;

&lt;p&gt;A sticky element can only stick while its parent box is on screen. A common setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"site-header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Site title&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nav&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;…&lt;span class="nt"&gt;&amp;lt;/nav&amp;gt;&lt;/span&gt;   &lt;span class="c"&gt;&amp;lt;!-- sticky --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;…&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;nav&lt;/code&gt; is sticky, but its parent is the &lt;code&gt;header&lt;/code&gt;. Once the header scrolls away, the nav goes with it. In our test, the nav was at -440px after a 500px scroll.&lt;/p&gt;

&lt;p&gt;The fix: move the sticky element so its parent is the tall, scrolling part of the page. Here, put the &lt;code&gt;nav&lt;/code&gt; after the &lt;code&gt;header&lt;/code&gt;, as a sibling of &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to verify
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Find the trap with a script.&lt;/strong&gt;&lt;br&gt;
Paste this into the browser console. Change the selector to match your sticky element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// your sticky element&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getComputedStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;hidden|auto|scroll|overlay&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflowX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflowY&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sticky is trapped by:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflowX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;overflowY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It lists every ancestor that can trap your sticky element. Click a result to jump to it in the Elements panel. One note: if &lt;code&gt;body&lt;/code&gt; shows up and &lt;code&gt;html&lt;/code&gt; does not, the body's overflow may be going to the viewport. Check that case with the table above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Check the computed styles.&lt;/strong&gt;&lt;br&gt;
Select a suspect element and open the Computed tab. Look at &lt;code&gt;overflow-x&lt;/code&gt; and &lt;code&gt;overflow-y&lt;/code&gt;. Remember that a value you didn't write (like &lt;code&gt;auto&lt;/code&gt;) can show up because of the rule about pairs above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Measure while scrolling.&lt;/strong&gt;&lt;br&gt;
Scroll down, then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it sticks, you'll see your &lt;code&gt;top&lt;/code&gt; value, such as &lt;code&gt;0&lt;/code&gt;. If you see a negative number, it scrolled away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Test on a real page length.&lt;/strong&gt;&lt;br&gt;
Sticky only shows up when there's enough content to scroll. Test with real content, not a near-empty page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] The sticky element has &lt;code&gt;top&lt;/code&gt; (or another inset) set.&lt;/li&gt;
&lt;li&gt;[ ] No ancestor has &lt;code&gt;overflow: hidden&lt;/code&gt;, &lt;code&gt;auto&lt;/code&gt;, or &lt;code&gt;scroll&lt;/code&gt;, unless you want it to stick inside that box.&lt;/li&gt;
&lt;li&gt;[ ] Use &lt;code&gt;overflow: clip&lt;/code&gt; or &lt;code&gt;overflow-x: clip&lt;/code&gt; when you only need clipping.&lt;/li&gt;
&lt;li&gt;[ ] The sticky element's parent is tall enough to scroll through.&lt;/li&gt;
&lt;li&gt;[ ] Add a &lt;code&gt;background&lt;/code&gt; and &lt;code&gt;z-index&lt;/code&gt; so content doesn't show through or sit above it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;MDN: &lt;code&gt;position&lt;/code&gt; — &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/position" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/position&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MDN: &lt;code&gt;overflow&lt;/code&gt; — &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/overflow" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/CSS/overflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MDN browser compat data (&lt;code&gt;overflow: clip&lt;/code&gt;, &lt;code&gt;position: sticky&lt;/code&gt;) — &lt;a href="https://github.com/mdn/browser-compat-data" rel="noopener noreferrer"&gt;https://github.com/mdn/browser-compat-data&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Shared by PIXEL RECRUITING LLC, where we match companies with frontend, UI and design systems engineers. Direct staffing partner for Mastercard · &lt;a href="https://pixelrecruiting.com" rel="noopener noreferrer"&gt;pixelrecruiting.com&lt;/a&gt; · &lt;a href="mailto:info@pixelrecruiting.com"&gt;info@pixelrecruiting.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>frontend</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
