niklasvh / html2canvas

Screenshots with JavaScript
https://html2canvas.hertzen.com/
MIT License
30.56k stars 4.8k forks source link

Extra padding when set img display:block styles #2829

Open dohooo opened 2 years ago

dohooo commented 2 years ago

Please make sure you are testing with the latest release of html2canvas. Old versions are not supported and issues reported for them will be closed.

Please follow the general troubleshooting steps first:

Bug reports:

Extra padding when i set img display:block styles.

image

jsfiddle.

Specifications:

mccahan commented 2 years ago

I hit this issue as well - I've got a Pull Request in for a fix, but you may be able to work around it by adding this CSS to your page stylesheet:

    body > div:last-child > span + img {
      display: inline !important;
    }

In brief, the library measures text size information by appending a span containing the text with all the CSS applied and then a blank image, and then measuring how much the text displaces the image to determine the height of the text. The <img> element that gets appended doesn't set its own display property, so if you're setting the display to block for every image in the document it will add padding to the test image and incorrectly measure the height of the text, which results in the extra padding in the output.

The workaround is a little flimsy since it may cause unintended issues if you have images you're cloning that also match that CSS selector, but it works correctly in your jsfiddle.

dohooo commented 2 years ago

I hit this issue as well - I've got a Pull Request in for a fix, but you may be able to work around it by adding this CSS to your page stylesheet:

    body > div:last-child > span + img {
      display: inline !important;
    }

In brief, the library measures text size information by appending a span containing the text with all the CSS applied and then a blank image, and then measuring how much the text displaces the image to determine the height of the text. The <img> element that gets appended doesn't set its own display property, so if you're setting the display to block for every image in the document it will add padding to the test image and incorrectly measure the height of the text, which results in the extra padding in the output.

The workaround is a little flimsy since it may cause unintended issues if you have images you're cloning that also match that CSS selector, but it works correctly in your jsfiddle.

uh, yes in fact I found a work around that similar to yours.

img {
    display: initial !important;
}

I think it’s safer in any browsers.

XiDanko commented 2 years ago

I hit this issue as well - I've got a Pull Request in for a fix, but you may be able to work around it by adding this CSS to your page stylesheet:

    body > div:last-child > span + img {
      display: inline !important;
    }

In brief, the library measures text size information by appending a span containing the text with all the CSS applied and then a blank image, and then measuring how much the text displaces the image to determine the height of the text. The <img> element that gets appended doesn't set its own display property, so if you're setting the display to block for every image in the document it will add padding to the test image and incorrectly measure the height of the text, which results in the extra padding in the output.

The workaround is a little flimsy since it may cause unintended issues if you have images you're cloning that also match that CSS selector, but it works correctly in your jsfiddle.

they should merge your pull request already

ASCSam commented 1 year ago

I hit this issue as well - I've got a Pull Request in for a fix, but you may be able to work around it by adding this CSS to your page stylesheet:

    body > div:last-child > span + img {
      display: inline !important;
    }

In brief, the library measures text size information by appending a span containing the text with all the CSS applied and then a blank image, and then measuring how much the text displaces the image to determine the height of the text. The <img> element that gets appended doesn't set its own display property, so if you're setting the display to block for every image in the document it will add padding to the test image and incorrectly measure the height of the text, which results in the extra padding in the output.

The workaround is a little flimsy since it may cause unintended issues if you have images you're cloning that also match that CSS selector, but it works correctly in your jsfiddle.

Legend! You have no idea how many hours I spent, how many solutions that I tried and I also tried out basically every single one of those export image packages in the market, and each of them has some other issues that I just ended up come back to html2canvas.

arayutw commented 1 year ago

It would be very helpful if this could be addressed within the program(html2canvas).

Edu-hs commented 10 months ago

I hit this issue as well - I've got a Pull Request in for a fix, but you may be able to work around it by adding this CSS to your page stylesheet:

    body > div:last-child > span + img {
      display: inline !important;
    }

In brief, the library measures text size information by appending a span containing the text with all the CSS applied and then a blank image, and then measuring how much the text displaces the image to determine the height of the text. The <img> element that gets appended doesn't set its own display property, so if you're setting the display to block for every image in the document it will add padding to the test image and incorrectly measure the height of the text, which results in the extra padding in the output.

The workaround is a little flimsy since it may cause unintended issues if you have images you're cloning that also match that CSS selector, but it works correctly in your jsfiddle.

Legend!!!

Dude, you saved my life. Someone has to accept your pr ASAP

jacobglowdev commented 3 months ago

I was having the same issue in my angular app, and whilst the above solution did fix it, the implementation didn't.

Adding the img {display: inline !important;} rule to my stylesheet didn't work, instead I had to apply the CSS rule dynamically to the head element:

const style = document.createElement('style');

style.innerHTML = 'img { display: inline !important; }';

document.head.appendChild(style);

const canvas = await html2canvas(document.body);

document.head.removeChild(style);

Hopefully this is helpful to anyone else who had the same issue as me.