CSSOM view/Coordinate systems

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
74/190

안녕하세요! 오늘 번역해 볼 MDN 문서는 웹 개발에서 마우스 이벤트나 요소의 위치를 다룰 때 필수적으로 알아야 하는 좌표계(Coordinate systems)에 대한 내용입니다.

프론트엔드 개발자로 취업을 준비하시면서 인터랙티브한 UI를 만들거나 캔버스(Canvas) 작업을 할 일이 생기실 텐데요, 이때 clientX, offsetX, pageX 등의 차이를 명확히 구분하지 못하면 요소가 엉뚱한 곳에 렌더링되거나 클릭 이벤트가 빗나가는 당황스러운 상황을 겪게 됩니다. 이 문서를 통해 웹에서 위치를 계산하는 기준점들이 어떻게 다른지 확실하게 정리해 두시면 실무에서 큰 도움이 될 거예요!


좌표계 (Coordinate systems)

그래픽 컨텍스트(graphics context)에서 특정 픽셀의 위치를 지정할 때는 (대수학(algebra)에서 좌표계를 지정할 때와 마찬가지로) 컨텍스트 내의 고정된 점을 기준으로 위치가 정의됩니다. 이 고정된 점을 원점(origin)이라고 부릅니다. 위치는 원점으로부터 컨텍스트의 각 차원(가로, 세로)을 따라 몇 픽셀만큼 떨어져 있는지(offset)로 지정됩니다.

이 가이드에서는 CSS 객체 모델(CSS Object Model, CSSOM)에서 사용하는 표준 좌표계들에 대해 설명합니다. 이 좌표계들은 일반적으로 원점이 어디에 위치하는가에 따라서만 차이가 납니다.

이 문서에서 다룰 내용 (In this article)


차원 (Dimensions)

웹 기술에서 사용되는 좌표계에서 가로축(수평)의 이동 거리는 x-좌표(x-coordinate)라고 부릅니다. 여기서 음수 값은 원점의 왼쪽을, 양수 값은 원점의 오른쪽을 나타냅니다. y-좌표(y-coordinate)는 세로축(수직)의 이동 거리를 지정하며, 음수 값은 원점의 위쪽을, 양수 값은 원점의 아래쪽을 나타냅니다.

웹에서 기본 원점(0, 0)은 주어진 컨텍스트의 왼쪽 상단(top-left) 모서리입니다 (양수의 y-좌표 값이 원점 아래쪽으로 내려갑니다). 이는 원점이 왼쪽 하단(bottom-left) 모서리에 있고 양수의 y-좌표 값이 원점 위쪽으로 올라가는 일반적인 수학적 모델과는 다르다는 점을 꼭 기억하세요.

객체들을 앞뒤로 쌓기 위해 3차원(third dimension)을 사용할 때, 우리는 z-축(z-axis)을 사용합니다. z-축은 관찰자(viewer)로부터 화면의 표면을 향해 뻗어 나갑니다. CSS z-index 속성값은 위치가 지정된 요소들이 이 축 위에서 어디에 놓일지를 결정하며, 이를 통해 요소가 관찰자로부터 멀어지거나 가까워지는 효과를 줍니다.

💡 노트 (Note):
CSS transform 속성 등을 사용하면 이러한 좌표계의 정의와 방향을 바꿀 수 있습니다. 하지만 여기서는 일단 표준 좌표계에 대해서만 이야기하도록 하겠습니다.


표준 CSSOM 좌표계 (Standard CSSOM coordinate systems)

CSS 객체 모델에서 사용하는 표준 좌표계에는 네 가지가 있습니다.
주요 좌표계들을 시각적으로 이해하는 데 도움을 주기 위해, 아래 다이어그램은 뷰포트(viewport) 밖으로 스크롤된 콘텐츠를 포함하고 있는 브라우저 창이 띄워진 모니터를 보여줍니다.
뷰포트 밖으로 스크롤되어 올라간 페이지 콘텐츠는 "page" 좌표계의 원점이 어디인지를 나타내기 위해 브라우저 창 위쪽에 반투명하게 표시되어 있습니다.
"client", "page", 그리고 "viewport" 좌표계의 원점들이 강조 표시되어 있습니다.

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.

오프셋 (Offset)

"offset(오프셋)" 모델을 사용하여 지정된 좌표는 검사 중이거나 이벤트가 발생한 대상 요소의 왼쪽 상단 모서리를 원점으로 사용합니다.

예를 들어, 마우스 이벤트(mouse event)가 발생할 때, 이벤트 객체의 offsetXoffsetY 속성에 명시된 마우스의 위치는 이벤트가 전달된(클릭된) 노드의 왼쪽 상단 모서리를 기준으로 제공됩니다. 이 원점은 패딩 경계(padding edge), 즉 패딩 영역과 테두리(border) 영역 사이의 경계선 안쪽을 기준으로 합니다.

💡 강사의 실무 팁!
캔버스(Canvas)에 그림을 그리는 앱이나, 특정 div 박스 안에서만 마우스를 따라다니는 커스텀 커서를 만들 때 이 offsetX, offsetY가 필수적으로 사용됩니다. 요소 내부에서의 상대적인 위치를 잡을 때 가장 유용합니다!

뷰포트 (Viewport)

"viewport(뷰포트)" (또는 "client(클라이언트)") 좌표계는 이벤트가 발생한 뷰포트나 브라우징 컨텍스트(browsing context)의 왼쪽 상단 모서리를 원점으로 사용합니다. 이것은 문서가 표시되는 '전체 시각적 영역'을 의미합니다.

