Html2canvas: Abnormal letter spacing in Chrome / Chromium

Created on 19 Nov 2017  ·  25Comments  ·  Source: niklasvh/html2canvas

When calling:

html2canvas(document.getElementsByClassName('console'), {
      onrendered: function(canvas) {
        var img = canvas.toDataURL()
        var iframe = '<iframe src="' + img + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>'
        var x = window.open();
        x.document.open();
        x.document.write(iframe);
        x.document.close();
      },
      letterRendering: true,
    });

Both with or without letterRendering, this is what Chrome outputs:

html2canvasbug

When the output in Firefox is:

screenshot-2017-11-19 http localhost

Any specific reason why it renders it like that?

Bug

Most helpful comment

I have fixed this also by going to the div I want to screenshot and then I set the " font-variant: normal; " this has worked for me hope it helps .

All 25 comments

The letter spacing (word spacing in this case) looks correct actually, what doesn't appear to be correct is the font family. Which version of html2canvas are you using? Can you replicate the issue on jsfiddle?

Edit: with letterRendering it should render differently as you mentioned.

Thanks for your reply,

I'm using the version 0.5.0-beta4.

What do you mean the work spacing looks correct? Are you referring to the first picture I have shared? Would the font create such spacing between words?

Note that I'm using CodeMirror for the text editor that is rendered, specifically an Angular wrapper: ng2-codemirror.

I tried reproducing the issue to no avail here.

I also found the same problem in firefox and chrome. If you have a letter-spacing css rule on the text it will render the text with large gaps between each word. This was not the case in version 0.4.1 it used to render text perfectly but it was missing pseudo elements(:before :after)

Once you remove the letter-spacing rule everything goes back to normal for you? I'm not using it, neither in my component's css nor in my custom code-mirror's css file.

Yes After removing the letter-spacing rule from the CSS the issue is gone. there are no large spaces between words. it's something in the rendering of the page at the part of the letter-spacing that is messing it up.

Update! I just built the library from the latest sources on master and it works perfectly. everything looks really good so far. Previously I tried with the v0.5.0-beta4 release.

Edit: Found 1 issue on firefox. background-images aren't being clipped to text when
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
are used.
works great in chrome though.

I don't use any letter-spacing property in my CSS and the issue is still present. I am using v0.5.0-beta4 though.

Try building from the latest master sources.

Done, and yet this does not solve the problem, the display remains the same.

Seems like the problem persists like such:

screenshot_2017-12-18_09-56-43

Here's how I rendered the element:

html2canvas(document.body).then(function(canvas) {      
      document.body.appendChild(canvas);
});    

I have downloaded the latest pre-release version as mentioned by you and replaced the old one.

@christopherkade does it fix it if you set the option letterRendering: true?

Sadly it does not, here's how I do it:

let element = document.getElementById('console');
const options = {
  letterRendering: true
};

html2canvas(element, options).then(function(canvas) {      
  document.body.appendChild(canvas);

  var url = canvas.toDataURL();
  var img = '<img src="' + url + '" style="border:0;"></img>'
  var x = window.open();
  x.document.open();
  x.document.write(img);
  x.document.close();
});

Same result if I try the example given in the repository.

I have found a workaround for the matter (and it's not very clean):

// Package used to detect the browser used by the user
const browser = detect();
const element = document.getElementById('console');

// Set up my options
let options = {};
// For some reason foreignObjectRendering solves the spacing issue on Chrome but gives an error on Firefox, so I detect the browser and apply the adequate options.
if (browser && browser.name === 'chrome') {      
  options = {
    useCORS: true,
    foreignObjectRendering: true
  };  
}

// Open the canvas in a new window
html2canvas(element, options).then(function(canvas) {
  const url = canvas.toDataURL();
  const img = '<img src="' + url + '" style="border:0;"></img>'
  const x = window.open();
  x.document.open();
  x.document.write(img);
  x.document.close();
});

Note that the error I get on Firefox when using the second option is as follows:

Uncaught (in promise): [Exception... \"Method not implemented\" ...

Same problem!!

Solved here by removing CSS attribute font-variant-numeric: proportional-nums from HTML body.

Fixed similar problem with removing font-variant: tabular-nums; (in antd.css)
2018-12-19 19 20 38

same problem with Arabic language any suggestion please ?

@mohafouad +1

Have you found any fix for this? Thank you.

@2xSamurai no :(

I have fixed this also by going to the div I want to screenshot and then I set the " font-variant: normal; " this has worked for me hope it helps .

fixed if I add font-variant: normal !important to outer div of whole content (in antd project)

same problem, drived me crazy
image

font-variant: normal !important not working

@Malarkey-Jhu's and @maaoui's answer solved my problem.

The problem I had: Font family wasn't working and spacing was very wonky. Sometimes I would have overlapping letters.

What I do: During export I call element.style.setProperty('font-variant', 'normal') on the element with the text, and this allows the font-family to show properly, and the spacing to not be all wonky. Then I remove that property after I've finished exporting.

Based on the above solutions, this issue is fixed for me by changing -webkit-font-variant-ligatures and font-variant-ligatures to normal in codemirror css file. I am using CodeMirror version 5.42.2.

Was this page helpful?
0 / 5 - 0 ratings