skip to Main Content

Note: I am well aware of how image masking can solve my problem but I do not wish to opt for it since in that case I will have to use my image as a background and that will cause accessibility issues. Some solution related clip-path is what I’m looking for.

Problem: The <rect>s in my SVG aren’t responding to changes in fillOpacity or opacity. The <rect>s need to be animated, hence I cannot manipulate the opacity of the entire image/SVG at once. I tried implementing the solutions provided here and here but none of those worked.

This is a react project and the here’s the HTML and CSS I’m talking about:

img {
  clip-path: url(#path-One);
  height: 60vw;
}
<div>
  <img src="https://images.unsplash.com/photo-1506399558188-acca6f8cbf41?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2173&q=80" alt="Big Data" />
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280.000000 673.000000">
    <clipPath id="path-One" transform="scale(1.127, 1.127)">
      <!-- Line 1: -->
      <rect width="10vw" height="10vw" fillOpacity="0" />
      <rect x="10vw" width="10vw" height="10vw" />
      <rect x="20vw" width="10vw" height="10vw" />
      <rect x="30vw" width="10vw" height="10vw" />
      <rect x="40vw" width="10vw" height="10vw" />
      <rect x="50vw" width="10vw" height="10vw" />
      <rect x="60vw" width="10vw" height="10vw" />
      <rect x="70vw" width="10vw" height="10vw" />
      <rect x="80vw" width="10vw" height="10vw" />
      <!-- Line 2: -->
      <rect y="10vw" width="10vw" height="10vw" />
      <rect x="10vw" y="10vw" width="10vw" height="10vw" />
      <rect x="20vw" y="10vw" width="10vw" height="10vw" />
      <rect x="30vw" y="10vw" width="10vw" height="10vw" />
      <rect x="40vw" y="10vw" width="10vw" height="10vw" />
      <rect x="50vw" y="10vw" width="10vw" height="10vw" />
      <rect x="60vw" y="10vw" width="10vw" height="10vw" />
      <rect x="70vw" y="10vw" width="10vw" height="10vw" />
      <rect x="80vw" y="10vw" width="10vw" height="10vw" />
      <!-- Line 3: -->
      <rect y="20vw" width="10vw" height="10vw" />
      <rect x="10vw" y="20vw" width="10vw" height="10vw" />
      <rect x="20vw" y="20vw" width="10vw" height="10vw" />
      <rect x="30vw" y="20vw" width="10vw" height="10vw" />
      <rect x="40vw" y="20vw" width="10vw" height="10vw" />
      <rect x="50vw" y="20vw" width="10vw" height="10vw" />
      <rect x="60vw" y="20vw" width="10vw" height="10vw" />
      <rect x="70vw" y="20vw" width="10vw" height="10vw" />
      <rect x="80vw" y="20vw" width="10vw" height="10vw" />
      <!-- Line 4: -->
      <rect y="30vw" width="10vw" height="10vw" />
      <rect x="10vw" y="30vw" width="10vw" height="10vw" />
      <rect x="20vw" y="30vw" width="10vw" height="10vw" />
      <rect x="30vw" y="30vw" width="10vw" height="10vw" />
      <rect x="40vw" y="30vw" width="10vw" height="10vw" />
      <rect x="50vw" y="30vw" width="10vw" height="10vw" />
      <rect x="60vw" y="30vw" width="10vw" height="10vw" />
      <rect x="70vw" y="30vw" width="10vw" height="10vw" />
      <rect x="80vw" y="30vw" width="10vw" height="10vw" />
    </clipPath>
  </svg>
</div>

2

Answers


  1. You can replace the clip path with a mask. There is no need for setting the image as a background. You can just use the CSS mask property.

    img {
      mask: url(#path-One);
      height: 60vw;
    }
    <div>
      <img src="https://images.unsplash.com/photo-1506399558188-acca6f8cbf41?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2173&q=80" alt="Big Data" />
      <svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
        <mask id="path-One" fill="white">
          <!-- Line 1: -->
          <rect id="tile" width="10vw" height="10vw" transform="scale(.99)" />
          <use href="#tile" x="10vw" fill-opacity=".5"/>
          <use href="#tile" x="20vw"/>
          <use href="#tile" x="30vw"/>
          <use href="#tile" x="40vw"/>
          <use href="#tile" x="50vw"/>
          <use href="#tile" x="60vw"/>
          <use href="#tile" x="70vw"/>
          <use href="#tile" x="80vw"/>
          <!-- Line 2: -->
          <use href="#tile" x="0vw" y="10vw"/>
          <use href="#tile" x="10vw" y="10vw"/>
          <use href="#tile" x="20vw" y="10vw"/>
          <use href="#tile" x="30vw" y="10vw"/>
          <use href="#tile" x="40vw" y="10vw"/>
          <use href="#tile" x="50vw" y="10vw"/>
          <use href="#tile" x="60vw" y="10vw"/>
          <use href="#tile" x="70vw" y="10vw"/>
          <use href="#tile" x="80vw" y="10vw"/>
          <!-- Line 3: -->
          <use href="#tile" x="0vw" y="20vw"/>
          <use href="#tile" x="10vw" y="20vw"/>
          <use href="#tile" x="20vw" y="20vw"/>
          <use href="#tile" x="30vw" y="20vw"/>
          <use href="#tile" x="40vw" y="20vw"/>
          <use href="#tile" x="50vw" y="20vw"/>
          <use href="#tile" x="60vw" y="20vw"/>
          <use href="#tile" x="70vw" y="20vw"/>
          <use href="#tile" x="80vw" y="20vw"/>
          <!-- Line 4: -->
          <use href="#tile" x="0vw" y="30vw"/>
          <use href="#tile" x="10vw" y="30vw"/>
          <use href="#tile" x="20vw" y="30vw"/>
          <use href="#tile" x="30vw" y="30vw"/>
          <use href="#tile" x="40vw" y="30vw"/>
          <use href="#tile" x="50vw" y="30vw"/>
          <use href="#tile" x="60vw" y="30vw"/>
          <use href="#tile" x="70vw" y="30vw"/>
          <use href="#tile" x="80vw" y="30vw"/>
        </mask>
      </svg>
    </div>
    Login or Signup to reply.
  2. You’re facing several problems:

    Fill colors and transparency

    Your mask elements are all black so they will make the masked image 100% transparent.
    Changing the fill-opacity from 1 to 0 wont’t have an effect – you need to apply a white fill color to your <rect> elements.

    svg {
      border: 1px solid red;
    }
    <h3>Works</h3>
    <svg width="220" height="100" viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
              <mask id="path-One">
                <g fill="#fff">
                <rect width="20" height="20" fill-opacity="0" />
                <rect x="20" width="20" height="20" fill-opacity="1" />
                <rect x="40" width="20" height="20" fill-opacity="0" />
                <rect x="60" width="20" height="20" fill-opacity="1" />
                <rect x="80" width="20" height="20" fill-opacity="0" />
                <rect x="100" width="20" height="20" fill-opacity="1" />
                <rect x="120" width="20" height="20" fill-opacity="0" />
                <rect x="140" width="20" height="20" fill-opacity="1" />
                <rect x="160" width="20" height="20" fill-opacity="0" />
                <rect x="180" width="20" height="20" fill-opacity="1" />
                <rect x="200" width="20" height="20" fill-opacity="0" />
                <rect y="20" width="20" height="20" fill-opacity="1" />
    
                <rect y="20" x="20" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="40" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="60" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="80" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="100" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="120" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="140" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="160" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="180" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="200" width="20" height="20" fill-opacity="1" />
    
                <rect y="40" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="20" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="40" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="60" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="80" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="100" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="120" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="140" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="160" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="180" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="200" width="20" height="20" fill-opacity="0" />
    
                <rect y="60" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="20" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="40" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="60" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="80" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="100" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="120" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="140" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="160" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="180" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="200" width="20" height="20" fill-opacity="1" />
    
                <rect y="80" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="20" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="40" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="60" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="80" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="100" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="120" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="140" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="160" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="180" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="200" width="20" height="20" fill-opacity="0" />
                  </g>
              </mask>
              <image width="100%" mask="url(#path-One)" href="https://images.unsplash.com/photo-1506399558188-acca6f8cbf41?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2173&q=80"></image>
            </svg>
    
    <h3>Doesn't work</h3>
    
    <svg width="220" height="100" viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
              <mask id="path-Two">
                <g >
                <rect width="20" height="20" fill-opacity="0" />
                <rect x="20" width="20" height="20" fill-opacity="1" />
                <rect x="40" width="20" height="20" fill-opacity="0" />
                <rect x="60" width="20" height="20" fill-opacity="1" />
                <rect x="80" width="20" height="20" fill-opacity="0" />
                <rect x="100" width="20" height="20" fill-opacity="1" />
                <rect x="120" width="20" height="20" fill-opacity="0" />
                <rect x="140" width="20" height="20" fill-opacity="1" />
                <rect x="160" width="20" height="20" fill-opacity="0" />
                <rect x="180" width="20" height="20" fill-opacity="1" />
                <rect x="200" width="20" height="20" fill-opacity="0" />
                <rect y="20" width="20" height="20" fill-opacity="1" />
    
                <rect y="20" x="20" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="40" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="60" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="80" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="100" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="120" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="140" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="160" width="20" height="20" fill-opacity="1" />
                <rect y="20" x="180" width="20" height="20" fill-opacity="0" />
                <rect y="20" x="200" width="20" height="20" fill-opacity="1" />
    
                <rect y="40" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="20" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="40" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="60" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="80" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="100" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="120" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="140" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="160" width="20" height="20" fill-opacity="0" />
                <rect y="40" x="180" width="20" height="20" fill-opacity="1" />
                <rect y="40" x="200" width="20" height="20" fill-opacity="0" />
    
                <rect y="60" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="20" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="40" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="60" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="80" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="100" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="120" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="140" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="160" width="20" height="20" fill-opacity="1" />
                <rect y="60" x="180" width="20" height="20" fill-opacity="0" />
                <rect y="60" x="200" width="20" height="20" fill-opacity="1" />
    
                <rect y="80" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="20" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="40" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="60" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="80" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="100" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="120" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="140" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="160" width="20" height="20" fill-opacity="0" />
                <rect y="80" x="180" width="20" height="20" fill-opacity="1" />
                <rect y="80" x="200" width="20" height="20" fill-opacity="0" />
                  </g>
              </mask>
              <image width="100%" mask="url(#path-Two)" href="https://images.unsplash.com/photo-1506399558188-acca6f8cbf41?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2173&q=80"></image>
            </svg>

    Mask HTML elements with svg masks

    Currently, only Firefox supports masking of HTML elements with inlined svg masks.

    As a workaround you might dynamically convert the svg to a dataURL.

    svgToMaskDataUrl( svgMask, imgMasked)
    
    function svgToMaskDataUrl( mask, maskedEl){
      let maskSvg = new XMLSerializer().serializeToString(mask)
      let dataURL = `data:image/svg+xml,`+ encodeURIComponent(maskSvg);
      maskedEl.style.webkitMaskImage=`url(${dataURL})`;
    }
    body {
      background: #ccc;
    }
    img {
      -webkit-mask-repeat: no-repeat;
      -webkit-mask-size: 100%;
      max-width:100%;
    }
    
    svg {
      border: 1px solid red;
    }
    <svg id="svgMask" viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; position:absolute;">
      <g fill="white">
        <rect width="20" height="20" fill-opacity="0" />
        <rect x="20" width="20" height="20" fill-opacity="1" />
        <rect x="40" width="20" height="20" fill-opacity="0" />
        <rect x="60" width="20" height="20" fill-opacity="1" />
        <rect x="80" width="20" height="20" fill-opacity="0" />
        <rect x="100" width="20" height="20" fill-opacity="1" />
        <rect x="120" width="20" height="20" fill-opacity="0" />
        <rect x="140" width="20" height="20" fill-opacity="1" />
        <rect x="160" width="20" height="20" fill-opacity="0" />
        <rect x="180" width="20" height="20" fill-opacity="1" />
        <rect x="200" width="20" height="20" fill-opacity="0" />
        <rect y="20" width="20" height="20" fill-opacity="1" />
    
        <rect y="20" x="20" width="20" height="20" fill-opacity="0" />
        <rect y="20" x="40" width="20" height="20" fill-opacity="1" />
        <rect y="20" x="60" width="20" height="20" fill-opacity="0" />
        <rect y="20" x="80" width="20" height="20" fill-opacity="1" />
        <rect y="20" x="100" width="20" height="20" fill-opacity="0" />
        <rect y="20" x="120" width="20" height="20" fill-opacity="1" />
        <rect y="20" x="140" width="20" height="20" fill-opacity="0" />
        <rect y="20" x="160" width="20" height="20" fill-opacity="1" />
        <rect y="20" x="180" width="20" height="20" fill-opacity="0" />
        <rect y="20" x="200" width="20" height="20" fill-opacity="1" />
    
        <rect y="40" width="20" height="20" fill-opacity="0" />
        <rect y="40" x="20" width="20" height="20" fill-opacity="1" />
        <rect y="40" x="40" width="20" height="20" fill-opacity="0" />
        <rect y="40" x="60" width="20" height="20" fill-opacity="1" />
        <rect y="40" x="80" width="20" height="20" fill-opacity="0" />
        <rect y="40" x="100" width="20" height="20" fill-opacity="1" />
        <rect y="40" x="120" width="20" height="20" fill-opacity="0" />
        <rect y="40" x="140" width="20" height="20" fill-opacity="1" />
        <rect y="40" x="160" width="20" height="20" fill-opacity="0" />
        <rect y="40" x="180" width="20" height="20" fill-opacity="1" />
        <rect y="40" x="200" width="20" height="20" fill-opacity="0" />
    
        <rect y="60" width="20" height="20" fill-opacity="1" />
        <rect y="60" x="20" width="20" height="20" fill-opacity="0" />
        <rect y="60" x="40" width="20" height="20" fill-opacity="1" />
        <rect y="60" x="60" width="20" height="20" fill-opacity="0" />
        <rect y="60" x="80" width="20" height="20" fill-opacity="1" />
        <rect y="60" x="100" width="20" height="20" fill-opacity="0" />
        <rect y="60" x="120" width="20" height="20" fill-opacity="1" />
        <rect y="60" x="140" width="20" height="20" fill-opacity="0" />
        <rect y="60" x="160" width="20" height="20" fill-opacity="1" />
        <rect y="60" x="180" width="20" height="20" fill-opacity="0" />
        <rect y="60" x="200" width="20" height="20" fill-opacity="1" />
    
        <rect y="80" width="20" height="20" fill-opacity="0" />
        <rect y="80" x="20" width="20" height="20" fill-opacity="1" />
        <rect y="80" x="40" width="20" height="20" fill-opacity="0" />
        <rect y="80" x="60" width="20" height="20" fill-opacity="1" />
        <rect y="80" x="80" width="20" height="20" fill-opacity="0" />
        <rect y="80" x="100" width="20" height="20" fill-opacity="1" />
        <rect y="80" x="120" width="20" height="20" fill-opacity="0" />
        <rect y="80" x="140" width="20" height="20" fill-opacity="1" />
        <rect y="80" x="160" width="20" height="20" fill-opacity="0" />
        <rect y="80" x="180" width="20" height="20" fill-opacity="1" />
        <rect y="80" x="200" width="20" height="20" fill-opacity="0" />
      </g>
    </svg>
    
    <img id="imgMasked" src="https://images.unsplash.com/photo-1506399558188-acca6f8cbf41?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2173&q=80" alt="Your Image" />
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search