csscss-mask

Css mask-image or mask-mode not working in safari


The mask-image or the mask-mode is not working on Safari.

The code below is from an answer submitted by user "herrstrietzel" in a previous post. He shares 2 solutions. The code below is his solution 2 titled "Replace CSS-clip path with a mask".

https://stackoverflow.com/a/78935950/23567682

:root{
  --mask : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><defs><path id='hex' d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></defs><rect width='100%' height='100%'/><use href='%23hex' fill='white' stroke='black'/></svg>");

  --hexfront : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><path fill='none' stroke='white' stroke-width='3' transform='scale(0.75)' transform-origin='50%' d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></svg>");
  
}


.hexagon {
  width: 200px;
  display: inline-block;
  margin: 0 5px;
  position:relative;
  line-height:0;
}

img {
  aspect-ratio:1/1.15;
  width: 100%;
  height:100%;
}



.mask{
  mask-image: var(--mask);
  mask-mode: luminance;
}


.mask:after {
  content: "";
  display: block;
  position: absolute;
  inset:0%;
  height: 100%;
  width: 100%;
  background-image: var(--hexfront);
}
<div class="hexagon">
  <div class="mask">
    <img src="https://images.unsplash.com/photo-1724884564497-f5024b7e2f93?q=80&w=257" />
  </div>
</div>


Solution

  • You can actually simplify the SVG to keep only the path and you won't need mask-mode

    :root{
      --mask : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><path d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></svg>");
      --hexfront : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><path fill='none' stroke='white' stroke-width='3' transform='scale(0.75)' transform-origin='50%' d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></svg>");
    }
    
    .hexagon {
      width: 200px;
      display: inline-grid;
      margin: 0 5px;
      mask-image: var(--mask);
    }
    
    .hexagon:after {
      content: "";
      grid-area: 1/1;
      background-image: var(--hexfront);
    }
    
    img {
      grid-area: 1/1;
      width: 100%;
      aspect-ratio:1/1.15;
      object-fit: cover;
    }
    <div class="hexagon">
        <img src="https://images.unsplash.com/photo-1724884564497-f5024b7e2f93?q=80&w=257" >
    </div>

    Another implementation using one element and multiple mask:

    img {
      --mask : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><path d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></svg>");
      --hexfront : url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 86.6 100'><path fill='none' stroke='white' stroke-width='3' transform='scale(0.75)' transform-origin='50%' d='M38.97 2.5q4.33-2.5 8.66 0l34.64 20q4.33 2.5 4.33 7.5l0 40q0 5-4.33 7.5l-34.64 20q-4.33 2.5-8.66 0l-34.64-20q-4.33-2.5-4.33-7.5l0-40q0-5 4.33-7.5l34.64-20z'/></svg>");
      width: 200px;
      aspect-ratio:1/1.15;
      object-fit: cover;
      mask: 
       var(--hexfront) exclude,
       var(--mask);
    }
    
    
    body {
      background: pink;
    }
    <img src="https://images.unsplash.com/photo-1724884564497-f5024b7e2f93?q=80&w=257" >