solid icon indicating copy to clipboard operation
solid copied to clipboard

Canvas elements created via JSX fail to obtain WebGL context in older Chromium versions

Open ahzvenol opened this issue 5 months ago • 1 comments

Describe the bug

When testing compatibility with older browser versions, I found that canvas elements created via JSX cannot obtain a WebGL context properly.

The following three methods of creating a canvas element all return null when calling canvas.getContext('webgl'):

  • Embedding directly in a component:
const App = () => (<canvas ref={(canvas) => console.log()} />);
  • Assigning directly to a variable:
const canvas = <canvas width={1280} height={720} /> as HTMLCanvasElement;
  • Simulating the template function element creation:
const template = document.createElement('template');
template.innerHTML = `<canvas width="1280" height="720"></canvas>`;
const canvas = template.content.firstChild as HTMLCanvasElement;

However, a canvas created with document.createElement('canvas') can correctly obtain the WebGL context:

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl'); // Returns a WebGLRenderingContext as expected

Your Example Website or App

https://playground.solidjs.com/anonymous/38be721a-c90f-4e0b-8ee8-a7c47a3cbcd4

Steps to Reproduce the Bug or Issue

  1. Use Chromium version 86.0.4236.0.
  2. Create canvas elements via JSX.
  3. Call canvas.getContext('webgl') and observe that it returns null.

Expected behavior

Canvas elements created via JSX should be able to obtain WebGL contexts just like those created with document.createElement.

Screenshots or Videos

No response

Platform

  • OS: Windows 11
  • Browser: Chromium
  • Version: 86.0.4236.0

Additional context

The playground runs on a modern browser version, so the error cannot actually be observed there. Please run the code in an older browser version to reproduce the issue.

ahzvenol avatar Aug 10 '25 13:08 ahzvenol

https://issues.chromium.org/issues/40152715

I had a similar issue that sometimes element.animate() doesn't work (either in ref or in children()) because the element is still owned by the fragment. And using requestAnimationFrame causes a flash. My workaround is calling document.adoptNode(element) before .animate().

yume-chan avatar Aug 10 '25 19:08 yume-chan