Get the actual visible height of the WordPress admin bar
You know the problem.
You’re working on a WordPress website. Everything looks fine.
Then you log in.
And there it is: the WordPress admin bar, casually messing with that fixed header, menu or overlay you just spent way too much time positioning perfectly.
Most of the time, I do what I suspect many developers do: add a quick 32px somewhere, maybe 46px for mobile, tell myself I’ll fix it properly later, and move on.
Well, here’s a slightly better way.
WordPress already moves the page
WordPress actually handles most of the problem for us. When the admin bar is visible, it adds a margin to the document to make room for it.
The annoying part is elements positioned relative to the viewport: fixed headers, fullscreen menus, overlays, modals, and so on.
For those, knowing that the admin bar is “usually 32px” isn’t particularly useful. What we really want to know is:
How much of the admin bar is actually visible right now?
Getting the visible height
Instead of hardcoding WordPress’s admin bar dimensions and breakpoints, we can ask the browser directly using getBoundingClientRect():
function updateAdminBarHeight() {
const adminBar = document.getElementById('wpadminbar');
if (!adminBar) {
document.documentElement.style.setProperty(
'--admin-bar-visible-height',
'0px'
);
return;
}
const rect = adminBar.getBoundingClientRect();
const visibleHeight = Math.max(
0,
Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 0)
);
document.documentElement.style.setProperty(
'--admin-bar-visible-height',
`${visibleHeight}px`
);
}
window.addEventListener('scroll', updateAdminBarHeight, { passive: true });
window.addEventListener('resize', updateAdminBarHeight);
updateAdminBarHeight();
What’s happening here?
The important bit is:
Math.max(
0,
Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 0)
);
getBoundingClientRect() gives us the position of the admin bar relative to the viewport.
From there, we calculate the intersection between the admin bar and the viewport.
If the whole bar is visible, we get its full height. If only 17px are visible, we get 17px. If it’s completely outside the viewport, we get 0.
Then we expose that value to CSS:
--admin-bar-visible-height
Using it in CSS
Now any viewport-fixed element can use the actual visible height of the admin bar:
.site-header {
position: fixed;
top: var(--admin-bar-visible-height, 0px);
}
The same variable can be reused for fullscreen menus, overlays or anything else that needs to stay below the admin bar.
One thing to keep in mind: moving a fixed header doesn’t move the rest of the document with it. You’ll still need to handle the space occupied by your header according to your layout.
This snippet isn’t trying to replace WordPress’s handling of the admin bar. It simply gives your CSS one useful piece of information that WordPress doesn’t: how many pixels of the admin bar are actually visible right now.
No hardcoded 32px. No 46px. No WordPress breakpoint to reproduce.
Just one of those tiny problems I’ve worked around countless times because finding a proper solution always felt like more effort than adding a magic number.
Turns out it wasn’t.