如何设置Canvas铺满浏览器宽高且无滚动无溢出?
我太懂你这种被浏览器默认样式坑到的无奈了!你遇到的1-20像素滚动空白,大概率是浏览器给html/body加的默认margin/padding,或者Canvas默认的inline-block显示模式导致的垂直空白,再加上不同浏览器的默认样式差异,才会出现这种不一致的情况。下面给你一套稳的解决方案:
第一步:重置全局样式,消除默认边距
首先在CSS里把html和body的默认margin、padding清掉,同时让它们占满整个视口高度:
html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; /* 彻底防止滚动条意外出现 */ } canvas { display: block; /* 关键!消除inline元素自带的垂直基线空白 */ }
为什么要设置canvas { display: block; }?因为Canvas默认是inline-block,浏览器会给它留一点基线对齐的空白(大概几像素),这会导致页面高度超出视口,触发垂直滚动条。
第二步:正确设置Canvas宽高(含窗口 resize 适配)
用JS设置Canvas的绘图尺寸(也就是元素的width和height属性),同时监听窗口大小变化,实时更新:
const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); // 初始化和更新Canvas尺寸的函数 function resizeCanvas() { // 获取视口的实际宽高,这是最准确的取值 const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; // 设置Canvas的绘图尺寸(避免拉伸模糊) canvas.width = viewportWidth; canvas.height = viewportHeight; // 测试用的填充色,验证Canvas是否铺满 ctx.fillStyle = '#2ecc71'; ctx.fillRect(0, 0, canvas.width, canvas.height); } // 页面加载时执行一次 resizeCanvas(); // 监听窗口 resize 事件,实时更新尺寸 window.addEventListener('resize', resizeCanvas);
额外优化:适配高分辨率屏幕(可选)
如果你的Canvas在Retina屏幕上看起来模糊,可以加上设备像素比(DPR)的处理,这一步不影响滚动条,但能大幅提升显示效果:
function resizeCanvas() { const dpr = window.devicePixelRatio || 1; const viewportWidth = window.innerWidth * dpr; const viewportHeight = window.innerHeight * dpr; canvas.width = viewportWidth; canvas.height = viewportHeight; // 设置Canvas的显示尺寸为视口大小,避免缩放变形 canvas.style.width = `${window.innerWidth}px`; canvas.style.height = `${window.innerHeight}px`; // 缩放绘图上下文,适配高分辨率屏幕 ctx.scale(dpr, dpr); // 测试绘图(这里用视口原始尺寸即可,因为上下文已经缩放) ctx.fillStyle = '#2ecc71'; ctx.fillRect(0, 0, window.innerWidth, window.innerHeight); }
为什么你之前的方法没用?
你试的document.body.offsetWidth、clientWidth这些值,会受到body的margin/padding影响——比如Chrome默认给body加了8px margin,那offsetWidth就会比视口小16px,你把Canvas设成这个宽度后,再加上body的margin,整个页面宽度就会超出视口,触发滚动条。而window.innerWidth是直接获取视口的实际宽度,不受body样式影响,是最可靠的取值。
现在用这套方案,不管Chrome、Firefox还是Safari,都不会出现滚动条,Canvas能完美铺满整个视口~
内容的提问来源于stack exchange,提问作者Iaiao

