document.querySelector( 'style' ).innerHTML += `
/* rotation animations*/
.rotate_x, .rotate_y, span {
animation-name: rotateX;
animation-duration: calc( var( --duration ) * 1s );
animation-timing-function: linear;
animation-iteration-count: infinite;
}
@keyframes rotateX {
0% { transform: rotateX( 0deg ); }
100% { transform: rotateX( 360deg ); }
}
.rotate_y { animation-name: rotateY; }
@keyframes rotateY {
0% { transform: rotateY( 0deg ); }
100% { transform: rotateY( 360deg ); }
}
/* hidden circle inside cube */
hr {
position: absolute;
z-index: 1000;
border-style: none;
border-radius: 10rem;
width: 10rem; height: 10rem;
background-color: rgba( 50,200,150,1 );
}
`;
/* main */
:root {
font-size: 0.65rem; /* decreased font-size to fit cube in viewport */
--duration: 10;
--quarter_time: calc( var( --duration ) / 4 );
--eighth_time: calc( var( --duration ) / 8 );
--bright: 125; --mid: 100; --dark: 75;
}
* {
box-sizing: border-box;
transform-style: preserve-3d;
margin: 0; padding: 0;
}
html, body { height: 100%; }
body, span {
display: flex;
justify-content: center;
align-items: center;
}
body { perspective: 30rem; }
section, div, span {
position: absolute;
width: 10rem; height: 10rem;
}
span {
background-color: rgba( 50,150,200,1 );
}
div span:nth-of-type( 1 ) { transform: translateZ( 5rem ); }
div span:nth-of-type( 2 ) { transform: rotateY( 180deg ) translateZ( 5rem ); }
.left_right { transform: rotateY( 90deg ); }
.top_bottom { transform: rotateX( 90deg ); }
/* Note: Some CSS was moved to the HTML and Javascript windows of the snippet
only to eliminate scrolling and for readability on desktops.
<style>
/* face brightness animations*/
.x_lighting span { animation-name: frontFaces; }
.front_back span, .top_bottom span {
animation-duration: calc( var( --quarter_time ) * 1s );
animation-timing-function: ease-in-out; animation-direction: alternate;
}
.top_bottom span, .x_y_lighting .left_right span {
animation-direction: alternate-reverse;
}
@keyframes frontFaces {
0% { filter: brightness( calc( var( --bright ) * 1% ) ); }
100% { filter: brightness( calc( var( --dark ) * 1% ) ); }
}
.x_y_lighting .left_right span {
animation-name: sideFaces; animation-duration: calc( var( --eighth_time ) * 1s );
}
@keyframes sideFaces {
0% { filter: brightness( calc( var( --mid ) * 1% ) ); }
100% { filter: brightness( calc( var( --dark ) * 1% ) ); }
}
</style>
<body class='x_lighting x_y_lighting'>
<section class='cube_cont rotate_x'>
<section class='cube_wrap rotate_y'>
<section class='cube rotate_y'> <hr>
<div class='front_back'> <span></span><span></span> </div>
<div class='left_right'> <span></span><span></span> </div>
<div class='top_bottom'> <span></span><span></span> </div>
</section>
</section>
</section>
</body>
When you have a 3D constructed object in CSS ( such as a cube ) that has children elements located "inside" of that 3D object in 3D space and you want to show that child element through the parent or "on top of" the parent element - what is the best way to achieve such an effect?
This might be best understood visually so in the snippet above inside of the cube I have an hr
element in the HTML that I styled as a green circle. It can't be seen because its directly inside of the opaque cube but when you change the opacity of the cube you see it through the faces:
One line of code that appears ignored is the z-index I set on the hr
:
/* hidden circle inside cube */
hr {
position: absolute;
z-index: 1000;
border-style: none;
border-radius: 10rem;
width: 10rem; height: 10rem;
background-color: rgba( 50,200,150,1 );
}
I set the z-index
to 1000
however the expected result isn't displayed in the snippet above. To be clear:
How do I set the z-index of the child element greater than the parent element so the circle shows on top of the cube but keeps it's position in 3D space? ( without making the cube transparent )
There are questions like this: how-to-get-a-child-element-to-show-behind-lower-z-index-than-its-parent that have answers that rely on hacks using 3D transforms. Yet I can't do that here because my child and parent are 3D transformed objects themselves. Also these questions aren't exactly asking the same thing here. So what's a CSS solution to going about this?