I have a page with a static main header, a sticky header spanning the page, and underneath that, a sticky sidebar. At the bottom is a footer that also spans the page. The sidebar itself can have a scrollbar. View Codepen example.
+---------------------------------------------------------------------+
| static main header |
+---------------------------------------------------------------------+
| sticky subheader |
|---------------------------------------------------------------------|
| content area | sidebar |
| content area | sidebar |
| content area | sidebar |
| content area | sidebar |
| content area | sidebar |
|---------------------------------------------------------------------|
| static footer |
+---------------------------------------------------------------------+
I want both the top and the bottom of the sidebar to always be within the viewport.
When I'm at the very top of the document the top of the sidebar appears below the sticky subheader. The bottom of the sidebar may extend at most to the very bottom edge of the viewport.
When I scroll far enough down that the footer enters the viewport, I want the sidebar's max height to shrink so the top of the sidebar can't get pushed up past the bottom edge of the sticky subheader.
To do this it seems I need use at least a scroll handler and a resize event handler. However, I think there must be a more robust and performant way of achieving what I want.
This doesn't show in my simple Codepen example, but in my actual use case, when I reach the bottom of the page there's a brief bit of visual jankiness when the max height is briefly higher than it should be, and the top of the sidebar gets pushed up above the bottom edge of the sticky subheader. Then the new max height is applied and the sidebar suddenly shrinks to fit, as desired.
How can I make this better? Maybe a creative use of ResizeObserver or IntersectionObserver?