2021年3月11日星期四

z-index of 3D-transformed objects

document.querySelector( 'style' ).innerHTML += `     /* rotation animations*/    .rotate_x, .rotate_y, .rotate_z, 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 ); }      }    .rotate_z { animation-name: rotateZ; }    @keyframes rotateZ {      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 ); }  /* EDIT: Some CSS was moved to the HTML and Javascript windows of the snippet  to completely eliminate scrolling for readability. No JavaScript is needed here
<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_z'> <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 inside of 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:

enter image description here

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 code below. 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?

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?

https://stackoverflow.com/questions/66592246/z-index-of-3d-transformed-objects March 12, 2021 at 07:53AM

没有评论:

发表评论