예를 들어, 데스크톱 컴퓨터에서 MouseEvent.clientXMouseEvent.clientY 속성은 이벤트가 발생한 순간에 window(현재 화면에 보이는 브라우저 창 내부)의 왼쪽 상단 모서리를 기준으로 한 마우스 커서의 위치를 나타냅니다.
스타일러스 펜이나 포인터를 사용할 때, 터치 이벤트(touch event)Touch.clientXTouch.clientY 좌표도 이와 동일한 원점을 기준으로 합니다.

브라우저 창(window)의 왼쪽 상단 모서리는 문서의 전체 내용이 얼마나 길든, 스크롤을 얼마나 내렸든 관계없이 항상 (0, 0)입니다. 다른 말로 하면, 문서를 스크롤하면 문서 내의 특정 지점에 대한 뷰포트 좌표(clientX, clientY) 값은 화면에서 보이는 위치가 달라지므로 계속 변하게 됩니다.

페이지 (Page)

"page(페이지)" 좌표계는 렌더링된 전체 Document의 왼쪽 상단 모서리를 기준으로 한 픽셀의 위치를 제공합니다.
이는 사용자가 문서에서 가로 또는 세로로 스크롤을 하더라도 (레이아웃 변경으로 인해 요소 자체가 움직이지 않는 한) 문서 내의 특정 지점은 항상 동일한 좌표를 갖는다는 것을 의미합니다.

마우스 이벤트의 pageXpageY 속성은 이벤트가 생성된 시점의 마우스 위치를 전체 문서의 왼쪽 상단 모서리를 기준으로 제공합니다.
터치 이벤트(touch event)Touch.pageXTouch.pageY 좌표도 이와 동일한 원점을 기준으로 합니다.

💡 강사의 실무 팁!
clientX/YpageX/Y의 차이는 스크롤된 상태에서 명확히 드러납니다. 스크롤을 많이 내린 상태에서 화면 맨 위를 클릭하면 clientY는 0에 가깝지만, pageY는 스크롤한 만큼 더해진 아주 큰 값이 나옵니다. 드래그 앤 드롭 기능을 구현할 때 이 둘을 헷갈리면 요소가 엉뚱한 곳으로 날아갈 수 있으니 주의하세요!

화면 (Screen)

마지막으로 살펴볼 것은 원점이 사용자 모니터 스크린 전체의 왼쪽 상단 모서리인 "screen(화면)" 모델입니다.
이 좌표계의 각 점은 단일 논리 픽셀을 나타내며, 값들은 각 축을 따라 정수 값으로 증가하거나 감소합니다.
만약 브라우저 창을 모니터 화면상에서 다른 곳으로 이동시키거나, 사용자의 모니터 환경이 변경되면(디스플레이 해상도를 변경하거나 시스템에 모니터를 추가/제거하는 등) 문서 내 특정 지점의 스크린 좌표 위치는 변하게 됩니다.

MouseEvent.screenXMouseEvent.screenY 속성은 스크린의 원점을 기준으로 마우스 이벤트 위치의 좌표를 제공합니다.
터치 이벤트(touch event)Touch.screenXTouch.screenY 좌표도 이와 동일한 원점을 기준으로 합니다.


예제 (Example)

특정 요소 안에서 마우스 좌표를 기록하는 예제를 살펴봅시다.
마우스가 안쪽 상자(inner box)로 들어가거나(enter), 안에서 이리저리 움직이거나(move), 밖으로 나갈(exit) 때마다 이벤트가 발생하며, 현재 마우스의 좌표를 앞서 설명한 네 가지 시스템(offset, client, page, screen) 각각으로 기록하여 보여줍니다.

JavaScript

자바스크립트 코드에서는 안쪽 상자(inner box)에 mouseenter, mousemove, mouseleave 각각의 이벤트 타입에 대해 addEventListener()를 호출하여 이벤트 핸들러를 설정합니다.
각각의 이벤트가 발생할 때마다 우리는 setCoords() 함수를 호출하는데, 이 함수는 <p> 요소의 내부 텍스트(inner text)를 각 좌표계 시스템에 해당하는 좌표값으로 업데이트합니다.

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> 요소가 포함되어 있습니다.

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

CSS

외부 상자(containing box) 역할을 하는 "outer" 클래스는 스크롤 시 마우스 좌표의 변화(특히 page와 client의 차이)를 잘 볼 수 있도록 의도적으로 넓이를 아주 크게(1000px) 설정했습니다.
"inner" 단락은 실제로 마우스 이벤트가 추적되고 좌표가 기록되는 영역입니다.

.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;
}

결과 (Result)

아래에서 실제 작동하는 결과를 확인할 수 있습니다. 파란색 상자 안팎으로 마우스를 이리저리 움직여 보면서, 네 가지 좌표계에서 마우스의 X, Y 좌표값이 어떻게 달라지는지 관찰해 보세요. (특히 화면을 가로로 스크롤한 뒤에 박스 안에서 마우스를 움직여보시면 Viewport(client) X와 Page X의 값이 서로 다르게 나타나는 것을 확실히 느끼실 수 있을 겁니다!)


같이 보기 (See also)


MDN 개선에 참여하기 (Help improve MDN)

이 페이지가 도움이 되셨나요?

기여하는 방법 알아보기 (Learn how to contribute)

이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다 (MDN contributors).

profile
프론트에_가까운_풀스택_개발자

0개의 댓글