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