坐标系

在指定图形上下文中的像素位置时(就像在代数中指定坐标系一样),它的位置是相对于上下文中的固定点定义的。这个固定点称为原点。位置指定为沿上下文每个维度从原点偏移的像素数。

本指南介绍了 CSS 对象模型使用的标准坐标系。这些通常仅在原点的位置不同。

尺寸

在 Web 技术使用的坐标系中,约定规定水平偏移称为x 坐标,其中负值表示原点左侧的位置,正值表示原点右侧的位置。y 坐标指定垂直偏移,负值表示原点上方,正值表示原点下方。

在 Web 上,默认原点是给定上下文的左上角(正 y 坐标值位于原点下方)。请注意,这与大多数数学模型不同,在数学模型中,原点位于左下角,正 y 坐标值位于原点上方。

当使用第三个维度从前到后分层对象时,我们使用 z 轴。z 轴从观察者延伸到屏幕表面。CSS z-index 属性影响定位元素在此轴上的位置,从而产生远离或靠近观察者的效果。

注意:实际上,可以使用 CSS 属性(如transform)更改这些坐标系的定义和方向。但是,我们现在只讨论标准坐标系。

标准 CSSOM 坐标系

CSS 对象模型使用四个标准坐标系。为了帮助可视化主要系统,下图显示了一个带有浏览器窗口的显示器,该窗口包含滚动到视区外的内容。滚动到视区外的页面内容以半透明形式显示在浏览器窗口上方,以指示“页面”坐标的原点将位于何处。“客户端”、“页面”和“视区”坐标系的原点突出显示。

Diagram of a computer monitor with a browser window containing content outside of the viewport. Labels show the origin for page, screen, and viewport coordinates.

偏移

使用“偏移”模型指定的坐标使用所检查元素的左上角,或者事件发生的元素。

例如,当发生鼠标事件时,事件的offsetXoffsetY 属性中指定的鼠标位置相对于事件已传递到的节点的左上角。原点由padding-edge内缩,它是填充区域和边框区域之间的边缘。

视区

“视窗”(或“客户端”)坐标系以视窗或事件发生的浏览上下文的左上角为原点。这是呈现文档的整个查看区域。

例如,在台式电脑上,MouseEvent.clientXMouseEvent.clientY 属性指示事件发生时鼠标光标的位置,相对于 window 的左上角。使用触控笔或指针时,Touch.clientXTouch.clientY 坐标在 触摸事件 中相对于相同的原点。

视窗的左上角始终为 (0, 0),无论文档内容或可能已完成的任何滚动。换句话说,滚动文档会改变文档中给定位置的视窗坐标。

页面

“页面”坐标系给出像素相对于整个渲染 Document 的左上角的位置。这意味着文档中元素中的一个点在用户水平或垂直滚动文档后将具有相同的坐标,除非元素通过布局更改移动。

鼠标事件的 pageXpageY 属性提供事件生成时鼠标的位置,相对于文档的左上角。 Touch.pageXTouch.pageY 坐标在 触摸事件 中相对于相同的原点。

屏幕

最后,我们来到“屏幕”模型,其原点是用户屏幕空间的左上角。此坐标系中的每个点都表示一个逻辑像素,因此值沿每个轴以整数增量和减量。如果包含的窗口移动,例如,或者用户屏幕几何形状发生变化(通过更改显示分辨率或向系统添加或删除显示器),文档中给定点的 位置将发生变化。

MouseEvent.screenXMouseEvent.screenY 属性给出鼠标事件位置相对于屏幕原点的坐标。 Touch.screenXTouch.screenY 坐标在 触摸事件 中相对于相同的原点。

示例

让我们看一个在元素中记录鼠标坐标的示例。每当鼠标进入、在内部移动或退出内部框时,事件都会通过在四个可用系统中记录当前鼠标坐标来处理。

JavaScript

对于 JavaScript,代码通过对内部框调用 addEventListener() 来设置内部框的事件处理程序,分别对应 mouseentermousemovemouseleave 类型。对于每个事件,我们都调用 setCoords() 函数,该函数使用每个系统的坐标设置 <p> 元素的内部文本。

js
const log = document.querySelector(".log");
const inner = document.querySelector(".inner");

function setCoords(e) {
  log.innerText = `
    Offset X/Y: ${e.offsetX}, ${e.offsetY}
    Viewport X/Y: ${e.clientX}, ${e.clientY}
    Page X/Y: ${e.pageX}, ${e.pageY}
    Screen X/Y: ${e.screenX}, ${e.screenY}`;
}

inner.addEventListener("mousemove", setCoords);
inner.addEventListener("mouseenter", setCoords);
inner.addEventListener("mouseleave", setCoords);

HTML

HTML 包含一个带有 "log" 类的 <p>,它显示来自鼠标事件的数据。

html
<div class="outer">
  <div class="inner">
    <p class="log">Mouse over this section to view coordinates</p>
  </div>
</div>

CSS

包含框的 "outer" 类有意地太宽,无法在内容滚动时查看鼠标坐标的效果。"inner" 段落是跟踪和记录鼠标事件的地方。

css
.outer {
  width: 1000px;
}

.inner {
  font-family: monospace;
  position: relative;
  width: 500px;
  height: 150px;
  top: 25px;
  left: 100px;
  background-color: darkblue;
  color: white;
  cursor: crosshair;
  user-select: none;
}

.log {
  position: relative;
  width: 100%;
  text-align: center;
}

结果

在这里您可以看到结果生效。当您将鼠标移入和移出蓝色框时,观察鼠标 X 和 Y 坐标的值在各种坐标系中的变化。

另请参阅