Consider the following example app, which produces an output that looks like this:
JS (React)
export default function App() {
return (
<>
<div className="container">
<div className="animation">
<div className="scrollable">
{Array(10)
.fill(0)
.map((_, i) => (
<div className={`box ${i % 2 ? "" : "top"}`} />
))}
</div>
</div>
</div>
<div className="overlay" />
</>
);
}
CSS
.animation {
/* transform: scale(0.95); */
}
.scrollable {
display: flex;
}
.box {
width: 100px;
height: 100px;
margin-right: 10px;
flex-shrink: 0;
background: fuchsia;
}
.box.top {
z-index: 10;
}
.overlay {
position: fixed;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, 0.5);
}
We have a position: fixed overlay on top of a scrollable collection of pink boxes. The scrollable flex container is wrapped in an .animation class, which we want to apply a transform to (like transform: scale(0.95).
If we uncomment the transform line, all the boxes appear below the overlay, like so:
We can add position: absolute and z-index: 10 to the .animation class in order to place all the boxes on top of the overlay, but that isn't desired either. What we want is to allow some boxes to appear above the overlay, and others below, as shown in the first image above. We need to be able to manipulate the transform of the .animation class, so removing that is not an option.
Making the following adjustments on Safari does the trick, but does not seem to work on Chrome.
CSS
.animation {
transform: scale(0.95);
transform-style: preserve-3d;
}
.box.top {
z-index: 10;
transform: translateZ(10px);
}
Is it possible, without changing the HTML structure, to reliably achieve the desired effect?
You can find a Sandbox Here


You can use
nth-childpseudo class.You need to make overlay element and scrollable element in one parent.
Example: Code sandbox