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

styles issue in 1.11.13

Open 80avin opened this issue 8 months ago • 7 comments

On upgrading html-to-image from 1.11.11 to 1.11.13 in https://github.com/80avin/jsontree/tree/cde2580307f9e6e891bc8326c5f5d3bf24edfdca I see the SVG & png are not drawn correctly. On inspecting, I find that the line modified in PR https://github.com/bubkoo/html-to-image/pull/384 is giving error

Error loading remote stylesheet SyntaxError: Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule

Strangely, the exact same rule passes in 1.11.13 and the only difference I see in the failing line was introduced in https://github.com/bubkoo/html-to-image/pull/384

Expected Behavior

Download image like

Image

Current Behavior

Image generated is

Image

Possible Solution

Steps To Reproduce

  1. Clone the project https://github.com/80avin/jsontree/tree/cde2580307f9e6e891bc8326c5f5d3bf24edfdca ( checkout to this commit if it is not latest )
  2. Update html-to-image to 1.11.13
  3. Run the app and click on download button in header
Error Message & Stack Trace

<!-- Provide a log message if relevant -->

Additional Context

Your Environment

  • html-to-image: 1.11.13
  • OS: Ubuntu 24.04
  • Browser: Version 134.0.6998.165 (Official Build) (64-bit)

80avin avatar Mar 30 '25 14:03 80avin

👋 @80avin

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 Mar 30 '25 14:03 biiibooo[bot]

@80avin

it could be font problem, try to add skipFonts: true

toPng( ref.current, { ....... skipFonts: true, } )

kdl-github-albert avatar Apr 03 '25 07:04 kdl-github-albert

@kdl-github-albert Confirmed, it is not font problem. Even with skipFonts: true, it fails.

80avin avatar Apr 03 '25 18:04 80avin

I am also seeing regressions. We upgraded from v1.11.11 -> 1.11.13

Image

<div style="width: 400px; height: 200px; position: relative; background-color: white; overflow: hidden; display: flex; justify-content: center; padding: 0px 10px;"><div style="width: calc(100% - 20px); height: auto; display: flex; flex-direction: column; align-items: center; overflow: hidden;"><table style="border-collapse: collapse;" cellspacing="0">
<tbody>
<tr>
<td style="background-color: #2f5496; vertical-align: top; width: 155px; border: 1px solid black;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;"><span style="color: white;">Project Phase</span></span></span></span></p>
</td>
<td style="background-color: #2f5496; border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: 1px solid black; vertical-align: top; width: 396px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;"><span style="color: white;">Activities in Scope</span></span></span></span></p>
</td>
<td style="background-color: #2f5496; border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: 1px solid black; vertical-align: top; width: 120px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;"><span style="color: white;">Estimated Hours</span></span></span></span></p>
</td>
</tr>
<tr>
<td style="background-color: #e7e6e6; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; border-top: none; vertical-align: top; width: 671px;" colspan="3">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;"><span style="color: black;">{technology} Cloud Build</span></span></span></span></p>
</td>
</tr>
<tr>
<td style="border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; border-top: none; vertical-align: top; width: 155px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">Deploy&nbsp;(2) Nodes within AWS per Region</span></span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 396px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">Our Services will assist with onboarding of the remote offices. We believe having three nodes per AWS Region will provide optimal High Availability (HA)</span></span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 120px;">
<p><span style="font-family: Calibri,sans-serif;"><span style="font-size: 16px;">16</span></span></p>
</td>
</tr>
<tr>
<td style="background-color: #e7e6e6; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; border-top: none; vertical-align: top; width: 552px;" colspan="2">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;"><span style="color: black;">Feedback and Environment Remediation</span></span></span></span></p>
</td>
<td style="background-color: #e7e6e6; border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 120px;">
<p>&nbsp;</p>
</td>
</tr>
<tr>
<td style="border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; border-top: none; vertical-align: top; width: 155px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">Solicit Initial feedback</span></span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 396px;">
<p><span style="font-family: Calibri,sans-serif;"><span style="font-size: 16px;">Work with initial pilot user groups to solicit feedback around the performance of the platform.&nbsp;</span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 120px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">5</span></span></span></p>
</td>
</tr>
<tr>
<td style="border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; border-top: none; vertical-align: top; width: 155px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">Environment Remediation</span></span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 396px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">Our Services will allocate up to <strong>10 project-hours</strong> for initial remediation as part of this engagement. Should more hours be needed, we will discuss it with the client project lead&nbsp;and provide an addendum to this scope definition upon mutual agreement.</span></span></span></p>
</td>
<td style="border-bottom: 1px solid black; border-left: none; border-right: 1px solid black; border-top: none; vertical-align: top; width: 120px;">
<p><span style="font-size: 11pt;"><span style="font-family: Calibri,sans-serif;"><span style="font-size: 12.0pt;">20</span></span></span></p>
</td>
</tr>
</tbody>
</table></div></div>

