javascriptanchorcss-houdinicss-paint-api

PaintWorklet isn't working inside anchor tag


Paint Worklet isn't working when it's placed inside an anchor tag.

Example Site: https://codepen.io/lonekorean/pen/aYoJPv

Above Example, Use

<div class="polka-dot"></div>

as

<a href="https://google.com"><div class="polka-dot"></div></a>

It's not working. See only background-color, not background-image: paint(polka-dot-fade). I think anchor tags and Paint Worklet crash somewhere in implementation.


Solution

  • This is actually intentional, to mitigate with a privacy leak that could happen if one were to paint :visited links. Here is a specs issue discussing this.
    Basically an evil website could tell which link has been visited by applying a paint() only for such links and check if the PaintWorklet has been called.
    So the current solution Chrome's team came with was to simply disable the PaintWorklet for all anchors with an href attribute, that is until the root problem gets properly addressed (but this will take time).

    For the time being, to workaround that issue, you'd have to wrap your anchor element inside an other element an apply the paint on that wrapper element.

    (Note that the bug also affects inner elements, so if you wanted to apply that paint on an element inside the anchor, that would become more complicated...)

    const url = URL.createObjectURL( new Blob( [ `
    class GreenPainter {
      paint(ctx, size, props) {
        ctx.fillStyle = "green";
        ctx.fillRect(0, 0, size.width, size.height);
      }
    }
    
    registerPaint('green', GreenPainter);
    ` ], { type:"text/javascript"} ));
    
    CSS.paintWorklet.addModule(url);
    .paint-me {
      background: paint(green);
    }
    div.paint-me {
      display: inline-block;
    }
    <a href="" class="paint-me">
      reproduces the bug
    </a>
    <div class="paint-me">
      <a href="">
        works around the bug
      </a>
    </div>