Search code examples
htmlcsscss-mask

Negative mask in CSS within the background image


I want to create a mask in css using png file but in a different way. Basically I don't want the mask to display the content underneath but I want it to CUT the content underneath and display everything else. So like negative mask. The important fact is that I want to mask the background image. Here is what I want to do::

example

I have 3 layers here. The first one is a video (html), then dotted background made as a repetitive background (CSS background) then a mask - needs to be png image as this will be the logo. I want the mask to remove the background underneath it and display the video.

.cont {
  width: 100%;
  height: 450px;
  position: relative;
  background: url("http://www.kamiennadlyna.pl/test/img/video-bg.jpg") no-repeat center;
}

.maska {
  width: 100%;
  height: 100%;
  background: url("http://www.kamiennadlyna.pl/test/img/mask.png") repeat;
  left: 0;
  bottom: 0;
  position: absolute;
  text-align: center;
  /*-webkit-mask-image: url("https://www.tucado.com/images/logo.png")*/
}
<div class="cont">

  <video autoplay muted loop id="myVideo">
          <source src="http://www.kamiennadlyna.pl/video.mp4" type="video/mp4" poster="http://www.kamiennadlyna.pl/test/img/video-bg.jpg">
        </video>

  <div class="maska">
  </div>

</div>

jsfiddle


Solution

  • New Answer

    Based on the update you can do the following. The idea is to consider an inverted version of your logo where you make the transparent part non-transparent (and the non-transparent part transparent) then you apply multiple mask layer to get what you want.

    I kept the same idea from the old answer. I am considering the logo at the center of the overlay:

    .overlay {
      --h:200px; /* height of the logo*/
      --w:200px; /* width of the logo */
    
      height:300px;
      background:radial-gradient(farthest-side,black 50%,transparent 52%) 0 0/8px 8px;
     
      -webkit-mask:
          linear-gradient(#fff,#fff) top   /100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) bottom/100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) left  /calc(50.1% - var(--w)/2) 100%,
          linear-gradient(#fff,#fff) right /calc(50.1% - var(--w)/2) 100%,
          url(https://i.ibb.co/1zDbtJw/logo.png) center/var(--w) var(--h);
      mask:
          linear-gradient(#fff,#fff) top   /100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) bottom/100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) left  /calc(50% - var(--w)/2) 100%,
          linear-gradient(#fff,#fff) right /calc(50% - var(--w)/2) 100%,
          url(https://i.ibb.co/1zDbtJw/logo.png) center/var(--w) var(--h);
      -webkit-mask-repeat:no-repeat;
      mask-repeat:no-repeat;
    }
    
    body {
      background:url(https://i.picsum.photos/id/44/800/800.jpg) center/cover;
    }
    <div class="overlay"></div>

    Here is a related question to explain how to obtain a new version of the logo: https://graphicdesign.stackexchange.com/q/63635

    We can also play with mask-composite and keep the original logo and it would be easier to adjust and change the position. Pay attention to the order of mask layers which is important here unlike the first example:

    .overlay {
    
      height:300px;
      background:radial-gradient(farthest-side,black 50%,transparent 52%) 0 0/8px 8px;
    
      -webkit-mask:
          linear-gradient(#fff,#fff),
          url(https://i.ibb.co/cKBT5WQ/logo.png) center/200px 200px;
      -webkit-mask-repeat:no-repeat;
      -webkit-mask-composite:source-out;
      mask:
          linear-gradient(#fff,#fff),
          url(https://i.ibb.co/cKBT5WQ/logo.png) center/200px 200px;
      mask-repeat:no-repeat;
      mask-composite:exclude;
    }
    
    body {
      background:url(https://i.picsum.photos/id/44/800/800.jpg) center/cover;
    }
    <div class="overlay"></div>


    Old answer

    I would build this with pure CSS without the need of images:

    .overlay {
      height:300px;
      /* the stripes */
      background:repeating-linear-gradient(to right,blue 0 10px,transparent 10px 20px);
      /* the mask*/
      -webkit-mask:
          linear-gradient(#fff,#fff) top   /100% 50px,
          linear-gradient(#fff,#fff) bottom/100% 50px,
          linear-gradient( 235deg,transparent 10%,#fff 9%) calc(50% - 600px) 50%/1200px calc(100% - 100px),
          linear-gradient(-235deg,transparent 10%,#fff 9%) calc(50% + 600px) 50%/1200px calc(100% - 100px);
      -webkit-mask-repeat:no-repeat;
      mask:
          linear-gradient(#fff,#fff) top   /100% 50px,
          linear-gradient(#fff,#fff) bottom/100% 50px,
          linear-gradient( 235deg,transparent 10%,#fff 9%) calc(50% - 600px) 50%/1200px calc(100% - 100px),
          linear-gradient(-235deg,transparent 10%,#fff 9%) calc(50% + 600px) 50%/1200px calc(100% - 100px);
      mask-repeat:no-repeat;
    }
    
    body {
      background:url(https://i.picsum.photos/id/44/800/800.jpg) center/cover;
    }
    <div class="overlay"></div>

    To understand the puzzle here is the gradient used for the mask with different coloration:

    .overlay {
      height:300px;
      background:
          linear-gradient(blue,blue) top   /100% 50px,
          linear-gradient(red,red)   bottom/100% 50px,
          linear-gradient( 235deg,transparent 10%,green  9%) 
             calc(50% - 600px)   50%  /    1200px calc(100% - 100px),
             /*          ^ this half of this ^ */
          linear-gradient(-235deg,transparent 10%,purple 9%) 
             calc(50% + 600px) 50%/1200px calc(100% - 100px);
      background-repeat:no-repeat;
    }
    
    body {
      background:url(https://i.picsum.photos/id/44/800/800.jpg) center/cover;
    }
    <div class="overlay"></div>


    Here is another syntax where I will be using CSS variables to easily control the triangle:

    .overlay {
      --h:200px; /* height of the triangle*/
      --w:200px; /* width of the triangle */
    
      height:300px;
      /* the stripes */
      background:repeating-linear-gradient(to right,blue 0 10px,transparent 10px 20px);
      /* the mask*/
      -webkit-mask:
          linear-gradient(#fff,#fff) top   /100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) bottom/100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) left  /calc(50% - var(--w)/2) 100%,
          linear-gradient(#fff,#fff) right /calc(50% - var(--w)/2) 100%,
          linear-gradient(to top right,#fff 49%,transparent 50%) calc(50% - var(--w)/4) 50%/calc(var(--w)/2) var(--h),
          linear-gradient(to top left ,#fff 49%,transparent 50%) calc(50% + var(--w)/4) 50%/calc(var(--w)/2) var(--h);
      -webkit-mask-repeat:no-repeat;
      mask:
          linear-gradient(#fff,#fff) top   /100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) bottom/100% calc(50% - var(--h)/2),
          linear-gradient(#fff,#fff) left  /calc(50% - var(--w)/2) 100%,
          linear-gradient(#fff,#fff) right /calc(50% - var(--w)/2) 100%,
          linear-gradient(to top right,#fff 49%,transparent 50%) calc(50% - var(--w)/4) 50%/calc(var(--w)/2) var(--h),
          linear-gradient(to top left ,#fff 49%,transparent 50%) calc(50% + var(--w)/4) 50%/calc(var(--w)/2) var(--h);
      mask-repeat:no-repeat;
    }
    
    body {
      background:url(https://i.picsum.photos/id/44/800/800.jpg) center/cover;
    }
    <div class="overlay"></div>