Renders

Image

With no options present (removed them during triage)

nicolasiscoding avatar Apr 08 '25 19:04 nicolasiscoding

+1 on this issue - it seems like style rendering overall is broken in 1.11.13

fristys avatar May 15 '25 12:05 fristys

any workarounds for this issue?

update: the below code worked for me...i m using nextjs with tailwind await toPng(ref.current, { includeQueryParams: true, filter: (node) => !node.classList?.contains('no-export'), });

amishaaggarwal avatar May 16 '25 09:05 amishaaggarwal

The css classes for SVGs are not applied after upgrading to 1.11.13. Works in 1.11.11

adityatoshniwal avatar May 27 '25 08:05 adityatoshniwal

import React, { useState } from "react"; import { Panel, useReactFlow, getNodesBounds } from "reactflow"; import { toPng } from "html-to-image"; import { Button } from "@mui/material"; import { Download } from "@mui/icons-material";

function downloadImage(dataUrl) { const a = document.createElement("a"); a.setAttribute("download", workflow-${Date.now()}.png); a.setAttribute("href", dataUrl); a.click(); }

function getEdgeBounds(nodes, edges) { let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;

nodes.forEach((node) => { const nodeX = node.position.x; const nodeY = node.position.y; const nodeWidth = node.width || 150; const nodeHeight = node.height || 50;

minX = Math.min(minX, nodeX);
minY = Math.min(minY, nodeY);
maxX = Math.max(maxX, nodeX + nodeWidth);
maxY = Math.max(maxY, nodeY + nodeHeight);

});

edges.forEach((edge) => { if (edge.sourceX && edge.sourceY && edge.targetX && edge.targetY) { minX = Math.min(minX, edge.sourceX, edge.targetX); minY = Math.min(minY, edge.sourceY, edge.targetY); maxX = Math.max(maxX, edge.sourceX, edge.targetX); maxY = Math.max(maxY, edge.sourceY, edge.targetY); } });

const edgePadding = 200; return { x: minX - edgePadding, y: minY - edgePadding, width: maxX - minX + edgePadding * 2, height: maxY - minY + edgePadding * 2, }; }

function DownloadButton() { const { getNodes, getEdges } = useReactFlow(); const [isDownloading, setIsDownloading] = useState(false);

const onClick = () => { setIsDownloading(true);

const reactFlowElement = document.querySelector(".react-flow");
const nodes = getNodes();
const edges = getEdges();

const bounds = getEdgeBounds(nodes, edges);

const viewportElement = document.querySelector(".react-flow__viewport");
const edgePaths = reactFlowElement.querySelectorAll(
  ".react-flow__edge-path"
);
edgePaths.forEach((path) => {
  path.setAttribute(
    "style",
    "stroke: #b1b1b7; stroke-width: 2; fill: none;"
  );
});
toPng(viewportElement, {
  backgroundColor: "#ffffff",
  width: bounds.width,
  height: bounds.height,
  pixelRatio: 2,
  style: {
    width: bounds.width,
    height: bounds.height,
    transform: `translate(${-bounds.x}px, ${-bounds.y}px) scale(1)`,
  },
})
  .then(downloadImage)
  .catch((error) => {
    console.error("Export failed:", error);
  })
  .finally(() => {
    setIsDownloading(false);
  });

};

return ( <Panel position="top-right"> <Button onClick={onClick} color="primary" variant="contained" disabled={isDownloading} sx={{ "&:hover": { backgroundColor: "#1565c0", }, }} startIcon={<Download />} > {isDownloading ? "Downloading..." : "Download Image"} </Button> </Panel> ); }

export default DownloadButton;

Just Create Download button and implement like this it will download perfect image :)

UsmanNaveed896 avatar Jul 01 '25 12:07 UsmanNaveed896

This is still a regression from 1.11.11. Are you going to publish a fix for this?

moklick avatar Oct 01 '25 09:10 moklick