2026-10-09 · 前端 / 验收 排错与验收
窄屏截图骗了我:headless 渲染的最小窗宽
起因:给站点做手机端验收
站点要上线,手机端总得看一眼。最省事的办法是用无头浏览器直接出一张窄图,命令大致是这样:
msedge --headless=new --window-size=390,2600 --screenshot=out.png <url>
参数很直白:宽 390、高 2600,够把整页一次拍完。看起来没什么可怀疑的地方,于是也就照着它下了结论。
现象:像 CSS 溢出了
图出来确实是 390 宽没错。但页面内容明显是按更宽的视口排的——文字一行行在右边被硬切掉,导航被挤掉一半。第一反应是"CSS 在窄屏溢出了"。
这个误判很容易发生,因为两种情况的观感几乎一样:内容超出容器、被右边裁掉。区别只在原因——一个是布局真的超了,一个是布局没错、但截图框比布局窄。
这里还有一个顺序上的问题:在确认原因之前动手改 CSS,方向就已经错了。如果毛病出在出图方式上,改了 CSS 只会把真机上本来正常的布局改坏,而截图里的"裁切"一点都不会变。所以第一件事不是修,是先分清这两者。
排查:换一个宽度做对照
于是把同一页改用 --window-size=500,1200 再出一张做对照。结果布局完全正常。
这就把 CSS 摘干净了:同一份样式,换个宽度就没事,说明问题不在页面,而在出图的方式。
结论:无头模式的布局视口有下限
真实原因是:无头模式的布局视口有一个约 500px 的最小宽度。你设 390,它仍然按 ~500 来布局;而截图只截 390 宽。布局在 500 上做,画面只留 390,于是看起来像被裁切——实际上右边那部分是"没截进来",不是"溢出去了"。
换句话说,布局宽度和截图宽度在这里不是一回事。这一点如果没意识到,就会一直在 CSS 里找一个根本不存在的 bug。
这也是无头截图最容易被误读的地方:它给你的画面是真的,但产生这个画面的条件和你以为的不一样。图本身不会骗人,是参数的含义会。
正确做法:走设备模拟
要真机手机版的效果,得走浏览器的设备模拟。这次用的是 iPhone-14 预设:390×844,截图 1170×2532,3 倍像素密度。据此确认该页在 390 下布局完全正常、没有溢出。
关键在于设备模拟给的是"这台设备真的这样渲染",而不是"一个被缩小的窗口"。前者可以用来验收,后者只能用来出图。两者看起来都是改宽度,实际不是一回事:设备模拟模拟的是一台设备,把窗口调窄只是让浏览器在一个更窄的窗口里渲染——而无头模式恰恰在这一点上有自己的下限。
落点
下次再用无头浏览器拍窄屏,先用 500 宽出一张做对照。如果"500 正常、390 被裁",基本就是这个假象,别去改 CSS 修一个不存在的 bug。
验收这件事最怕的不是测不出来,而是测出来一个假的。工具本身有边界,出图之前先确认它的边界在哪,比出完图再解释结果便宜得多。

