I have four HTML elements, and one of them is scrolling downward with a scroll effect. I want the green-colored div to always stay above Block B but below Block C. Additionally, I need Block C to become hidden behind Block B when they overlap. Also, the darker green element should be shown the same way as Block A.
Edit: Corrected Codesandbox.
Codesandbox
return (
<div className=" h-[200vh] w-full flex flex-col items-center">
<div className=" relative mt-[300px] bg-green-900 w-full h-[200px] text-black text-center flex flex-col justify-between text-white ">
<div className=" relative z-10">
Block A
</div>
</div>
<Image
src={borderSvgTexture}
className=" relative h-auto w-full min-w-screen mt-[-5px] "
alt=""
/>
<div className=" bg-blue-600 w-full h-[200px] mt-[-50px] ">
<div className=' mt-[100px] text-center'>Block B</div>
</div>
<motion.div
style={{ y }}
className="h-[500px] flex justify-center absolute inset-x-0 mx-auto max-w-[1800px] text-white"
>
<div className=" w-[100px] h-[100px] bg-red-500">Block C</div>
</motion.div>
</div>
)
I’ve tried various z-index combinations but can’t achieve the desired results, something unintended always ends up getting hidden. Now, I am not sure if this even possible.
3
Answers
To achieve the desired behavior with the HTML elements you described, you can follow these steps:
Place "Block C" inside "Block B" so that it becomes a child of "Block B."
Set a z-index for "Block B" higher than that of "Block C" to ensure it appears above "Block C" when they overlap.
Use position: relative for "Block A" to create a positioning context for the z-index.
Make sure "Block C" has position: absolute so you can control its position relative to its parent, "Block B."
Here’s how you can implement these changes in your code:
With these changes, "Block B" will have a higher z-index than "Block C," ensuring it appears above "Block C" when the elements overlap. At the same time, "Block A" retains its position and positioning context, allowing you to manage the stacked elements as desired.
I apologize for the oversight. To make sure "Block C" hides behind "Block B" when they overlap, you can adjust the z-index and positioning of the elements as follows:
In this updated code, I’ve added
z-10
,z-20
, andz-30
classes to control the stacking order. "Block A" and "Block B" have lower z-index values (10 and 20, respectively) to ensure that "Block C" (z-index 30) appears above them.With these adjustments, "Block C" should now hide behind "Block B" when they overlap.
I have created a solution to this based using the
Element:getBoundingClientRect()
for identifying component scroll positions and dimensions in react.Basically utilizing
useRef
hooks for getting the component properties, and getting thetop
andbottom
for thedivs
. We are able to define conditions when theBlock C
height
should shrink, expand, orz-index
changed.Updated: to include hiding behind the image pattern.
Take a look at the CodeSandbox, where I have implemented this method on a fork of your code. Note: On the sandbox sometimes randomly
Block C
is not visible initially.Please refresh when that happens to ensure all 3 blocks are visible, soinitialHeight
forBlock C
is properly capturedThe key function is described below, this listenToScroll is called via
useEffect
whenever the user scrolls as thescrollHandler
.Essentially it defines three conditions, for the
Block C
and affects theheight
andz-index
class