html-to-image icon indicating copy to clipboard operation
html-to-image copied to clipboard

background-clip: text (-webkit-background-clip) not working

Open LarchLiu opened this issue 2 years ago • 9 comments

Expected Behavior

I want to create colorful text with CSS

.heading {
  font-size: 5rem;
  font-weight: 700;
  line-height: 5rem;
  background-image: linear-gradient(45deg, #54c8fa, #be1cfa, #54c8fa);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  text-fill-color: transparent;
}

and show corrently

image

Current Behavior

I use toPng to generate image but the display is like this

screenshot

Possible Solution

Steps To Reproduce

https://stackblitz.com/edit/vitejs-vite-fscqgd?file=src%2FApp.vue

Additional Context5tr

Your Environment

  • html-to-image: [1.10.8]
  • OS: [macOS Big Sur 11.2.3]
  • Browser: [chrome 105.0.5195.125]

LarchLiu avatar Sep 21 '22 12:09 LarchLiu

👋 @LarchLiu

Thanks for opening your first issue here! If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can.

biiibooo[bot] avatar Sep 21 '22 12:09 biiibooo[bot]

+1

NicoADavite avatar Oct 24 '22 20:10 NicoADavite

I found that window.getComputedStyle can't get style of -webkit-background-clip, even if set -webkit-background-clip property manually it doesn't work too.

https://github.com/bubkoo/html-to-image/blob/f0b3cdf53836475e4a30e8a903f79e5561fec9c9/src/clone-node.ts#L82-L92

I try to set some other property.

      if (name === 'background-clip' && value === 'text') {
        targetStyle.setProperty(
          '--has-background-clip',
          value,
          sourceStyle.getPropertyPriority(name),
        )
      }

And then replace --has-background-clip to -webkit-background-clip

const _str = str.replace(/--has-background-clip/g, '-webkit-background-clip')

Yes, it works but i don't think it's a good solution. Check it in this commit

LarchLiu avatar Oct 25 '22 11:10 LarchLiu

I am also stuck with the same problem. It's very difficult not to use background-clip in my design. Please give me a hint to solve it.

tamakisaya avatar Dec 14 '22 05:12 tamakisaya

@tamakisaya

screenshot (1)

stackblitz demo

can try this branch ~

qq15725 avatar Jan 06 '23 10:01 qq15725

Before calling the toXXX API,You can try to override XMLSerializer.prototype.serializeToString in the following way

  const { serializeToString } = XMLSerializer.prototype;
  const clearTextBackgroundClip = (element) => {
    if (element.style?.webkitBackgroundClip === "text") {
      element.style.setProperty("-webkit-background-clip", "unset");
      element.style.setProperty("--background-clip-replace", "text");
    }
    element.childNodes.forEach((child) => {
      clearTextBackgroundClip(child);
    });
  };
  XMLSerializer.prototype.serializeToString = function (node) {
    clearTextBackgroundClip(node);
    return serializeToString
      .call(this, node)
      .replaceAll("--background-clip-replace", "-webkit-background-clip");
  };

kuangshy avatar May 16 '23 04:05 kuangshy

Hey team, Any update on this ?

MURUGAN96 avatar May 22 '23 08:05 MURUGAN96

+1

MJSPollard avatar Jul 12 '23 20:07 MJSPollard

+1

tried html2canvas and it doesn't support backgroud-clip:text and now trying this library and guess it doesn't support background-clip at all

yechukim avatar Oct 15 '23 10:10 yechukim