CSS size is not render size
A canvas has two sizes. CSS decides how large it appears on the page. The drawing buffer decides how many pixels WebGL renders. If these values drift apart, the scene can look blurry, stretched, or expensive. A good resize function reads the displayed size, updates the renderer drawing buffer, and then updates the camera projection.
Avoid setting canvas width and height in CSS alone and hoping Three.js will infer the rest. The renderer must know the real buffer size. At the same time, avoid letting `setSize` rewrite your CSS every frame. Pass `false` as the third argument so layout remains controlled by CSS.
Clamp pixel ratio
High-DPI screens can request two or three times as many pixels as the CSS size suggests. That can make a small phone canvas surprisingly expensive. Clamp renderer pixel ratio with `Math.min(window.devicePixelRatio, 2)` or even a lower value for heavy scenes. The difference is often invisible to users but very visible to battery and frame rate.
For static product viewers, sharpness matters. For animated shader backgrounds, smoothness may matter more. Make the pixel ratio choice per scene instead of copying one value across every project.
Resize when the container changes
Window resize is a start, but modern layouts can change canvas size without a full window resize. Sidebars open, tabs change, browser UI collapses, and CSS grid tracks shift. ResizeObserver is a better fit for tool panels and responsive hero scenes because it watches the actual container.
The render loop can call a cheap resize check before drawing, but do not trigger expensive work if width and height did not change. Compare the current renderer size to the target size, then update only when needed.
Test the awkward sizes
Responsive scenes often fail between common breakpoints. Test a narrow phone, a tablet width, and a very wide desktop. Check whether text overlays still have contrast, whether the object remains framed, and whether UI controls overlap the canvas. A technically responsive canvas can still produce a poor composition.
For AdSense-friendly pages, this testing also matters because layout quality affects perceived trust. A guide page with a broken hero canvas on mobile feels unfinished even if the article text is strong.
When this guide is the right tool
Use this guide when the problem is specific enough that a broad Three.js tutorial would waste time. The focus here is responsive in a real browser page: what to check first, what to measure, and what to avoid before the scene becomes harder to reason about.
The practical rule is simple: Read the canvas container size and call renderer.setSize with updateStyle set to false. If that sentence describes the scene in front of you, treat the article as a checklist. Read the explanation, copy the smallest useful code pattern, then test the result in a narrow mobile viewport and a wide desktop viewport before adding more polish.
Common mistake to avoid
The common mistake is treating Make a Three.js canvas responsive without blurry rendering as a visual tweak instead of a scene-system decision. Three.js problems often look like one broken line of code, but the actual issue is usually a chain: asset assumptions, renderer settings, camera math, material setup, interaction state, and page layout all meet inside the canvas.
That is why the safest fix is incremental. Start from a known-good scene, change one variable, and keep a visible diagnostic while testing. Clamp device pixel ratio so high-density screens do not destroy performance. When the scene works, remove temporary helpers and leave behind only the checks that make sense for users.
Publishing check
Before publishing, run the scene through three questions. Does the page remain useful if WebGL fails or the asset loads slowly? Does the same scene still read clearly on a phone? Can another developer understand the important settings without reverse-engineering the whole file?
The last pass should be boring on purpose: verify canvas size, console errors, mobile performance, source links, internal links, and the related guide path. Update camera.aspect and projection matrix whenever the render size changes. If any answer is fuzzy, fix that before introducing a new effect or a larger asset.
Resize helper
function resizeRenderer(renderer, camera, container) {
const width = Math.max(1, container.clientWidth);
const height = Math.max(1, container.clientHeight);
const current = renderer.getSize(new THREE.Vector2());
renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2));
if (current.x !== width || current.y !== height) {
renderer.setSize(width, height, false);
camera.aspect = width / height;
camera.updateProjectionMatrix();
}
}
FAQ
When should I use Make a Three.js canvas responsive without blurry rendering?
Use it when your Three.js scene has a focused responsive problem and you need a practical checklist before adding more visual polish.
Is the code snippet production-ready?
Treat the snippet as a clear starting point. Test it in your scene, adapt naming and paths, and verify behavior on mobile hardware before publishing.
What should I check after applying this guide?
Run the scene through mobile sizing, console errors, loading states, source links, and related guide paths so the page remains useful even when assets or WebGL fail.