坐标系

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

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

维度

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

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

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

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

标准 CSSOM 坐标系统

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

A large screen with a smaller browser window rendering a web page's bottom half; the top half is shown as scrolled outside the browser viewport. The top-left corners of the screen, page, and viewport are all labeled with coordinates of 0,0.

偏移量

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

例如,当发生鼠标事件时,事件的 offsetXoffsetY 属性指定的鼠标位置是相对于事件已分派到的节点的左上角。原点向内偏移了内边距边缘,即内边距区域和边框区域之间的边缘。

视口

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

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

窗口的左上角始终是 (0, 0),无论文档内容如何或是否进行了任何滚动。换句话说,滚动文档将改变文档中给定位置的视口坐标。

页面

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

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

Screen

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

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 坐标值在各种坐标系统中如何变化。

另见