Search code examples
javascripthtmlcsssvg

CSS Invert colors in transparent svg element


in my html I have transparent svg circle. I need to invert colors on this svg circle, so I will see black circle with cyan text.

I tried to set .cursor__inner's fill to transparent with filter invert(1) (as you can see it on code snippet), but it didn't work.

.cursor {
  position: absolute;
  top: 0;
  left: 0;
}
.cursor__inner {
  fill: transparent;
  filter: invert(1);
}
p {
  color: red;
}
<svg class="cursor" width="64" height="64" viewBox="0 0 64 64">
  <circle class="cursor__inner" cx="32" cy="32" r="32" />
</svg>
<p>Hello World!</p>

I want to make this effect:

effect

I prefer solution with pure css.


Solution

  • One way of achieving the required result is close to the code given in the question.

    The color of the text in the p element is inverted so that the part lying over the circle has the color cyan. The background of the element containing the p and svg (in this snippet's case, the body) has a background of white set so the mix-blend-mode on the text takes the difference of the color (which is now #00ffff = cyan) and white (#ffffff) to take us back to red (#ff0000).

    As noted in comments, it's not possible to invert the SVG circle color as it has transparency so will always have that whatever RGB it has inverted so it's filled with a solid color.

    body {
      background: white;
      height: 100vh;
    }
    
    .cursor {
      position: absolute;
      top: 0;
      left: 0;
    }
    
    .cursor__inner {
      fill: black;
    }
    
    p {
      color: cyan;
      color: red;
      filter: invert(1);
      mix-blend-mode: difference;
    }
    <body>
      <svg class="cursor" width="64" height="64" viewBox="0 0 64 64">
          <circle class="cursor__inner" cx="32" cy="32" r="32" />
        </svg>
      <p>Hello World!</p>
    </body>