Search code examples
csssvgcanvasmaskingclipping

Single, fixed position clipping region in css affecting only images


I need a single, fixed position clipping region (or a fullscreen mask) which will affect only images in my page.

Imagine a circled clip-path in the center of the screen. I need the images to be partially visible only on scroll inside this clipping region.

How can i achieve this?

This is what i tried so far:

#mask {
  left 0;
  position: fixed;
  top: 0;
}

.test {
    clip-path: url(#clipRegion);
}
<div class="site">

  <svg id="mask" view-box="0 0 800 600" width="800" height="600">
    <defs>
      <clipPath id="clipRegion">
        <circle cx="400" cy="300" r="100" />
      </clipPath>
    </defs>
  </svg>
  
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vestibulum, dui ac pellentesque volutpat, nisi dui interdum metus, vitae pellentesque tortor sem sit amet nisl. Pellentesque commodo arcu et eleifend efficitur. Nunc id tempus enim. Suspendisse mi lectus, faucibus non bibendum a, dapibus sed leo.</p>
  
  <img class="clip" src="https://picsum.photos/400/900?image=1069">
  
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vestibulum, dui ac pellentesque volutpat, nisi dui interdum metus, vitae pellentesque tortor sem sit amet nisl. Pellentesque commodo arcu et eleifend efficitur. Nunc id tempus enim. Suspendisse mi lectus, faucibus non bibendum a, dapibus sed leo.</p>
  
  <img class="clip" src="https://picsum.photos/900/500?image=1059">

</div>

Other solutions other than svg are appreciated. Thanks in advance for any suggestion!


Solution

  • I think you need to create a layer that will cover all the screen then use z-index to place all the image behind it and keep the other element above.

    here is an idea with a simple div and without any complex SVG or mask:

    .mask {
      left 0;
      top: 0;
      position: fixed;
      height: 100%;
      width: 100%;
      background: radial-gradient(circle at center, transparent 40%, #fff 40.5%);
      z-index: -1;
    }
    
    p,
    img {
      position: relative;
    }
    
    .clip {
      z-index: -2;
    }
    
    body {
      margin: 0;
    }
    <div class="site">
      <div class="mask"></div>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vestibulum, dui ac pellentesque volutpat, nisi dui interdum metus, vitae pellentesque tortor sem sit amet nisl. Pellentesque commodo arcu et eleifend efficitur. Nunc id tempus enim. Suspendisse
        mi lectus, faucibus non bibendum a, dapibus sed leo.</p>
    
      <img class="clip" src="https://picsum.photos/600/700?image=1069">
    
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vestibulum, dui ac pellentesque volutpat, nisi dui interdum metus, vitae pellentesque tortor sem sit amet nisl. Pellentesque commodo arcu et eleifend efficitur. Nunc id tempus enim. Suspendisse
        mi lectus, faucibus non bibendum a, dapibus sed leo.</p>
    
      <img class="clip" src="https://picsum.photos/900/500?image=1059">
    
    </div>