Search code examples
javascripthtmlcsstailwind-csscss-position

How can I make the shadow cover a component that has the css property "relative"


Below is a simple code, the essence of which boils down to the following: at the top of the page there is a shadow and if you scroll the page vertically, this shadow will be constantly visible, covering the components (except VideoComponent ) that are located in the div with id='sub'.

   <div id='main' class="flex h-full">
    <div class="absolute inset-0 shadow-[inset_0_10px_3px_red] pointer-events-none"></div>
    <div id='sub' class="overflow-auto" style="width: 100vw">
      <div class="h-[50vh] bg-blue-200">Some text</div>
      <div class="h-[50vh] bg-sky-200">Some text</div>
      <VideoComponent />
      <div class="h-[50vh] bg-teal-200">Some text</div>
      <div class="h-[50vh] bg-emerald-200">Some text</div>
    </div>
  </div>

You may ask why it is necessary to use the “relative” CSS property in VideoComponent.....I’ll explain. Since in VideoComponent I use html tag video and overlay text and photos on the video itself using the CSS property "absolute". In abbreviated form, this code looks like this:

 export function VideoComponent() {
  return (
    <div className="relative grid">
      <video className="aspect-video rounded-lg" ref={videoRef} />
      {needText && (
        <div className="absolute h-full w-full">
          <TextView />
        </div>
      )}
      {needPhoto && (
        <div className="absolute h-full w-full">
          <PhotoView />
        </div>
      )}
    </div>
  );
}

If a shadow passes through a VideoComponent, the shadow is no longer visible, meaning the VideoComponent covers the shadow. This happens because VideoComponent have the "relative" css property.

My question is this: how can I change the VideoComponent so that when scrolled it will be covered by a shadow and not break the current functionality in this component.

Perhaps, somehow you can influence not the VideoComponent, but the shadow (the first part of the code).

I would be grateful for any advice


Solution

  • Here's a demo of how the stacking order of absolute or relative elements can be influenced by z-index. You probably need either a negative z-index on your element that is showing up over the shadow, or a positive z-index on the shadow that is supposed to cover a relatively positioned element.

    Additionally, if the shadow just came later in the html than the relatively positioned element, it would have a higher priority in the stacking order as well.

    If you have any questions, I'm happy to answer.

    * {
      box-sizing: border-box;
    }
    
    #element-with-inset-shadow {
      position: absolute;
      inset: 0;
      box-shadow: inset 0 0px 10px 10px red;
      pointer-events: none;
    }
    
    #element-over-shadow {
      height: 50px;
      background-color: lightblue;
      position: relative;
    }
    
    #negative:checked ~ #element-over-shadow {
      z-index: -1;
    }
    
    #positive:checked ~ #element-with-inset-shadow {
      z-index: 1;
    }
    <label for="default">default</label>
    <input 
      checked
      type="radio" name="index-state" id="default" />
      <br>
    <label for="negative">
      negative z index for element over shadow
    </label>
    <input 
      type="radio" name="index-state" id="negative" />
      <br>
    <label for="positive">
      positive z-index on absolute shadow
    </label>
    <input 
      type="radio" name="index-state" id="positive" />
    
    <div id="element-with-inset-shadow"></div>
    <div id="element-over-shadow"></div>