Demo
https://jsfiddle.net/mg8zbr41/172/
(I hope this was the desired behaviour)
Explanation
The whole problem would have been solved if we were allowed to have overflow-x: auto
and overflow-y: visible
together. But we cannot do that (see this answer). So we use the following workaround.
- If you want to have want the red div to pop out you cannot put
position: relative
parent. So we remove that first - Now bottom becomes relative to parent relative element i.e. body but we don’t want that so we also remove
bottom
- Now we have
top
,right
,bottom
,left
all asauto
. So the elements placed below the green box as it would have been if it wasstatic
. The only difference is it pops out of the bottom box - Now we want it to be 10px above the green box for that we use
translateY(calc(100% + 10px) * -1)
- Now this works till there’s no scrolling. When the div is scrolled the red box stays there and doesn’t move with its green box, we need to fix that
- This can be easily fixed if we know how much is the div scrolled. Suppose the div is scrolled by 100px towards left we’ll shift the red box towards left by 100px
- We cannot find
scrollLeft
without JS. I personally don’t like JS intervention for styling. We cannot avoid it but at least we can make it more semantic by using css variables for communication between JS and CSS. - We use JS to update a
--scroll-left
css variable on#bottom-div
with thescrollLeft
value - Once we have
--scroll-left
we can now addtranslateX(calc(var(--scroll-left,0px) * -1))
- Also we don’t want the red box to pop out of the box horizontally. We cannot fix this by
overflow: hidden
because that would requireposition: relative
. So we useclip-path: inset(-999px 0px -999px 0px)
. - Finally we achieved want we wanted. Phew.
Demerits:
- Horizontal repositioning will be laggy in Firefox because of Scroll Lined Effects. Same might be the problem in mobile browsers
See also:
https://css-tricks.com/popping-hidden-overflow/ Source of inspiration for my answer but both (solution in the article and my solution) are quite different but same core approach
2
solved How to style element to overlap scroll