Sticky sidebar not working in WordPress? Six causes and the fix for each
Last updated: 28 October 2026
You added position: sticky to a sidebar widget, or turned on WordPress's Sticky setting for a Group block, and the box still scrolls away with the page. CSS sticky has a few strict conditions, and WordPress themes break them in a handful of repeatable ways. Below are six causes, how to recognise each one with your browser's developer tools, and the CSS that fixes it.
We make a sticky widget plugin, Quicksloth Sticky Widget, so we are not neutral; most fixes below need no plugin. The CSS behaviour was checked on 27 October 2026 in a small test page in Chromium 153, one case at a time; what we say about specific themes comes from our tests on WordPress 7.1.3 in October 2026 with Twenty Twenty-Five, Astra, Kadence, GeneratePress, OceanWP and Twenty Twenty-One. We did not repeat the test page in Firefox or Safari.
Before you start: find the sticky element in DevTools
- Open a long post or page that shows the sidebar, logged out or in a private window, so caching and the admin bar do not confuse things.
- Right-click the widget and choose Inspect (Chrome, Edge and Firefox) or Inspect Element (Safari, with the Develop menu turned on).
- In the Elements panel, select the element that should stick: the one with your
position: stickyrule, or, for WordPress's own setting, the Group with the classis-position-sticky. - Open the Computed tab and check
positionandtop. Ifpositionis notsticky, your rule is not applied at all (a typo in the selector, a cache that serves old CSS, or, for the Group setting, a theme that does not turn it on: see cause 6). - Then walk up the tree of parent elements, one at a time, with the same tab open. Causes 2 to 4 show up there.
1. No top value
How to spot it: in Computed, position is sticky but top is auto.
A sticky element needs a threshold. MDN puts it this way: if both inset properties for an axis are auto, "on that axis the sticky value will behave as relative" (MDN, position). In our test page, a widget with position: sticky and no top scrolled away like any other box; adding top: 20px made it stay 20 px from the top of the window.
#text-2 {
position: sticky;
top: 20px;
}
2. A parent element has overflow set
How to spot it: walking up from the sticky element, one of the parents shows overflow, overflow-x or overflow-y as hidden, auto or scroll in Computed. Look at every level up to body and html: theme wrappers such as a "site" or "page" container are common places.
A sticky element sticks to its nearest ancestor with a "scrolling mechanism", which overflow creates when it is hidden, scroll, auto or overlay, "even if that ancestor isn't the nearest actually scrolling ancestor" (MDN, position). That ancestor usually does not scroll, so the element never moves. In our test page:
overflow: hiddenon a page wrapper stopped the widget from sticking, even though nothing inside the wrapper overflowed;overflow-x: hiddenalone, the kind of rule a theme adds to hide horizontal scrolling, stopped it too;overflow: clipon the same wrapper let it stick again.
The fix: on the element you found, set to clip every overflow property that is hidden. If both overflow-x and overflow-y show hidden, write overflow: clip; if only overflow-x does, write overflow-x: clip. A hidden left on the other axis keeps the box a scroll container: in our test page overflow: hidden plus overflow-x: clip still did not stick, while overflow: clip did. clip also hides what overflows but, as MDN says, "The element box is not a scroll container" (MDN, overflow). Use the theme's own selector, for example:
.site {
overflow: clip;
}
The theme set overflow for a reason, often to stop a wide element from causing a horizontal scrollbar, so check a few pages on a phone-sized window afterwards. If the value is auto or scroll because the box really scrolls, clip is not the right change: the sticky element then has to live outside that box.
3. The sidebar is no taller than its widgets
How to spot it: select the sidebar column (often aside, #secondary or .sidebar) and hover it in the Elements panel. If its highlighted box ends just below the last widget, while the content next to it goes on much further, the sticky widget has no room to move.
A sticky element stays inside its parent: it is "stuck" only until it meets the opposite edge of its containing block (MDN, position). When a theme lays out content and sidebar with flexbox and align-items: flex-start (or a grid with align-items: start, or floats), the sidebar is only as tall as its widgets. In our test page, align-items: flex-start on the row stopped the last widget from sticking, and align-self: stretch on the sidebar fixed it:
#secondary {
align-self: stretch;
}
This is also why sticky often works on the last widget only after the sidebar has been stretched. In a thread on the WordPress.org forums, a sticky last widget in GeneratePress started working for the poster once the content area became a flex row and the sidebar was given full height (they later reported trouble in Safari). If the sidebar is floated rather than a flex or grid item, align-self does nothing; the cleaner route is then the theme's own sticky sidebar option, if it has one, or a plugin.
4. You made the whole column sticky, and it is stretched
How to spot it: the sticky element is the sidebar column itself, and its highlighted box is as tall as the content next to it.
This is the reverse of cause 3. Flex and grid items stretch to the height of the row by default, so a sticky column is already as tall as its parent and has nowhere to go. In our test page, the stretched column scrolled away; align-self: flex-start made it only as tall as its widgets, and it stuck:
#secondary {
position: sticky;
top: 20px;
align-self: flex-start;
}
A column taller than the window sticks as soon as its top reaches the top value and hides its own lower part until its parent ends (in our test page a 1,500 px column stayed at 20 px with its bottom 720 px below the window edge); for a tall sidebar, make only the last widget sticky instead.
5. A fixed header covers it
How to spot it: the widget does stick, but its top is hidden behind the site header, or behind the black admin bar when you are logged in. In Computed, its top is smaller than the header's height.
A sticky element stops at its top value and does not know about other fixed elements. In our test page, with an 80 px fixed header, a widget with top: 0 stuck under the header; top: 100px kept it 20 px below. Measure the header's height in the Elements panel (the size shows in the tooltip) and add a gap:
#text-2 {
position: sticky;
top: 100px; /* 80 px header + 20 px gap */
}
For the admin bar, WordPress's own Sticky setting already moves the block down when you are logged in. In your own CSS you can add the bar's height with the variable used in Ollie's fix for sticky block headers: top: calc(20px + var(--wp-admin--admin-bar--height, 0px));, and set it back to 20px in a @media (max-width: 600px) rule, where the admin bar is not fixed, as Ollie does. If the header's height changes on small screens, set top again in a media query.
6. Block themes, Group blocks and block widgets
Blocks add their own layers, and three things go wrong more often there.
- The theme does not turn the Sticky setting on. WordPress offers Position → Sticky only on the Group block among the core blocks, and only on themes that turn it on. In our test with WordPress 7.1.3 on 26 October 2026, a Group saved with that setting stuck on Twenty Twenty-Five, Astra 4.14.1 and Kadence 1.5.2, and was a normal, non-sticky block on GeneratePress 3.6.1, OceanWP 4.2.7 and Twenty Twenty-One 2.9 (no
is-position-stickyclass in the page). How to spot it: the class is missing in the Elements panel. Our guide to making a widget sticky covers where the setting is and its limits. - The block sits in a wrapper as tall as itself. Template parts, block widgets in a classic widget area and some page builder widgets put an extra box around your block. If that box ends where your block ends, the block has no room to move (cause 3, one level down). Ollie describes exactly this for headers: the template part's
<header class="wp-block-template-part">wraps the sticky Group, and the fix is to make the wrapper sticky (Ollie, June 2025). In our test page, a sticky Group inside a wrapper of the same height scrolled away, and sticky on the wrapper worked. In the classic themes we tested, the wrapper of a block widget was the box with an ID likeblock-2: put the sticky rule on#block-2, not on the Group inside it, and check that the column around it leaves room (causes 2 and 3). - There is no real sidebar column. On a block theme the "sidebar" is usually the narrow column of a Columns block in a template. In our tests a sticky Group in that column stuck on Twenty Twenty-Five, Astra and Kadence; the Columns block stretches its columns to the row's height unless you set a vertical alignment. If yours does not, select the column in DevTools: if it ends where its content ends (for example after changing its vertical alignment), you are back to cause 3, and the sticky element needs a column that runs the full height.
Quick check list
| Cause | What DevTools shows | Fix |
|---|---|---|
No top | top: auto on the sticky element | Add top: 20px |
overflow on a parent | hidden, auto or scroll on any parent, also overflow-x alone | clip instead of hidden on every axis that has it, if nothing inside needs to scroll |
| Short sidebar | The sidebar's box ends at its last widget | align-self: stretch on the sidebar (flex or grid layouts) |
| Stretched sticky column | The sticky column is as tall as the content | align-self: flex-start on the column |
| Fixed header | The element sticks under the header | top = header height + gap |
| Blocks | No is-position-sticky class, or a wrapper as tall as the block | A theme that supports the setting, or sticky on the wrapper |
When CSS cannot do it
Sometimes none of these fixes is practical: the overflow is needed, the theme's markup cannot be changed, or you want the widget to stop before the footer rather than at the end of its column. Then a script has to measure the page and switch the element to a fixed position while you scroll. Quicksloth Sticky Widget uses position: sticky where the layout allows it and falls back to a fixed position with a placeholder where it does not. In our tests the plugin chose that fallback for a classic sidebar widget on Astra, GeneratePress, Kadence and OceanWP (the sidebar column ended well before the end of the page, or an ancestor had overflow), and the widget stayed in view on each of them.
The plugin is free in the WordPress.org Plugin Directory.
For the built-in options and the CSS that works in four popular themes, see sticky sidebar in Astra, GeneratePress, Kadence and OceanWP. More on what it does and what it does not do, how to make a widget sticky with and without a plugin, how to keep a table of contents in view and, if you use Fixed Widget (q2w3) today, the Fixed Widget alternative page. Still stuck with your theme? Write to support@quicksloth.dev with a link to the page.