一个响应式调试浮层:断点、溢出、网格标尺
DevTools 的设备模式很好用,直到它碍事:它缩小你的视口、在调整尺寸时卡顿,而且它没法告诉你哪个元素导致了那条恼人的水平滚动条。本文构建一个轻量的响应式调试浮层,你直接注入到页面上 —— 一个实时尺寸徽章、当前断点名、一个「轮廓化一切」开关、一个溢出查找器和一个列标尺。把它和 JustZix 的 CSS 面板配对,你就能在同一个窗口里发现一个 bug 并修好它。
为什么页内浮层胜过设备模式
设备模式回答「这在 375px 下看起来怎样?」 —— 但大多数响应式 bug 不是关于某个特定宽度,而是关于过渡:一个不会折叠的外边距、一张固定宽度的图片、一个拒绝收缩的 flex 子项。对那些,你想要拖动你真实的浏览器窗口,实时看着数字变化。一个注入的浮层给你这个,以原生性能,且没有占用像素的浏览器外壳。
下面的一切是一条 JS 规则。注入一次;浮层会在你调整尺寸时自己更新。
实时视口徽章
从一个固定徽章开始,它显示当前视口的宽和高,并在每次调整尺寸时更新。
(() => {
document.getElementById('jz-resp')?.remove();
const bar = document.createElement('div');
bar.id = 'jz-resp';
Object.assign(bar.style, {
position: 'fixed', left: '10px', bottom: '10px',
font: '12px/1.5 ui-monospace, monospace',
background: '#111', color: '#fff',
padding: '6px 10px', borderRadius: '6px',
zIndex: 2147483600, pointerEvents: 'none',
whiteSpace: 'pre',
});
document.body.appendChild(bar);
function update() {
const w = window.innerWidth;
const h = window.innerHeight;
bar.textContent = w + ' × ' + h + 'px · ' + bpName(w);
}
window.addEventListener('resize', update);
update();
徽章坐在左下角,忽略指针事件所以它永不挡住点击,并搭载一个高到足以盖过几乎任何站点的 z-index。
给当前断点命名
一个原始的像素数很有用,但「我们在平板范围里吗?」才是你真正会问的问题。把宽度映射到名字 —— 调整这张表来匹配站点的框架(这些是 Tailwind 的默认值)。
function bpName(w) {
if (w >= 1536) return '2xl';
if (w >= 1280) return 'xl';
if (w >= 1024) return 'lg';
if (w >= 768) return 'md';
if (w >= 640) return 'sm';
return 'xs';
}
现在徽章读起来像 1024 × 768px · lg —— 而你拖过一个断点边界的那一刻,名字就翻转。那个即时反馈就是全部要点。
轮廓化每个元素
经典的「轮廓化一切」技巧暴露整个页面的盒模型 —— 你立刻看到游离的外边距、错位的列和意外的嵌套。把它做成一个开关,这样它不会碍事。
let outlined = false;
const styleEl = document.createElement('style');
document.head.appendChild(styleEl);
function toggleOutline() {
outlined = !outlined;
styleEl.textContent = outlined
? '* { outline: 1px solid rgba(255,0,0,.35) !important; }'
: '';
}
// Press 'o' to toggle outlines
window.addEventListener('keydown', e => {
if (e.key === 'o' && !e.metaKey && !e.ctrlKey) toggleOutline();
});
用 outline 而不是 border 很重要 —— 轮廓不占空间,所以切换它们不会让你正想检查的布局重排。
水平溢出查找器
这是值回整篇文章的功能。一条横向滚动条意味着某个元素比视口宽 —— 但是哪一个?遍历每个元素,标记任何右边缘越过 document.documentElement.clientWidth 的元素。
function findOverflow() {
document.querySelectorAll('.jz-of').forEach(n => {
n.classList.remove('jz-of');
n.style.outline = '';
});
const limit = document.documentElement.clientWidth;
const culprits = [];
document.querySelectorAll('*').forEach(el => {
const r = el.getBoundingClientRect();
if (r.right > limit + 1 || r.left < -1) {
culprits.push(el);
el.classList.add('jz-of');
el.style.outline = '3px solid #f0f';
}
});
console.log('%c' + culprits.length + ' overflowing element(s)',
'color:#f0f');
console.log(culprits);
return culprits;
}
// Press 'f' to find overflow
window.addEventListener('keydown', e => {
if (e.key === 'f' && !e.metaKey && !e.ctrlKey) findOverflow();
});
按下 f,每个碍事的元素都得到一道品红色轮廓;列表也落进 Output Console,这样你能检查每个节点。通常它就是一个元素 —— 一张固定宽度的图片、一个不换行的长字符串、一个负外边距 —— 而现在你精确知道是哪一个。
一个列 / 网格标尺
要检查内容是否对齐到网格,叠加均匀间隔的列。这会在视口上画一个带间隙的 12 列标尺。
function toggleRuler() {
let ruler = document.getElementById('jz-ruler');
if (ruler) { ruler.remove(); return; }
ruler = document.createElement('div');
ruler.id = 'jz-ruler';
Object.assign(ruler.style, {
position: 'fixed', inset: '0',
display: 'grid', gap: '16px',
gridTemplateColumns: 'repeat(12, 1fr)',
maxWidth: '1200px', margin: '0 auto',
padding: '0 16px',
zIndex: 2147483500, pointerEvents: 'none',
});
for (let i = 0; i < 12; i++) {
const col = document.createElement('div');
col.style.background = 'rgba(0, 120, 255, .12)';
ruler.appendChild(col);
}
document.body.appendChild(ruler);
}
// Press 'g' to toggle the grid ruler
window.addEventListener('keydown', e => {
if (e.key === 'g' && !e.metaKey && !e.ctrlKey) toggleRuler();
});
})();
让 maxWidth、gap 和列数匹配站点实际的网格。现在你能一眼看出标题、卡片和图片是否吸附到同样的线 —— 还是偏移了几个像素。
完整的键盘映射
- o —— 切换轮廓化一切。
- f —— 查找水平溢出的元凶。
- g —— 切换 12 列网格标尺。
- 尺寸徽章在每次调整尺寸时更新,不需要按键。
保留修饰键检查(!e.metaKey && !e.ctrlKey),这样快捷键不会和浏览器命令冲突。如果站点本身监听普通字母键,换成像 Alt+O 这样的。
把它和 CSS 面板配对
这个浮层告诉你什么出了错;JustZix 的 CSS 面板让你不离开标签页就修好它。工作流:
- 从 JS 面板注入浮层并运行它。
- 拖动你的窗口穿过断点,看着徽章。
- 看到一条滚动条出现?按
f,拿到元凶。 - 打开 CSS 面板,实时打补丁 ——
max-width: 100%、overflow-wrap: anywhere,它需要什么就给什么。 - 当它看起来对了,把 CSS 存进规则,让修复留下来。
另见
- 一个实时无障碍审计浮层 —— 同样的页内浮层方法用于无障碍。
- 为更好的 PDF 定制打印样式表 —— 为另一种媒介修复布局。
别再为设备模式诊断不了的 bug 与它搏斗。安装 JustZix,注入浮层,在你真实的浏览器里以全速调试响应式布局。
为这篇文章评分
暂无评分 — 成为第一个。