我们终于学会了如何让 div 居中,结果浏览器又加了侧边栏。
We finally learned to center a div, then browsers added sidebars

原始链接: https://seg6.space/posts/center-div/

使用 CSS Grid (`place-items: center`) 来居中元素虽然简单,但它会将内容锚定在可视视口,而非整个浏览器窗口。当侧边栏或开发者工具等元素出现时,“完美居中”的内容在视觉上会显得偏移。 为了解决这个问题,作者计算了相对于物理浏览器窗口居中元素所需的偏移量。虽然 `window.innerWidth` 和 `window.outerWidth` 提供了额外的总空间,但它们无法揭示这些空间在屏幕上是如何分布的。 突破点在于利用指针事件(`screenX` 和 `clientX`)来映射网页在浏览器窗口中的位置。虽然 Firefox 直接提供了此数据,但 Chromium 需要在用户与页面交互时进行修正更新。作者最终将此逻辑封装为一个名为“center, actually”的工具,该工具可以自动检测并居中那些用户无法直接控制代码页面上的元素。

这篇 Hacker News 讨论聚焦于用户 `seg6` 发布的一篇博客文章。作者编写了一个脚本,旨在让页面内容在浏览器侧边栏打开时,依然能保持与物理屏幕中心的对齐。 作者的初衷是防止页面内容在浏览器视口变窄时偏离中心。然而,社区的反应却是一边倒的批评。评论者们认为: * **视口与屏幕的区别**:网页内容应在“视口”(浏览器可用的显示区域)内居中,而非根据物理屏幕进行对齐。 * **用户自主权**:浏览器及其侧边栏受用户控制。试图“自作聪明”地干预布局的网站被视为“用户敌对”或“反设计”。 * **技术风险**:这种方法依赖于侵入性的黑客手段,会导致闪烁、布局故障及无障碍访问问题。 * **设计原则**:许多人认为,网站无权追踪或干涉窗口相对于屏幕或物理环境的位置。 面对关于无障碍性和标准布局行为的强烈抵制,作者承认了批评意见,认同该做法本质上是一种“黑客手段”,并考虑将该功能限制在个人浏览器插件中使用。
相关文章

原文

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.

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.

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.

联系我们 contact @ memedata.com