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
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.
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.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.