we finally learned to center a div, then browsers added sidebars
摘要
文章讲的是作者在开发个人网站时,发现用现代 CSS(如 flex / grid)居中 div 在浏览器侧边栏(如 Firefox 的侧边栏)打开时,元素仍居中但相对于错误的矩形 —— 即 webview 而不是整个窗口。作者尝试用 JavaScript 获取窗口和 webview 宽度差来修正,但 DevTools 停靠会破坏计算。最终通过 pointer 事件获取屏幕坐标和 webview 内坐标,推算出 webview 在窗口中的位置,从而精确居中。作者还做了一个名为 “center, actually” 的书签工具,可在任意网页上自动寻找并修正居中元素。
荐读理由
文章给出了一个具体的浏览器兼容性问题及利用PointerEvent坐标推算webview位置的解决方案,并提供了可直接使用的书签工具,可迁移到需要精确居中的Web项目或浏览器扩展开发中。
原文
Centering a div used to require this little ritual:
.thing {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
These days, it is almost disappointingly easy:
body {
display: grid;
min-height: 100dvh;
place-items: center;
}
I used that for the .site div you’re reading. It looked centered until I opened it in a browser with the sidebar visible.
The .site div was still perfectly centered, just inside the wrong rectangle. I figured the fix would be simple enough: JavaScript knows the width of both the webview and the browser window.
window.innerWidth // the webview
window.outerWidth // the whole browser window
const browserChrome = window.outerWidth - window.innerWidth;
With the sidebar on the left, I could move .site back by half of that difference:
const shift = -browserChrome / 2;
.site {
translate: var(--window-center-shift, 0px);
}
That worked, right up until I opened DevTools.
devtools ruins the easy fix
Mine is docked on the right, so the width difference now included browser UI on both sides. It gave me the total, but no way to tell how that total was split.
What finally gave me the missing coordinate was the pointer. A trusted pointer event knows where it is on the screen and where it is inside the webview, which is enough to locate the webview inside the window:
const viewportLeft = event.screenX - event.clientX * scale;
const viewportRight = viewportLeft + innerWidth * scale;
const left = viewportLeft - window.screenX;
const right = window.screenX + outerWidth - viewportRight;
const shift = (right - left) / (2 * scale);
Firefox exposes the same viewport position directly. Chromium does not, so this site starts with the left-sidebar estimate and corrects it as soon as the pointer enters the page.
center, actually
I wanted to try the same fix on pages I do not control, so I made center, actually. It tries to find the centered element itself; if it guesses wrong, I can pick one. The demo is the simplest place to see the difference.
这条对你有帮助吗?