Canvas elements created via JSX fail to obtain WebGL context in older Chromium versions
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
- Use Chromium version 86.0.4236.0.
- Create canvas elements via JSX.
- Call
canvas.getContext('webgl')and observe that it returnsnull.
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.
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().