Search code examples
htmlcssclip-pathcss-mask

CSS mask and clip-path both obstruct other elements in on the page in Safari


I have a project where I need to use both clip-path and masks in order to get some sort of gradient coloring onto a div. I use the clip-path and mask to contain the colors within the borders of the div.

This works fine in both Chrome and Firefox. But in Safari other elements are still behind the masked elements and not able to have interactions. As you can see in the snippet bellow I have added 2 examples. One using clip-path and the other using mask. In Safari there is no interaction possible with the green div's.

#clip-container {
  width: 4rem;
  height: 3rem;
  background-color: yellow;
  clip-path: inset(0);
}

#clip-container::after {
  content: '';
  position: absolute;
  width: 5rem;
  height: 6rem;
  background-color: red;
}

#covered-container {
  width: 4rem;
  height: 2rem;
  background-color: green;
}

#covered-container:hover {
  background-color: purple;
}

#mask-container {
  margin-top: 3rem;
  width: 4rem;
  height: 3rem;
  border: 1px solid blue;
  -webkit-mask: linear-gradient(#fff 0 0);
  mask: linear-gradient(#fff 0 0);
}

#mask-container::after {
  content: '';
  position: absolute;
  width: 5rem;
  height: 6rem;
  background-color: pink;
}

#second-covered-container {
  width: 4rem;
  height: 2rem;
  background-color: green;
}

#second-covered-container:hover {
  background-color: purple;
}
<div id="clip-container"></div>
<div id="covered-container"></div>

<div id="mask-container"></div>
<div id="second-covered-container"></div>


Solution

  • Control the stacking context your self and don't leave the default one:

    #clip-container {
      width: 4rem;
      height: 3rem;
      background-color: yellow;
      clip-path: inset(0);
      position:relative;
      z-index:0;
    }
    
    #clip-container::after {
      content: '';
      position: absolute;
      z-index:-1;
      width: 5rem;
      height: 6rem;
      background-color: red;
    }
    
    #covered-container {
      width: 4rem;
      height: 2rem;
      background-color: green;
      position:relative;
    }
    
    #covered-container:hover {
      background-color: purple;
    }
    
    #mask-container {
      margin-top: 3rem;
      width: 4rem;
      height: 3rem;
      border: 1px solid blue;
      -webkit-mask: linear-gradient(#fff 0 0);
      mask: linear-gradient(#fff 0 0);
    }
    
    #mask-container::after {
      content: '';
      position: absolute;
      z-index:-1;
      width: 5rem;
      height: 6rem;
      background-color: pink;
    }
    
    #second-covered-container {
      width: 4rem;
      height: 2rem;
      background-color: green;
      position:relative;
    }
    
    #second-covered-container:hover {
      background-color: purple;
    }
    <div id="clip-container"></div>
    <div id="covered-container"></div>
    
    <div id="mask-container"></div>
    <div id="second-covered-container"></div>