CSSOM 뷰 모듈

W3C 워킹 드래프트,

이 문서에 대한 추가 세부정보
이 버전:
https://www.w3.org/TR/2025/WD-cssom-view-1-20250916/
최신 공개 버전:
https://www.w3.org/TR/cssom-view-1/
편집자 초안:
https://drafts.csswg.org/cssom-view/
이전 버전:
이력:
https://www.w3.org/standards/history/cssom-view-1/
피드백:
CSSWG 이슈 저장소
명세 내 인라인
편집자:
(Apple Inc)
(Mozilla)
이전 편집자:
(Opera Software AS)
Glenn Adams (Cox Communications, Inc.)
Anne van Kesteren (Opera Software ASA)
이 명세에 대한 수정 제안:
GitHub 편집기
레거시 이슈 목록:
Bugzilla
테스트 스위트:
https://wpt.fyi/results/css/cssom-view/

요약

이 명세에서 도입된 API는 문서의 시각적 뷰를 조사하고 조작하는 방법을 저자에게 제공합니다. 여기에는 요소 레이아웃 박스의 위치를 얻는 것, 스크립트를 통해 뷰포트의 너비를 얻는 것, 그리고 요소를 스크롤하는 것이 포함됩니다.

CSS 는 구조화된 문서(예: HTML 및 XML)의 렌더링을 화면, 인쇄물 등에서 기술하기 위한 언어입니다.

이 문서의 상태

이 절은 출판 시점에서 문서의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정판은 W3C 표준 및 초안 색인에서 찾을 수 있습니다.

이 문서는 CSS 워킹 그룹워킹 드래프트권고 경로를 사용하여 출판한 것입니다. 워킹 드래프트로의 출판은 W3C 및 회원의 승인을 의미하지 않습니다.

이것은 초안 문서이며 언제든지 다른 문서에 의해 업데이트, 대체 또는 폐기될 수 있습니다. 진행 중인 작업이 아닌 것처럼 인용하는 것은 부적절합니다.

피드백은 GitHub 이슈 제출(선호됨)로 보내 주시고, 제목에 명세 코드 “cssom-view”를 포함해 주세요. 예: “[cssom-view] …코멘트 요약…”. 모든 이슈와 코멘트는 보관됩니다. 또는 (보관) 공개 메일링 리스트 www-style@w3.org로 보낼 수도 있습니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받습니다.

이 문서는 W3C 특허 정책 하에 운영되는 그룹에 의해 작성되었습니다. W3C는 그룹 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지합니다; 해당 페이지에는 특허 공개 방법에 대한 지침도 포함되어 있습니다. 개인이 Essential Claim(s)을 포함한다고 판단하는 특허에 대해 실제 지식을 가지고 있는 경우 W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

1. 배경

이 명세에서 정의된 많은 기능들은 오랜 기간 동안 브라우저에서 지원되어 왔습니다. 이 명세의 목표는 이러한 기능들을 모든 브라우저가 상호 운용 가능하게 구현할 수 있도록 정의하는 것입니다. 또한 이 명세는 스크롤 커스터마이징을 가능하게 하는 몇 가지 새로운 기능도 정의합니다.

테스트

기본 IDL 테스트


2. 용어

이 명세에서 사용되는 용어는 DOM, CSSOM, HTML에서 가져온 것입니다. [DOM] [CSSOM] [HTML]

요소 body(이는 body 요소가 됨)은 다음 모든 조건을 만족하면 스크롤 가능성 있음으로 간주합니다:

참고: body 요소가 스크롤 가능성 있음이어도 스크롤 박스가 없을 수도 있습니다. 예를 들어, overflow 속성의 사용 값이 auto지만, 콘텐츠가 콘텐츠 영역을 넘치지 않을 수 있습니다.

뷰포트 또는 요소의 스크롤 박스는 두 개의 오버플로우 방향을 가지며, 이는 그 뷰포트 또는 요소에 대한 block-endinline-end 방향입니다. 초기 스크롤 위치는 스크롤 영역 원점에 정렬되지 않을 수 있습니다. 이는 콘텐츠 분배 속성에 따라 달라지며, CSS Box Alignment 3 § 5.3 Overflow 및 스크롤 컨테이너를 참고하세요.

스크롤 영역이라는 용어는 뷰포트나 요소의 박스를 가리키며, 뷰포트 또는 요소의 스크롤 박스오버플로우 방향에 따라 아래의 엣지를 가집니다.

오버플로우 방향이 …인 경우 뷰포트의 경우 요소의 경우
오른쪽 및 아래쪽
상단 엣지
초기 포함 블록의 상단 엣지.
오른쪽 엣지
초기 포함 블록의 가장 오른쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 오른쪽 엣지.
하단 엣지
초기 포함 블록의 가장 아래쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 하단 엣지.
왼쪽 엣지
초기 포함 블록의 왼쪽 엣지.
상단 엣지
요소의 상단 padding 엣지.
오른쪽 엣지
요소의 오른쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 오른쪽 margin 엣지.
하단 엣지
요소의 하단 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 하단 margin 엣지.
왼쪽 엣지
요소의 왼쪽 padding 엣지.
왼쪽 및 아래쪽
상단 엣지
초기 포함 블록의 상단 엣지.
오른쪽 엣지
초기 포함 블록의 오른쪽 엣지.
하단 엣지
초기 포함 블록의 가장 아래쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 하단 엣지.
왼쪽 엣지
초기 포함 블록의 가장 왼쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 왼쪽 엣지.
상단 엣지
요소의 상단 padding 엣지.
오른쪽 엣지
요소의 오른쪽 padding 엣지.
하단 엣지
요소의 하단 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 하단 margin 엣지.
왼쪽 엣지
요소의 가장 왼쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 왼쪽 margin 엣지.
왼쪽 및 위쪽
상단 엣지
초기 포함 블록의 가장 위쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 상단 엣지.
오른쪽 엣지
초기 포함 블록의 오른쪽 엣지.
하단 엣지
초기 포함 블록의 하단 엣지.
왼쪽 엣지
초기 포함 블록의 가장 왼쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 왼쪽 엣지.
상단 엣지
요소의 가장 위쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 상단 margin 엣지.
오른쪽 엣지
요소의 오른쪽 padding 엣지.
하단 엣지
요소의 하단 padding 엣지.
왼쪽 엣지
요소의 가장 왼쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 왼쪽 margin 엣지.
오른쪽 및 위쪽
상단 엣지
초기 포함 블록의 가장 위쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 상단 엣지.
오른쪽 엣지
초기 포함 블록의 가장 오른쪽 엣지 및 margin 엣지 중 뷰포트의 모든 하위 박스의 오른쪽 엣지.
하단 엣지
초기 포함 블록의 하단 엣지.
왼쪽 엣지
초기 포함 블록의 왼쪽 엣지.
상단 엣지
요소의 가장 위쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 상단 margin 엣지.
오른쪽 엣지
요소의 가장 오른쪽 padding 엣지 및 요소의 모든 하위 박스 중 (요소를 포함 블록으로 갖는 박스 제외) 오른쪽 margin 엣지.
하단 엣지
요소의 하단 padding 엣지.
왼쪽 엣지
요소의 왼쪽 padding 엣지.

스크롤 영역원점초기 포함 블록의 원점이며, 스크롤 영역뷰포트인 경우입니다. 그 외에는, 요소가 기본 스크롤 위치일 때 요소의 왼쪽 상단 padding 엣지입니다. x 좌표는 오른쪽으로 증가하고, y 좌표는 아래쪽으로 증가합니다.

박스 또는 요소의 특정 엣지 집합에서 시작 엣지는 다음과 같습니다:

오버플로우 방향이 오른쪽 및 아래쪽인 경우
상단 및 왼쪽 엣지
오버플로우 방향이 왼쪽 및 아래쪽인 경우
상단 및 오른쪽 엣지
오버플로우 방향이 왼쪽 및 위쪽인 경우
하단 및 오른쪽 엣지
오버플로우 방향이 오른쪽 및 위쪽인 경우
하단 및 왼쪽 엣지

박스 또는 요소의 특정 엣지 집합에서 끝 엣지는 다음과 같습니다:

오버플로우 방향이 오른쪽 및 아래쪽인 경우
하단 및 오른쪽 엣지
오버플로우 방향이 왼쪽 및 아래쪽인 경우
하단 및 왼쪽 엣지
오버플로우 방향이 왼쪽 및 위쪽인 경우
상단 및 왼쪽 엣지
오버플로우 방향이 오른쪽 및 위쪽인 경우
상단 및 오른쪽 엣지

시각적 뷰포트뷰포트의 한 종류로서, 그 스크롤 영역이 또 다른 뷰포트레이아웃 뷰포트라 불립니다.

스크롤링 외에도 시각적 뷰포트레이아웃 뷰포트에 스케일 변환(확대/축소 변환)을 적용할 수 있습니다. 이 변환은 레이아웃 뷰포트캔버스에 적용되며, 내부 좌표 공간에는 영향을 주지 않습니다.

참고: 시각적 뷰포트의 스케일 변환은 흔히 "핀치 줌"이라고 불립니다. 개념적으로 이 변환은 CSS 기준 픽셀의 크기를 변경하지만, 레이아웃 뷰포트의 크기도 비례적으로 변경하여 페이지의 콘텐츠 재배치(reflow)가 발생하지 않게 합니다.

스케일 변환의 크기는 시각적 뷰포트스케일 팩터라고 합니다.

이 애니메이션은 확대된 시각적 뷰포트가 "팬(pan)"되는 예시를 보여줍니다(예: 사용자가 터치 드래그를 수행할 때). 페이지는 레이아웃 뷰포트가 시각적 뷰포트보다 더 크게 스케일됩니다.

스크롤 델타는 우선 시각적 뷰포트에 적용됩니다. 시각적 뷰포트가 그 한계에 도달하면, 스크롤 델타는 레이아웃 뷰포트에 적용됩니다. 이 동작은 스크롤 수행 단계에 의해 구현됩니다.

Document 레이아웃 뷰포트 시각적 뷰포트

VisualViewport 객체는 연결된 문서를 가지고 있으며, 이는 Document 객체입니다. 이는 소유 Window연결된 문서입니다 VisualViewport의. 레이아웃 뷰포트는 소유 Window뷰포트입니다.

이 명세의 요구사항을 위해, display 속성의 계산된 값이 table-column 또는 table-column-group인 요소는 연관된 박스(box) (각각 컬럼 또는 컬럼 그룹)을 가진 것으로 간주해야 합니다.

SVG 레이아웃 박스라는 용어는 CSS에서 정의된 display 타입에 해당하지 않는 SVG 요소가 생성하는 박스(box)를 의미합니다. (예: rect 요소가 생성하는 박스 등.)

변환(transforms)은 SVG 변환과 CSS 변환을 의미합니다. [SVG11] [CSS-TRANSFORMS-1]

메서드나 속성이 다른 메서드 또는 속성을 호출한다고 명시된 경우, 사용자 에이전트는 해당 속성이나 메서드의 내부 API를 호출해야 하며, 즉 저자가 ECMAScript에서 속성이나 메서드를 커스텀 프로퍼티나 함수로 덮어써도 그 동작을 변경할 수 없습니다.

별도 명시가 없는 한, 모든 문자열 비교는 is를 사용합니다.

2.1. CSS 픽셀

이 명세에서 정의된 API의 모든 좌표와 치수는 별도의 명시가 없는 한 CSS 픽셀 단위입니다. [CSS-VALUES]

참고: 예를 들어 matchMedia()와 같이 단위가 명시적으로 지정된 경우에는 적용되지 않습니다.

2.2. 확대/축소(Zooming)

확대/축소에는 두 가지 종류가 있습니다. 초기 뷰포트의 크기에 영향을 주는 페이지 확대/축소와, 초기 뷰포트 또는 실제 뷰포트에는 영향을 주지 않고 돋보기처럼 동작하는 시각적 뷰포트의 스케일 팩터입니다. [CSS-DEVICE-ADAPT]

참고: "스케일 팩터"는 흔히 "핀치 줌"이라고 불리지만, 핀치 줌 외의 방법으로도 영향을 받을 수 있습니다. 예를 들어 사용자 에이전트가 포커스된 입력 요소를 보기 쉽게 확대할 수도 있습니다.

2.3. 웹에 노출되는 화면 정보

사용자 에이전트는 사용자의 프라이버시 보호를 위해 출력 장치의 화면 정보를 숨길 수 있습니다. API 간 일관된 방식으로 이를 처리하기 위해, 이 명세에서는 각각 너비와 높이를 가지며, 원점은 좌상단이고, x, y 좌표는 각각 오른쪽과 아래로 증가하는 다음 용어를 정의합니다.

웹에 노출되는 화면 영역은 다음 중 하나입니다:

웹에 노출되는 사용 가능한 화면 영역은 다음 중 하나입니다:

3. 공통 인프라

이 명세는 WHATWG Infra 표준에 의존합니다. [INFRA]

3.1. 스크롤

사용자 에이전트가 스크롤 수행스크롤 박스 box에 대해, 특정 위치 position으로, 연관된 요소 또는 의사 요소 element와 선택적으로 스크롤 동작 behavior("auto"가 생략된 경우), 다음 단계를 실행해야 합니다:

  1. 진행 중인 부드러운 스크롤box에 대해 모두 중단합니다.
  2. 사용자 에이전트가 scroll-behavior 속성을 적용하며 다음 조건 중 하나를 만족하는 경우:
    • behavior가 "auto"이고 element가 null이 아니며 해당 scroll-behavior 속성의 계산 값이 smooth인 경우
    • behaviorsmooth인 경우
    ...이면 부드러운 스크롤box에 대해 position으로 수행합니다. 위치 업데이트가 완료되면 scrollend 이벤트를 발생시킵니다. 그렇지 않으면 즉시 스크롤box에 대해 position으로 수행합니다. 즉시 스크롤 이후 scrollend 이벤트를 발생시킵니다.

    참고: behavior: "instant"는 이 알고리즘에서 항상 즉시 스크롤을 수행합니다.

    참고: 사용자 상호작용이나 프로그래밍 호출 결과로 스크롤 위치가 변경되지 않아 변환이 적용되지 않은 경우에는 스크롤이 발생하지 않았으므로 scrollend 이벤트가 발생하지 않습니다.

사용자 에이전트가 뷰포트 스크롤 수행뷰포트에 대해 특정 위치 position으로, 선택적으로 스크롤 동작 behavior("auto"가 생략된 경우)로 수행할 때, 다음 단계에 따라 조정된 뷰포트 스크롤을 해야 합니다:

  1. doc뷰포트의 연관된 Document로 합니다.

  2. vvVisualViewport연관된 문서doc인 것으로 합니다.

  3. maxX뷰포트의 스크롤 박스의 너비에서 vvwidth 속성 값을 뺀 값으로 합니다.

  4. maxY뷰포트의 스크롤 박스의 높이에서 vvheight 속성 값을 뺀 값으로 합니다.

  5. dxposition의 수평 성분에서 vvpageLeft 값을 뺀 값으로 합니다.

  6. dyposition의 수직 성분에서 vvpageTop 값을 뺀 값으로 합니다.

  7. visual xvvoffsetLeft 속성 값으로 합니다.

  8. visual yvvoffsetTop 속성 값으로 합니다.

  9. visual dx를 min(maxX, max(0, visual x + dx)) - visual x로 합니다.

  10. visual dy를 min(maxY, max(0, visual y + dy)) - visual y로 합니다.

  11. layout dxdx - visual dx로 합니다.

  12. layout dydy - visual dy로 합니다.

  13. elementdoc의 루트 요소가 있으면 그 요소, 없으면 null로 합니다.

  14. 스크롤 수행뷰포트의 스크롤 박스에 대해 현재 스크롤 위치 + (layout dx, layout dy)로, element를 연관 요소로, behavior를 스크롤 동작으로 지정하여 수행합니다.

  15. 스크롤 수행vv스크롤 박스에 대해 현재 스크롤 위치 + (visual dx, visual dy)로, element를 연관 요소로, behavior를 스크롤 동작으로 지정하여 수행합니다.

참고: 개념적으로, 시각적 뷰포트가 "레이아웃 뷰포트"의 가장자리에 닿을 때까지 먼저 스크롤되고, 그 이후에는 스크롤 델타가 레이아웃 뷰포트에 적용되어 레이아웃 뷰포트를 "밀어냅니다". 그러나 위 단계의 스크롤은 사전에 계산되어 반대 순서로 적용되어, 레이아웃 뷰포트를 먼저 스크롤한 다음 시각적 뷰포트를 스크롤합니다. 이는 스크롤 이벤트 순서의 일관성을 위한 역사적 이유 때문입니다. 시각적 예시는 위의 예시를 참고하세요.

사용자가 문서를 핀치 줌한 상태에서 마우스 휠을 돌려 문서를 50px 아래로 스크롤하도록 요청합니다. 문서가 핀치 줌 되어 있으므로 시각적 뷰포트는 20px만큼 스크롤할 수 있습니다. 사용자 에이전트는 시각적 뷰포트를 20px, 레이아웃 뷰포트를 30px 아래로 각각 스크롤하여 분배합니다.
사용자는 모바일 사용자 에이전트에서 문서를 보고 있습니다. 문서에서 오프스크린 텍스트 입력 요소에 포커스를 맞추면 가상 키보드가 표시되어 시각적 뷰포트가 줄어듭니다. 사용자 에이전트는 이제 해당 요소가 시각적 뷰포트 내에 보이도록 해야 합니다. 사용자 에이전트는 요소가 레이아웃 뷰포트 내에 보이도록 레이아웃 뷰포트를 스크롤한 후, 요소가 사용자가 볼 수 있도록 시각적 뷰포트를 스크롤합니다.

스크롤은 완료됨(completed) 상태는 스크롤 위치에 더 이상 대기 중인 업데이트나 변환이 없고 사용자가 제스처를 완료한 경우입니다. 스크롤 위치 업데이트에는 부드러운 또는 즉시 마우스 휠 스크롤, 키보드 스크롤, 스크롤 스냅 이벤트, 기타 API 및 제스처로 인해 스크롤 위치가 변경되고 보간될 수 있습니다. 터치 팬이나 트랙패드 스크롤과 같은 사용자 제스처는 포인터 또는 키가 해제되기 전까지 완료되지 않습니다.

사용자 에이전트가 부드러운 스크롤스크롤 박스 box에 대해 position으로 수행할 때, box의 스크롤 위치를 사용자 에이전트가 정의한 방식으로 사용자 에이전트가 정의한 시간 동안 업데이트해야 합니다. 스크롤이 완료(completed)되면 box의 스크롤 위치는 position이어야 합니다. 스크롤은 알고리즘 또는 사용자에 의해 중단(aborted)될 수도 있습니다.

사용자 에이전트가 즉시 스크롤스크롤 박스 box에 대해 position으로 수행할 때, box의 스크롤 위치를 position으로 즉시 업데이트해야 합니다.

문서의 처음으로 스크롤을 document document에 대해 수행하려면 다음 단계를 따릅니다:

  1. viewportdocument와 연관된 뷰포트로 합니다.
  2. positionviewport시작 가장자리(beginning edges)스크롤 영역시작 가장자리를 맞춘 스크롤 위치로 합니다.
  3. positionviewport의 현재 스크롤 위치와 같고, viewport에 진행 중인 부드러운 스크롤이 없다면, 이 단계를 종료합니다.
  4. 뷰포트 스크롤 수행viewport에 대해 position으로, document루트 요소가 있으면 그 요소를, 없으면 null을 연관 요소로 지정하여 수행합니다.

참고: 이 알고리즘은 HTML에서 정의된 #top 프래그먼트 식별자로 이동할 때 사용됩니다. [HTML]

Tests

3.2. WebIDL 값

x에 대해 비유한수(non-finite) 값을 정규화(normalize non-finite values)하라는 요청을 받을 때, 만약 x가 세 가지 특수 부동 소수점 리터럴 값(Infinity, -Infinity 또는 NaN) 중 하나라면, x는 값 0으로 변경되어야 합니다. [WEBIDL]

4. Window 인터페이스에 대한 확장

enum ScrollBehavior { "auto", "instant", "smooth" };

dictionary ScrollOptions {
    ScrollBehavior behavior = "auto";
};
dictionary ScrollToOptions : ScrollOptions {
    unrestricted double left;
    unrestricted double top;
};

partial interface Window {
    [NewObject] MediaQueryList matchMedia(CSSOMString query);
    [SameObject, Replaceable] readonly attribute Screen screen;
    [SameObject, Replaceable] readonly attribute VisualViewport? visualViewport;

    // browsing context
    undefined moveTo(long x, long y);
    undefined moveBy(long x, long y);
    undefined resizeTo(long width, long height);
    undefined resizeBy(long x, long y);

    // viewport
    [Replaceable] readonly attribute long innerWidth;
    [Replaceable] readonly attribute long innerHeight;

    // viewport scrolling
    [Replaceable] readonly attribute double scrollX;
    [Replaceable] readonly attribute double pageXOffset;
    [Replaceable] readonly attribute double scrollY;
    [Replaceable] readonly attribute double pageYOffset;
    undefined scroll(optional ScrollToOptions options = {});
    undefined scroll(unrestricted double x, unrestricted double y);
    undefined scrollTo(optional ScrollToOptions options = {});
    undefined scrollTo(unrestricted double x, unrestricted double y);
    undefined scrollBy(optional ScrollToOptions options = {});
    undefined scrollBy(unrestricted double x, unrestricted double y);

    // client
    [Replaceable] readonly attribute long screenX;
    [Replaceable] readonly attribute long screenLeft;
    [Replaceable] readonly attribute long screenY;
    [Replaceable] readonly attribute long screenTop;
    [Replaceable] readonly attribute long outerWidth;
    [Replaceable] readonly attribute long outerHeight;
    [Replaceable] readonly attribute double devicePixelRatio;
};

메서드 matchMedia(query)가 호출되면, 다음 단계들이 실행되어야 합니다:

  1. 파싱의 결과로 parsed media query list를 얻습니다(parsing query).
  2. 새로운 MediaQueryList 객체를 반환합니다. 이 객체는 this연관된 Documentdocument로 가지며, parsed media query list를 그 연관된 media query list로 가집니다.
테스트

screen 속성은 Screen 객체를 반환해야 하며, 이는 Window 객체와 연관된 것입니다.

참고: screenWindowProxy 객체를 통해 접근하면, Document 가 네비게이션될 때 다른 결과가 반환될 수 있습니다.

만약 연관된 문서완전히 활성화(fully active)되어 있다면, visualViewport 속성은 VisualViewport 객체를 반환해야 하며, 이는 Window 객체의 연관된 문서와 연관된 객체여야 합니다. 그렇지 않으면 null을 반환해야 합니다.

참고: VisualViewport 객체는 현재 표시되고 있는 문서의 Window에 대해서만 반환되고 유용합니다. 만약 연관된 Document가 현재 표시되고 있지 않은 VisualViewport에 대한 참조가 유지된다면, 그 VisualViewport의 값들은 브라우징 컨텍스트에 대한 정보를 노출해서는 안 됩니다.

테스트

moveTo(x, y) 메서드는 다음 단계를 따라야 합니다:

  1. 선택적으로 반환합니다.

  2. targetthis관련 전역 객체(relevant global object)browsing context로 합니다.

  3. 만약 target이 스크립트에 의해 생성된 보조 브라우징 컨텍스트(auxiliary browsing context)가 아니라면(사용자 동작으로 생성된 것이 아니라면), 반환합니다.

  4. 선택적으로, 창이 사용 가능한 공간 밖으로 이동하지 않도록 사용자 에이전트가 정의한 방식으로 xy를 제한(clamp)합니다.

  5. target의 창을 이동시켜 그 창의 좌상단 모서리가 출력 장치의 좌상단 모서리에 상대적인 좌표 (x, y)에 위치하도록 합니다. 이 좌표들은 target의 CSS 픽셀(CSS pixels)로 측정됩니다. 양의 축은 오른쪽 및 아래 방향입니다.

moveBy(x, y) 메서드는 다음 단계를 따라야 합니다:

  1. 선택적으로 반환합니다.

  2. targetthis관련 전역 객체browsing context로 합니다.

  3. 만약 target이 스크립트에 의해 생성된 보조 브라우징 컨텍스트가 아니라면, 반환합니다.

  4. 선택적으로, 창이 사용 가능한 공간 밖으로 이동하지 않도록 xy를 사용자 에이전트가 정의한 방식으로 제한합니다.

  5. target의 창을 x만큼 오른쪽으로, y만큼 아래로 이동시킵니다. (측정 단위는 target의 CSS 픽셀입니다, CSS pixels).

resizeTo(width, height) 메서드는 다음 단계를 따라야 합니다:

  1. 선택적으로 반환합니다.

  2. targetthis관련 전역 객체browsing context로 합니다.

  3. 만약 target이 스크립트에 의해 생성된 보조 브라우징 컨텍스트가 아니라면, 반환합니다.

  4. 선택적으로, 창이 너무 작아지거나 사용 가능한 공간보다 커지지 않도록 widthheight를 사용자 에이전트 정의 방식으로 제한합니다.

  5. 뷰포트의 왼쪽과 오른쪽 가장자리 사이 거리가 width CSS 픽셀, 상단과 하단 가장자리 사이 거리가 height CSS 픽이 되도록 창의 오른쪽 및 하단 가장자리를 이동시켜 target의 창을 리사이즈합니다.

  6. 선택적으로, 창이 사용 가능한 공간 밖으로 커지지 않도록 사용자 에이전트 정의 방식으로 창을 이동시킵니다.

테스트

resizeBy(x, y) 메서드는 다음 단계를 따라야 합니다:

  1. 선택적으로 반환합니다.

  2. targetthis관련 전역 객체browsing context로 합니다.

  3. 만약 target이 스크립트에 의해 생성된 보조 브라우징 컨텍스트가 아니라면, 반환합니다.

  4. 선택적으로, 창이 너무 작아지거나 사용 가능한 공간보다 커지지 않도록 xy를 제한합니다.

  5. 창의 오른쪽 가장자리를 x CSS 픽셀, 하단 가장자리를 y CSS 픽만큼 이동시켜 target의 창을 리사이즈합니다.

  6. 선택적으로, 창이 사용 가능한 공간 밖으로 커지지 않도록 사용자 에이전트가 정의한 방식으로 창을 이동시킵니다.

innerWidth 속성은 렌더된 스크롤바(있는 경우)의 크기를 포함한 뷰포트 너비를 반환해야 하며, 만약 뷰포트가 없으면 0을 반환해야 합니다.

뷰포트의 너비를 얻는 방법 예시는 다음과 같습니다:
var viewportWidth = innerWidth

innerHeight 속성은 렌더된 스크롤바(있는 경우)의 크기를 포함한 뷰포트 높이를 반환해야 하며, 만약 뷰포트가 없으면 0을 반환해야 합니다.

scrollX 속성은 initial containing block 원점에 대한 상대 좌표로서, 뷰포트의 왼쪽의 x-좌표를 반환해야 하며, 뷰포트가 없으면 0을 반환해야 합니다.

pageXOffset 속성은 scrollX 속성이 반환하는 값을 반환해야 합니다.

scrollY 속성은 initial containing block 원점에 대한 상대 좌표로서, 뷰포트의 상단의 y-좌표를 반환해야 하며, 뷰포트가 없으면 0을 반환해야 합니다.

pageYOffset 속성은 scrollY 속성이 반환하는 값을 반환해야 합니다.

메서드 scroll() 가 호출될 때, 다음 단계들이 실행되어야 합니다:

  1. 만약 하나의 인수로 호출되었다면, 다음 하위 단계들을 따릅니다:

    1. options를 인수로 합니다.

    2. optionsleft 딕셔너리 멤버가 있으면 그 값을 x로 하고, 그렇지 않으면 뷰포트의 현재 x축 스크롤 위치를 사용합니다.

    3. optionstop 딕셔너리 멤버가 있으면 그 값을 y로 하고, 그렇지 않으면 뷰포트의 현재 y축 스크롤 위치를 사용합니다.

  2. 만약 두 개의 인수로 호출되었다면, 다음 하위 단계들을 따릅니다:

    1. options를 null로 두고 이것을 변환하여 ScrollToOptions 딕셔너리로 만듭니다. [WEBIDL]

    2. xy를 각각 인수로 합니다.

  3. 비유한수 정규화xy에 대해 수행합니다.

  4. 만약 뷰포트가 없다면, 이 단계를 중단합니다.

  5. viewport width를 스크롤바 너비를 제외한 뷰포트의 너비로 합니다.

  6. viewport height를 스크롤바 높이를 제외한 뷰포트의 높이로 합니다.

  7. 만약 뷰포트의 오버플로우 방향이 오른쪽 방향이라면(overflow direction)
    x를 max(0, min(x, 뷰포트 스크롤 영역 너비 - viewport width))로 합니다.
    만약 뷰포트의 오버플로우 방향이 왼쪽 방향이라면(overflow direction)
    x를 min(0, max(x, viewport width - 뷰포트 스크롤 영역 너비))로 합니다.
  8. 만약 뷰포트의 오버플로우 방향이 아래 방향이라면(overflow direction)
    y를 max(0, min(y, 뷰포트 스크롤 영역 높이 - viewport height))로 합니다.
    만약 뷰포트의 오버플로우 방향이 위 방향이라면(overflow direction)
    y를 min(0, max(y, viewport height - 뷰포트 스크롤 영역 높이))로 합니다.
  9. position을 뷰포트가 x-좌표 x의 스크롤 영역을 뷰포트의 왼쪽과 정렬하고, y-좌표 y의 스크롤 영역을 뷰포트의 상단과 정렬함으로써 뷰포트가 가지게 될 스크롤 위치로 합니다.

  10. 만약 position이 뷰포트의 현재 스크롤 위치와 같고, 뷰포트에 진행 중인 부드러운 스크롤이 없다면, 이 단계를 중단합니다.

  11. document를 뷰포트의 연관된 Document로 합니다.

  12. 뷰포트 스크롤 수행을 뷰포트에 대해 position으로 실행합니다. 연관된 요소는 document루트 요소가 있으면 그 요소, 없으면 null로 하고, 스크롤 동작은 behavior 딕셔너리 멤버의 값으로 합니다.

    사용자 에이전트들은 이것이 (조정된) 뷰포트perform a scroll를 사용하는지, 아니면 레이아웃 뷰포트의 스크롤 박스에 대한 perform a scroll를 사용하는지에 대해 의견이 일치하지 않습니다.

테스트

메서드 scrollTo()가 호출될 때, 사용자 에이전트는 동일한 인수로 scroll() 메서드가 호출된 것처럼 동작해야 합니다.

테스트

메서드 scrollBy()가 호출될 때, 사용자 에이전트는 다음 단계를 실행해야 합니다:

  1. 만약 두 개의 인수로 호출되었다면, 다음 하위 단계를 따릅니다:

    1. options를 null로 두고 이것을 변환하여 ScrollToOptions 딕셔너리로 만듭니다. [WEBIDL]

    2. xy를 각각 인수로 합니다.

    3. optionsleft 딕셔너리 멤버에 값 x를 넣습니다.

    4. optionstop 딕셔너리 멤버에 값 y를 넣습니다.

  2. 비유한수 정규화lefttop 딕셔너리 멤버들에 대해 수행합니다.

  3. scrollX 값을 left 딕셔너리 멤버에 더합니다.

  4. scrollY 값을 top 딕셔너리 멤버에 더합니다.

  5. options를 단일 인수로 하여 scroll() 메서드가 호출된 것처럼 동작합니다.

screenXscreenLeft 속성들은 웹에 노출되는 화면 영역(Web-exposed screen area)의 원점에 대한 상대 좌표로서, 클라이언트 창의 왼쪽의 x-좌표를 CSS 픽셀(CSS pixels) 단위의 숫자로 반환해야 하며, 해당 값이 없으면 0을 반환해야 합니다.

테스트

screenYscreenTop 속성들은 웹에 노출되는 화면 영역의 원점에 대한 상대 좌표로서, 클라이언트 창의 상단의 y-좌표를 CSS 픽셀(CSS pixels) 단위의 숫자로 반환해야 하며, 해당 값이 없으면 0을 반환해야 합니다.

outerWidth 속성은 클라이언트 창의 너비를 반환해야 합니다. 클라이언트 창이 없다면 이 속성은 0을 반환해야 합니다.

outerHeight 속성은 클라이언트 창의 높이를 반환해야 합니다. 클라이언트 창이 없다면 이 속성은 0을 반환해야 합니다.

devicePixelRatio 속성은 다음의 장치 픽셀 비율 결정(determine the device pixel ratio) 알고리즘의 결과를 반환해야 합니다:

  1. 출력 장치가 없으면 1을 반환하고 이 단계를 중단합니다.

  2. CSS pixel size를 현재 페이지 줌에서의 CSS 픽셀의 크기(스케일 팩터 1.0 사용)로 합니다.

  3. device pixel size를 출력 장치의 장치 픽셀의 수직 크기로 합니다.

  4. CSS pixel sizedevice pixel size로 나눈 결과를 반환합니다.

4.1. features 인수와 open() 메서드

HTML은 open() 메서드를 정의합니다. 이 절에서는 features 인수에 주어진 위치와 크기에 대한 동작을 정의합니다. [HTML]

브라우징 컨텍스트 기능 설정을 브라우징 컨텍스트 target에 대해 map tokenizedFeatures로 수행하려면:

  1. x를 null로 합니다.

  2. y를 null로 합니다.

  3. width를 null로 합니다.

  4. height를 null로 합니다.

  5. 만약 tokenizedFeatures["left"]가 존재하면:

    1. xtokenizedFeatures["left"]에 대해 정수 파싱 규칙을 적용한 결과를 설정합니다.

    2. 만약 x가 오류이면, x를 0으로 설정합니다.

    3. 선택적으로, 창이 웹에 노출되는 사용 가능한 화면 영역(Web-exposed available screen area)을 벗어나지 않도록 사용자 에이전트가 정의한 방식으로 x를 제한(clamp)할 수 있습니다.

    4. 선택적으로, target의 창을 이동시켜 창의 왼쪽 가장자리가 targetWeb-exposed screen area의 왼쪽 가장자리로부터 수평 좌표 x에 위치하도록 할 수 있습니다. 측정 단위는 CSS 픽셀이며, 양의 축은 오른쪽입니다.

  6. 만약 tokenizedFeatures["top"]가 존재하면:

    1. ytokenizedFeatures["top"]에 대해 정수 파싱 규칙을 적용한 결과를 설정합니다.

    2. 만약 y가 오류이면, y를 0으로 설정합니다.

    3. 선택적으로, 창이 웹에 노출되는 사용 가능한 화면 영역을 벗어나지 않도록 사용자 에이전트가 정의한 방식으로 y를 제한(clamp)할 수 있습니다.

    4. 선택적으로, target의 창을 이동시켜 창의 위쪽 가장자리가 targetWeb-exposed screen area의 위쪽 가장자리로부터 수직 좌표 y에 위치하도록 할 수 있습니다. 측정 단위는 CSS 픽셀이며, 양의 축은 아래쪽입니다.

  7. 만약 tokenizedFeatures["width"]가 존재하면:

    1. widthtokenizedFeatures["width"]에 대해 정수 파싱 규칙을 적용한 결과를 설정합니다.

    2. 만약 width가 오류이면, width를 0으로 설정합니다.

    3. 만약 width가 0이 아니면:

      1. 선택적으로, 창이 너무 작아지거나 웹에 노출되는 사용 가능한 화면 영역보다 커지지 않도록 사용자 에이전트가 정의한 방식으로 width를 제한(clamp)할 수 있습니다.

      2. 선택적으로, target의 창의 오른쪽 가장자리를 이동시켜 뷰포트의 좌우 가장자리 사이 거리가 width CSS 픽셀이 되도록 하여 창 크기를 조정할 수 있습니다.

      3. 선택적으로, 창이 웹에 노출되는 사용 가능한 화면 영역을 벗어나지 않도록 사용자 에이전트가 정의한 방식으로 target의 창을 이동시킬 수 있습니다.

  8. 만약 tokenizedFeatures["height"]가 존재하면:

    1. heighttokenizedFeatures["height"]에 대해 정수 파싱 규칙을 적용한 결과를 설정합니다.

    2. 만약 height가 오류이면, height를 0으로 설정합니다.

    3. 만약 height가 0이 아니면:

      1. 선택적으로, 창이 너무 작아지거나 웹에 노출되는 사용 가능한 화면 영역보다 커지지 않도록 사용자 에이전트가 정의한 방식으로 height를 제한(clamp)할 수 있습니다.

      2. 선택적으로, target의 창의 하단 가장자리를 이동시켜 뷰포트의 상하 가장자리 사이 거리가 height CSS 픽셀이 되도록 하여 창 크기를 조정할 수 있습니다.

      3. 선택적으로, 창이 웹에 노출되는 사용 가능한 화면 영역을 벗어나지 않도록 사용자 에이전트가 정의한 방식으로 target의 창을 이동시킬 수 있습니다.

지원되는 open() 기능 이름은 다음 중 하나입니다:

width
뷰포트의 너비.
height
뷰포트의 높이.
left
창의 왼쪽 위치.
top
창의 위쪽 위치.

4.2. MediaQueryList 인터페이스

이 절은 HTML에 정의된 이벤트 루프와 통합됩니다. [HTML]

MediaQueryList 객체는 생성 시 연관된 media query list와 연관된 document를 가집니다.

MediaQueryList 객체는 생성된 media query list직렬화된 형태인 연관된 media를 가집니다.

MediaQueryList 객체는 연관된 media query list가 문서의 상태와 일치하는지를 나타내는 연관된 matches state를 가집니다. 일치하면 true, 그렇지 않으면 false입니다.

미디어 쿼리를 평가하고 변경사항 보고를 문서 Document doc에 대해 요청받으면, 다음 단계를 실행합니다:

  1. docdocument로 가지는 각 MediaQueryList 객체 target에 대해, 생성된 순서(가장 오래된 것부터)로 다음 하위 단계를 실행합니다:

    1. 만약 targetmatches state가 마지막 실행 이후 변경되었다면, 이벤트 발화를 수행하여 이름이 change인 이벤트를 target에 대해 MediaQueryListEvent로 발화합니다. 이때 이벤트의 isTrusted 속성은 true로 초기화되고, media 속성은 target의 연관된 media로 초기화되며, matches 속성은 targetmatches state로 초기화됩니다.
뷰포트의 방향 변경을 감지하는 간단한 코드 예시는 다음과 같습니다:
function handleOrientationChange(event) {
    if(event.matches) // landscapeelse}
var mql = matchMedia("(orientation:landscape)");
mql.onchange = handleOrientationChange;
[Exposed=Window]
interface MediaQueryList : EventTarget {
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
  undefined addListener(EventListener? callback);
  undefined removeListener(EventListener? callback);
           attribute EventHandler onchange;
};

media 속성은 연관된 media를 반환해야 합니다.

matches 속성은 연관된 matches state를 반환해야 합니다.

addListener(callback) 메서드가 호출되면, 다음 단계를 실행해야 합니다:

  1. 이벤트 리스너 추가this와, 타입이 change이벤트 리스너로, 콜백은 callback이 되도록 하여 수행합니다.

removeListener(callback) 메서드가 호출되면, 다음 단계를 실행해야 합니다:

  1. 만약 this이벤트 리스너 목록이 타입이 change이고 콜백이 callback이며 capture가 false인 이벤트 리스너를 포함한다면, 그 이벤트 리스너를 제거합니다.

참고: 이 명세는 초기에는 addListener()removeListener() 라는 커스텀 콜백 메커니즘을 사용했고, 콜백은 연관된 media query list를 인수로 호출되었습니다. 지금은 대신 일반 이벤트 메커니즘을 사용합니다. 이전과의 호환성을 위해, 이들 메서드(addListener()removeListener())는 본질적으로 addEventListener()removeEventListener()의 별칭으로 동작합니다. 또한 change 이벤트는 MediaQueryList로 가장됩니다.

다음은 MediaQueryList 인터페이스를 구현하는 모든 객체가 지원해야 하는 이벤트 핸들러들(및 해당 핸들러 이벤트 타입)입니다:

이벤트 핸들러 이벤트 핸들러 이벤트 타입
onchange change
Tests
[Exposed=Window]
interface MediaQueryListEvent : Event {
  constructor(CSSOMString type, optional MediaQueryListEventInit eventInitDict = {});
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
};

dictionary MediaQueryListEventInit : EventInit {
  CSSOMString media = "";
  boolean matches = false;
};

media 속성은 생성 시 초기화된 값을 반환해야 합니다.

matches 속성은 생성 시 초기화된 값을 반환해야 합니다.

4.2.1. 이벤트 요약

이 절은 비규범적입니다.

이벤트 인터페이스 관심 대상 설명
change MediaQueryListEvent MediaQueryList MediaQueryList에서 matches state가 변경될 때 발생합니다.

4.3. Screen 인터페이스

이름에서 알 수 있듯이, Screen 인터페이스는 출력 장치의 화면에 대한 정보를 나타냅니다.

[Exposed=Window]
interface Screen {
  readonly attribute long availWidth;
  readonly attribute long availHeight;
  readonly attribute long width;
  readonly attribute long height;
  readonly attribute unsigned long colorDepth;
  readonly attribute unsigned long pixelDepth;
};

availWidth 속성은 웹에 노출되는 사용 가능한 화면 영역(Web-exposed available screen area)의 너비를 반환해야 합니다.

availHeight 속성은 웹에 노출되는 사용 가능한 화면 영역의 높이를 반환해야 합니다.

width 속성은 웹에 노출되는 화면 영역(Web-exposed screen area)의 너비를 반환해야 합니다.

height 속성은 웹에 노출되는 화면 영역의 높이를 반환해야 합니다.

colorDepthpixelDepth 속성은 출력 장치에서 픽셀 하나에 할당된 색상 비트 수(알파 채널 제외)를 반환해야 합니다. 사용자 에이전트가 출력 장치가 사용하는 비트 수를 반환할 수 없다면, 프레임버퍼나 내부 표현의 추정값 등 가능한 가장 근접한 추정값을 반환해야 합니다. 이들 속성에 대해서는, 사용자 에이전트는 적어도 color 미디어 특성 값의 세 배 이상이 되는 값을 반환해야 합니다. 색 성분들이 동일한 비트 수로 표현되지 않는 경우, 반환 값은 color 미디어 특성 값의 세 배보다 클 수 있습니다. 프라이버시 고려로 인해 색 깊이를 알 수 없거나 반환하고 싶지 않은 경우, 24를 반환해야 합니다.

참고: colorDepthpixelDepth 속성은 호환성 이유로 같은 값을 반환합니다.

참고: 일부 비준수 구현은 24 대신 32를 반환하는 것으로 알려져 있습니다.

Tests

5. Document 인터페이스에 대한 확장

partial interface Document {
  Element? elementFromPoint(double x, double y);
  sequence<Element> elementsFromPoint(double x, double y);
  CaretPosition? caretPositionFromPoint(double x, double y, optional CaretPositionFromPointOptions options = {});
  readonly attribute Element? scrollingElement;
};

dictionary CaretPositionFromPointOptions {
  sequence<ShadowRoot> shadowRoots = [];
};

elementFromPoint(x, y) 메서드는 다음 단계들을 따라야 한다:

  1. 어느 인수든 음수이거나, x뷰포트의 너비(렌더링된 스크롤 바의 크기 제외)보다 크거나, y뷰포트의 높이(렌더링된 스크롤 바의 크기 제외)보다 크거나, 문서에 연결된 뷰포트가 없다면 null을 반환하고 이 단계들을 종료한다.

  2. 박스뷰포트 내에서 좌표 x,y에서 히트 테스트의 대상이 되고, 자식에 적용되는 변형을 적용할 때, 연결된 요소를 반환하고 이 단계들을 종료한다.

  3. 문서에 루트 요소가 있다면, 루트 요소를 반환하고 이 단계들을 종료한다.

  4. null을 반환한다.

참고: elementFromPoint() 메서드는 반드시 최상단에 그려진 요소를 반환하는 것은 아니다. 예를 들어, pointer-events CSS 속성을 사용하면 요소가 히트 테스트 대상에서 제외될 수 있다.

테스트

elementsFromPoint(x, y) 메서드는 다음 단계들을 따라야 한다:

  1. sequence를 새로운 빈 시퀀스로 만든다.

  2. 어느 인수든 음수이거나, x뷰포트의 너비(렌더링된 스크롤 바의 크기 제외)보다 크거나, y뷰포트의 높이(렌더링된 스크롤 바의 크기 제외)보다 크거나, 문서에 연결된 뷰포트가 없다면 sequence를 반환하고 이 단계들을 종료한다.

  3. 박스마다, 뷰포트 내에서 페인트 순서(최상단 박스부터 시작)대로, 좌표 x,y에서 히트 테스트의 대상이 되고 겹치는 것이 없어도, 자식에 적용되는 변형을 적용할 때 연결된 요소를 sequence에 추가한다.

  4. 문서에 루트 요소가 있고, sequence의 마지막 항목이 루트 요소가 아니라면, 루트 요소sequence에 추가한다.

  5. sequence를 반환한다.

테스트

caretPositionFromPoint(x, y, options) 메서드는 다음 단계들을 실행한 결과를 반환해야 한다:

  1. 문서에 연결된 뷰포트가 없다면 null을 반환한다.

  2. 어느 인수든 음수이거나, x뷰포트의 너비(렌더링된 스크롤 바의 크기 제외)보다 크거나, y뷰포트의 높이(렌더링된 스크롤 바의 크기 제외)보다 크면 null을 반환한다.

  3. 뷰포트의 좌표 x,y에서 자식에 적용되는 변형을 적용할 때, 텍스트 삽입 지점 표시가 삽입되지 않았다면 null을 반환한다.

  4. 뷰포트의 좌표 x,y에서 자식에 적용되는 변형을 적용할 때, 텍스트 입력 위젯(대체 요소이기도 함)에 텍스트 삽입 지점 표시가 삽입된다면, 다음과 같이 속성이 설정된 caret position을 반환한다:

    caret node
    텍스트 입력 위젯에 해당하는 노드.
    caret offset
    텍스트 삽입 지점 표시의 왼쪽에 있는 16비트 단위 수.
  5. 그 외의 경우:

    1. caretPosition튜플로, caretPositionNode(노드)와 caretPositionOffset(0 이상의 정수)로 하여, 자식에 적용되는 변형을 적용할 때 텍스트 삽입 지점 표시가 삽입될 위치로 한다.

    2. startNodecaretPositioncaretPositionNode로, startOffsetcaretPositioncaretPositionOffset로 한다.

    3. startNode노드이고, startNode루트섀도우 루트이며, startNode루트options["shadowRoots"]의 어느 섀도우를 포함한 포괄 조상도 아니면, 다음 단계를 반복한다:

      1. startOffset인덱스로, startNode루트호스트로 설정한다.

      2. startNodestartNode루트호스트부모로 설정한다.

    4. 다음과 같이 속성이 설정된 caret position을 반환한다:

      1. caret nodestartNode로 설정한다.

      2. caret offsetstartOffset으로 설정한다.

참고:caret positionlive가 아니다.

참고: 히트 테스트의 세부 사항은 이 명세의 범위에 포함되지 않으므로 elementFromPoint()caretPositionFromPoint() 역시 그렇다. 히트 테스트는 앞으로 CSS나 HTML의 개정판에서 정의될 예정이다.

scrollingElement 속성은, get 시 다음 단계들을 실행한다:

  1. Document쿼크 모드라면, 다음 하위 단계들을 따른다:

    1. body 요소가 존재하고, 스크롤될 가능성이 있는 요소가 아니라면, body 요소를 반환하고 이 단계들을 중단한다.

      이 목적을 위해, overflow:clip 값이 body 요소의 부모 요소에 있다면 overflow:hidden으로 취급해야 한다.

    2. null을 반환하고 이 단계들을 중단한다.

  2. 루트 요소가 있다면, 루트 요소를 반환하고 이 단계들을 중단한다.

  3. null을 반환한다.

참고: 항상 쿼크 모드 동작을 사용하는 비표준 사용자 에이전트의 경우, scrollTopscrollLeft에 대해, scrollingElement 속성도 항상 body 요소(또는 존재하지 않으면 null)를 반환할 것으로 예상된다. 이 API는 웹 개발자가 올바른 스크롤링 API용 요소를 얻기 위해 특정 사용자 에이전트의 동작을 가정하지 않고 스크롤을 발생시키지 않아도 뷰포트를 스크롤하는 요소를 알 수 있도록 존재한다.

참고: body 요소는 HTML의 document.body와 다르다. 후자는 frameset 요소를 반환할 수 있다.

테스트

5.1. CaretPosition 인터페이스

caret position은 텍스트 삽입 지점 표시기의 위치를 나타냅니다. 항상 연결된 caret nodecaret offset이 있습니다. 이것은 CaretPosition 객체로 표현됩니다.

[Exposed=Window]
interface CaretPosition {
  readonly attribute Node offsetNode;
  readonly attribute unsigned long offset;
  [NewObject] DOMRect? getClientRect();
};

offsetNode 속성은 caret node를 반환해야 합니다.

offset 속성은 caret offset을 반환해야 합니다.

getClientRect() 메서드는 다음 단계를 따라야 하며, 값을 반환하는 첫 번째 단계에서 중단해야 합니다:

  1. caret node가 문서에 있는 교체 요소(replaced element)인 텍스트 입력 위젯인 경우, 위젯의 caret을 나타내는 scaled DOMRect 객체를 caret offset 값에 따라 반환합니다. 요소와 그 조상에 적용되는 transforms가 적용됩니다.

  2. 그 외의 경우:

    1. caretRange를 생성합니다. 이는 Range 객체로, start nodeend nodecaret node로 설정되고, start offsetend offsetcaret offset으로 설정된, collapse된 Range입니다.

    2. caretRange에 대해 DOMRect 객체를 반환합니다. 이는 getBoundingClientRect() 메서드를 caretRange에 호출한 결과입니다.

참고:DOMRect 객체는 live가 아닙니다.

테스트

6. Element 인터페이스 확장

enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
dictionary ScrollIntoViewOptions : ScrollOptions {
  ScrollLogicalPosition block = "start";
  ScrollLogicalPosition inline = "nearest";
  ScrollIntoViewContainer container = "all";
};

enum ScrollIntoViewContainer { "all", "nearest" };

dictionary CheckVisibilityOptions {
    boolean checkOpacity = false;
    boolean checkVisibilityCSS = false;
    boolean contentVisibilityAuto = false;
    boolean opacityProperty = false;
    boolean visibilityProperty = false;
};

partial interface Element {
  DOMRectList getClientRects();
  [NewObject] DOMRect getBoundingClientRect();

  boolean checkVisibility(optional CheckVisibilityOptions options = {});

  undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
  undefined scroll(optional ScrollToOptions options = {});
  undefined scroll(unrestricted double x, unrestricted double y);
  undefined scrollTo(optional ScrollToOptions options = {});
  undefined scrollTo(unrestricted double x, unrestricted double y);
  undefined scrollBy(optional ScrollToOptions options = {});
  undefined scrollBy(unrestricted double x, unrestricted double y);
  attribute unrestricted double scrollTop;
  attribute unrestricted double scrollLeft;
  readonly attribute long scrollWidth;
  readonly attribute long scrollHeight;
  readonly attribute long clientTop;
  readonly attribute long clientLeft;
  readonly attribute long clientWidth;
  readonly attribute long clientHeight;
  readonly attribute double currentCSSZoom;
};

참고: checkOpacitycheckVisibilityCSS 속성은 과거 이름입니다. 이 속성들은 새로운 명명 규칙에 맞는 별칭을 가지고 있습니다. 즉 opacityPropertyvisibilityProperty 입니다.

getClientRects() 메서드는 호출 시 다음 알고리즘의 결과를 반환해야 합니다:

  1. 호출된 요소에 연결된 box가 없으면 빈 DOMRectList 객체를 반환하고 알고리즘을 중단합니다.

  2. 요소에 연결된 SVG 레이아웃 박스가 있으면 scaled DOMRectList 객체(단일 DOMRect 객체 포함)를 SVG 명세에 따라 요소의 경계 상자를 설명하며, 요소와 그 조상에 적용되는 transforms를 적용하여 반환합니다.

  3. box fragment에 대해 내용 순서대로, 경계 영역(높이나 너비가 0이어도 포함)을 설명하는 DOMRect 객체들을 포함하는 DOMRectList 객체를 반환합니다. 다음 제약조건을 적용합니다:

    • 요소와 그 조상에 적용되는 transforms를 적용합니다.

    • 호출된 요소의 display 속성의 계산 값이 table 또는 inline-table이면, table box와 caption box(있다면)를 포함하되, 익명 컨테이너 박스는 포함하지 않습니다.

    • 익명 블록 박스는 자식 박스(들)로 교체하고, 최종 목록에 익명 블록 박스가 남지 않을 때까지 반복합니다.

참고: DOMRect 객체들은 getClientRects() 호출 시 live가 아닙니다.

테스트

getBoundingClientRect() 메서드는 element 요소에서 호출될 때 bounding box 가져오기의 결과를 반환해야 합니다.

elementbounding box 가져오기를 위해 다음 단계를 수행합니다:
  1. listelement에서 getClientRects() 를 호출한 결과로 설정합니다.

  2. list가 비어 있다면 DOMRect 객체를 반환하는데, x, y, width 그리고 height 멤버들은 모두 0이어야 합니다.

  3. list의 모든 사각형이 너비 또는 높이가 0이라면, list의 첫 번째 사각형을 반환합니다.

  4. 그 외의 경우, DOMRect 객체를 반환하는데, list 내에서 높이나 너비가 0이 아닌 모든 사각형을 포함하는 가장 작은 사각형을 설명합니다.

참고: DOMRect 객체는 getBoundingClientRect() 로 반환되며 live가 아닙니다.

다음 예제는 문서 내 첫 번째 div 요소의 크기를 가져옵니다:
var example = document.getElementsByTagName("div")[0].getBoundingClientRect();
var exampleWidth = example.width;
var exampleHeight = example.height;
테스트
참고: checkVisibility() 메서드는 요소가 잠재적으로 "보이는지"에 대한 간단한 검사를 제공합니다. 기본적으로 박스 트리를 기반으로 한 매우 단순하고 직관적인 방법을 사용하지만, 원하는 "가시성" 정의에 따라 추가 검사를 선택적으로 활성화할 수 있습니다.

checkVisibility(options) 메서드는 요소 this에서 호출될 때 다음 단계를 실행해야 합니다:

  1. this에 연관된 박스가 없다면, false를 반환합니다.

  2. this평면 트리 상위 요소가 content-visibility: hidden인 경우, false를 반환합니다.

  3. optionsopacityProperty 또는 checkOpacity 멤버가 true이고, this 또는 this평면 트리 상위 요소가 계산된 opacity 값이 0이라면, false를 반환합니다.

  4. optionsvisibilityProperty 또는 checkVisibilityCSS 멤버가 true이고, this비가시적이라면, false를 반환합니다.

  5. optionscontentVisibilityAuto 멤버가 true이고, this평면 트리 상위 요소가 content-visibility: auto로 인해 콘텐츠를 건너뛴다면, false를 반환합니다.

  6. true를 반환합니다.

테스트

scrollIntoView(arg) 메서드는 다음 단계를 실행해야 합니다:

  1. behavior를 "auto"로 설정합니다.

  2. block을 "start"로 설정합니다.

  3. inline을 "nearest"로 설정합니다.

  4. containernull로 설정합니다.

  5. argScrollIntoViewOptions 딕셔너리라면:

    1. behaviorbehavior 딕셔너리 멤버값으로 설정합니다.

    2. blockblock 딕셔너리 멤버값으로 설정합니다.

    3. inlineinline 딕셔너리 멤버값으로 설정합니다.

    4. container 딕셔너리 멤버값이 "nearest"라면, container를 해당 요소로 설정합니다.

  6. 그렇지 않고 arg가 false라면, block을 "end"로 설정합니다.

  7. 요소에 연관된 박스가 없거나, UA 기능에 사용할 수 없다면, 반환합니다.

  8. 해당 요소를 뷰로 스크롤합니다. behavior, block, inline, container 값을 사용합니다.

  9. 필요하다면 사용자의 주의를 해당 요소로 끄는 다른 동작을 수행합니다.

컴포넌트는 scrollIntoView를 사용하여 관심 있는 콘텐츠를 지정한 정렬로 스크롤할 수 있습니다:
<style>
    .scroller { overflow: auto; scroll-padding: 8px; }
    .slide { scroll-margin: 16px; scroll-snap-align: center; }
</style>
<div class="carousel">
    <div class="slides scroller">
        <div id="s1" class="slide">
        <div id="s2" class="slide">
        <div id="s3" class="slide">
    </div>
    <div class="markers">
        <button data-target="s1">1</button>
        <button data-target="s2">2</button>
        <button data-target="s3">3</button>
    </div>
</div>
<script>
    document.querySelector('.markers').addEventListener('click', (evt) => {
        const target = document.getElementById(evt.target.dataset.target);
        if (!target) return;
        // scrollIntoView는 scroll-snap-align, scroll-margin, 그리고 스크롤 컨테이너의 scroll-padding을 올바르게 맞춥니다.
        target.scrollIntoView({
            // 가장 가까운 스크롤 컨테이너만 스크롤합니다.
            container: 'nearest',
            behavior: 'smooth'
        });
    });
</script>
테스트

scroll() 메서드는 다음 단계를 실행해야 합니다:

  1. 하나의 인자로 호출된 경우, 다음 하위 단계를 따릅니다:

    1. options를 인자로 설정합니다.

    2. 만약 options 딕셔너리 멤버(left, top)가 있다면, 비유한 값 정규화를 수행합니다.

    3. xoptionsleft 값으로, 없으면 요소의 현재 x축 스크롤 위치로 설정합니다.

    4. yoptionstop 값으로, 없으면 요소의 현재 y축 스크롤 위치로 설정합니다.

  2. 두 개의 인자로 호출된 경우, 다음 하위 단계를 따릅니다:

    1. options를 null ECMAScript에서 IDL값으로 변환하여 ScrollToOptions 딕셔너리로 설정합니다.

    2. xy를 각각 인자로 설정합니다.

    3. 비유한 값 정규화xy에 수행합니다.

    4. optionsleftx 값을 설정합니다.

    5. optionstopy 값을 설정합니다.

  3. document를 요소의 노드 document로 설정합니다.

  4. document활성 document가 아니면, 이 단계를 종료합니다.

  5. windowdocumentdefaultView 속성 값으로 설정합니다.

  6. window가 null이면, 이 단계를 종료합니다.

  7. 요소가 root element이고 documentquirks mode라면, 이 단계를 종료합니다.

  8. 요소가 root element라면, window에서 scroll()windowscrollX를 첫 번째 인자로, y를 두 번째 인자로 호출하고, 단계를 종료합니다.

  9. 요소가 body 요소이고, documentquirks mode이며, 해당 요소가 잠재적으로 스크롤 가능이 아니라면, window에서 scroll()options만 인자로 호출하고, 단계를 종료합니다.

  10. 요소에 박스가 없거나, 스크롤 박스가 없거나, 오버플로우가 없다면, 단계를 종료합니다.

  11. 요소를 스크롤합니다. 위치는 x,y이고, 스크롤 동작은 optionsbehavior 값입니다.

scrollTo() 메서드가 호출되면, UA는 scroll() 메서드가 동일한 인자로 호출된 것처럼 동작해야 합니다.

scrollBy() 메서드가 호출되면, UA는 다음 단계를 실행해야 합니다:

  1. 하나의 인자로 호출되면, 다음 하위 단계를 따릅니다:

    1. options를 인자로 설정합니다.

    2. lefttop 딕셔너리 멤버가 존재하는 경우, 비유한 값 정규화를 수행합니다.

  2. 두 개의 인자로 호출되면, 다음 하위 단계를 따릅니다:

    1. options를 null ECMAScript에서 IDL 값으로 변환ScrollToOptions 딕셔너리로 설정합니다. [WEBIDL]

    2. xy를 각각 인자로 설정합니다.

    3. xy에 대해 비유한 값 정규화를 수행합니다.

    4. optionsleft 딕셔너리 멤버에 x 값을 할당합니다.

    5. optionstop 딕셔너리 멤버에 y 값을 할당합니다.

  3. scrollLeft 값을 left 딕셔너리 멤버에 더합니다.

  4. scrollTop 값을 top 딕셔너리 멤버에 더합니다.

  5. scroll() 메서드가 options 하나의 인자로 호출된 것처럼 동작합니다.

테스트

scrollTop 속성은 가져올 때 다음 단계를 실행한 결과를 반환해야 합니다:

  1. document를 요소의 노드 문서로 설정합니다.

  2. document활성 문서가 아니라면, 0을 반환하고 이 단계를 종료합니다.

  3. windowdocumentdefaultView 속성 값으로 설정합니다.

  4. window가 null이면, 0을 반환하고 이 단계를 종료합니다.

  5. 요소가 루트 요소이고 document쿼크 모드라면, 0을 반환하고 이 단계를 종료합니다.

  6. 요소가 루트 요소라면 windowscrollY 값을 반환합니다.

  7. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않으면, windowscrollY 값을 반환합니다.

  8. 요소에 연관된 박스가 없다면, 0을 반환하고 단계를 종료합니다.

  9. 요소의 스크롤 영역에서 요소의 패딩 엣지의 상단과 맞닿는 정렬 지점의 y좌표를 반환합니다.

scrollTop 속성을 설정할 때는 다음 단계를 실행해야 합니다:

  1. y를 주어진 값으로 설정합니다.

  2. y비유한 값 정규화를 수행합니다.

  3. document를 요소의 노드 문서로 설정합니다.

  4. document활성 문서가 아니라면, 단계를 종료합니다.

  5. windowdocumentdefaultView 속성 값으로 설정합니다.

  6. window가 null이면, 단계를 종료합니다.

  7. 요소가 루트 요소이고 document쿼크 모드라면, 단계를 종료합니다.

  8. 요소가 루트 요소라면 window에서 scroll()windowscrollX 값을 첫 번째 인자로, y를 두 번째 인자로 하여 호출하고 단계를 종료합니다.

  9. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않다면, window에서 scroll()windowscrollX 값을 첫 번째 인자로, y를 두 번째 인자로 하여 호출하고 단계를 종료합니다.

  10. 요소에 연관된 박스가 없거나, 요소에 스크롤 박스가 없거나, 요소에 오버플로우가 없으면 단계를 종료합니다.

  11. 요소를 스크롤합니다. scrollLeft, y로 이동하며, 스크롤 동작은 "auto"입니다.

테스트

scrollLeft 속성은 가져올 때 다음 단계를 실행한 결과를 반환해야 합니다:

  1. document를 요소의 노드 문서로 설정합니다.

  2. document활성 문서가 아니라면, 0을 반환하고 이 단계를 종료합니다.

  3. windowdocumentdefaultView 속성 값으로 설정합니다.

  4. window가 null이면, 0을 반환하고 이 단계를 종료합니다.

  5. 요소가 루트 요소이고 document쿼크 모드라면, 0을 반환하고 이 단계를 종료합니다.

  6. 요소가 루트 요소라면 windowscrollX 값을 반환합니다.

  7. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않으면, windowscrollX 값을 반환합니다.

  8. 요소에 연관된 박스가 없다면, 0을 반환하고 단계를 종료합니다.

  9. 요소의 스크롤 영역에서 요소의 패딩 엣지의 왼쪽과 맞닿는 정렬 지점의 x좌표를 반환합니다.

scrollLeft 속성을 설정할 때는 다음 단계를 실행해야 합니다:

  1. x를 주어진 값으로 설정합니다.

  2. x비유한 값 정규화를 수행합니다.

  3. document를 요소의 노드 문서로 설정합니다.

  4. document활성 문서가 아니라면, 단계를 종료합니다.

  5. windowdocumentdefaultView 속성 값으로 설정합니다.

  6. window가 null이면, 단계를 종료합니다.

  7. 요소가 루트 요소이고 document쿼크 모드라면, 단계를 종료합니다.

  8. 요소가 루트 요소라면 window에서 scroll()x를 첫 번째 인자로, windowscrollY 값을 두 번째 인자로 하여 호출하고 단계를 종료합니다.

  9. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않다면, window에서 scroll()x를 첫 번째 인자로, windowscrollY 값을 두 번째 인자로 하여 호출하고 단계를 종료합니다.

  10. 요소에 연관된 박스가 없거나, 요소에 스크롤 박스가 없거나, 요소에 오버플로우가 없으면 단계를 종료합니다.

  11. 요소를 스크롤합니다. x, scrollTop로 이동하며, 스크롤 동작은 "auto"입니다.

테스트

scrollWidth 속성은 다음 단계의 결과를 반환해야 합니다:

  1. document를 요소의 노드 문서로 설정합니다.

  2. document활성 문서가 아니라면, 0을 반환하고 단계를 종료합니다.

  3. viewport width뷰포트의 너비(스크롤바 너비 제외)로 설정하며, 뷰포트가 없으면 0입니다.

  4. 요소가 루트 요소이고 document쿼크 모드가 아니면, max(뷰포트 스크롤 영역 너비, viewport width)를 반환합니다.

  5. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않으면, max(뷰포트 스크롤 영역 너비, viewport width)를 반환합니다.

  6. 요소에 연관된 박스가 없다면 0을 반환하고 단계를 종료합니다.

  7. 요소의 스크롤 영역의 너비를 반환합니다.

테스트

scrollHeight 속성은 다음 단계의 결과를 반환해야 합니다:

  1. document를 요소의 노드 문서로 설정합니다.

  2. document활성 문서가 아니라면, 0을 반환하고 단계를 종료합니다.

  3. viewport height뷰포트의 높이(스크롤바 높이 제외)로 설정하며, 뷰포트가 없으면 0입니다.

  4. 요소가 루트 요소이고 document쿼크 모드가 아니면, max(뷰포트 스크롤 영역 높이, viewport height)를 반환합니다.

  5. 요소가 body 요소이고 document쿼크 모드이며, 요소가 잠재적으로 스크롤 가능하지 않으면, max(뷰포트 스크롤 영역 높이, viewport height)를 반환합니다.

  6. 요소에 연관된 박스가 없다면 0을 반환하고 단계를 종료합니다.

  7. 요소의 스크롤 영역의 높이를 반환합니다.

clientTop 속성은 다음 단계를 실행해야 합니다:

  1. 요소에 연관된 박스가 없거나 박스가 인라인이면, 0을 반환합니다.

  2. 비스케일드(unscaled) border-top-width의 계산값과, 패딩 엣지의 상단과 테두리 엣지의 상단 사이에 렌더링된 스크롤바의 높이를 더해서 반환합니다. 이때 요소 및 상위 요소에 적용된 변형(transform)은 무시합니다.

테스트

clientLeft 속성은 다음 단계를 실행해야 합니다:

  1. 요소에 연결된 박스가 없거나 박스가 인라인이면, 0을 반환합니다.

  2. 비스케일(unscaled) 계산값 border-left-width에, 패딩 엣지의 왼쪽과 테두리 엣지의 왼쪽 사이에 렌더링된 스크롤바의 너비를 더해서 반환하며, 요소 및 상위 요소에 적용된 변형(transform)은 무시합니다.

clientWidth 속성은 다음 단계를 실행해야 합니다:

  1. 요소에 연결된 박스가 없거나 박스가 인라인이면, 0을 반환합니다.

  2. 요소가 루트 요소이고 요소의 노드 문서쿼크 모드가 아니거나, 요소가 body 요소이고 요소의 노드 문서쿼크 모드면, 뷰포트의 너비(렌더링된 스크롤바 크기 제외)를 반환합니다.

  3. 비스케일(unscaled) 패딩 엣지의 너비에서, 패딩 엣지테두리 엣지 사이에 렌더링된 스크롤바의 너비를 제외한 값을 반환하며, 요소 및 상위 요소에 적용된 변형(transform)은 무시합니다.

clientHeight 속성은 다음 단계를 실행해야 합니다:

  1. 요소에 연결된 박스가 없거나 박스가 인라인이면, 0을 반환합니다.

  2. 요소가 루트 요소이고 요소의 노드 문서쿼크 모드가 아니거나, 요소가 body 요소이고 요소의 노드 문서쿼크 모드면, 뷰포트의 높이(렌더링된 스크롤바 크기 제외)를 반환합니다.

  3. 비스케일(unscaled) 패딩 엣지의 높이에서, 패딩 엣지테두리 엣지 사이에 렌더링된 스크롤바의 높이를 제외한 값을 반환하며, 요소 및 상위 요소에 적용된 변형(transform)은 무시합니다.

currentCSSZoom 속성은 요소의 effective zoom 값을 반환해야 하며, 요소가 렌더링 중이 아니면 1.0을 반환합니다.

테스트

6.1. Element 스크롤 멤버

스크롤-인투-뷰 위치 결정을 위해, targetElement, pseudo-element, 또는 Range일 때, 스크롤 동작 behavior, block 플로우 방향 위치 block, 인라인 기준 방향 위치 inline, 스크롤 박스 scrolling box와 함께 다음 단계를 실행합니다:

  1. target bounding border box를, targetElement이면 Element의 getBoundingClientRect() 반환값, targetRange이면 Range의 getBoundingClientRect() 반환값으로 설정합니다.

  2. scrolling box edge Ablock 플로우 방향시작 엣지(beginning edge)로, element edge Ascrolling box edge A와 같은 물리적 방향의 target bounding border box 엣지로 설정합니다.

  3. scrolling box edge Bblock 플로우 방향끝 엣지(ending edge)로, element edge Bscrolling box edge B와 같은 물리적 방향의 target bounding border box 엣지로 설정합니다.

  4. scrolling box edge C인라인 기준 방향시작 엣지(beginning edge)로, element edge Cscrolling box edge C와 같은 물리적 방향의 target bounding border box 엣지로 설정합니다.

  5. scrolling box edge D인라인 기준 방향끝 엣지(ending edge)로, element edge Dscrolling box edge D와 같은 물리적 방향의 target bounding border box 엣지로 설정합니다.

  6. element heightelement edge Aelement edge B 사이의 거리로 설정합니다.

  7. scrolling box heightscrolling box edge Ascrolling box edge B 사이의 거리로 설정합니다.

  8. element widthelement edge Celement edge D 사이의 거리로 설정합니다.

  9. scrolling box widthscrolling box edge Cscrolling box edge D 사이의 거리로 설정합니다.

  10. positionscrolling box가 다음 단계를 따라 갖게 될 스크롤 위치로 설정합니다:

    1. block이 "start"면, element edge Ascrolling box edge A를 맞춥니다.

    2. 그렇지 않고 block이 "end"면, element edge Bscrolling box edge B를 맞춥니다.

    3. 그렇지 않고 block이 "center"면, target bounding border box의 중앙과 scrolling box의 중앙을 block 플로우 방향으로 맞춥니다.

    4. 그 외의 경우 block이 "nearest"이면:

      element edge Aelement edge B가 모두 scrolling box edge Ascrolling box edge B 밖에 있으면
      아무 것도 하지 않습니다.
      element edge Ascrolling box edge A 밖에 있고 element heightscrolling box height보다 작거나,
      element edge Bscrolling box edge B 밖에 있고 element heightscrolling box height보다 크면
      element edge Ascrolling box edge A를 맞춥니다.
      element edge Ascrolling box edge A 밖에 있고 element heightscrolling box height보다 크거나,
      element edge Bscrolling box edge B 밖에 있고 element heightscrolling box height보다 작으면
      element edge Bscrolling box edge B를 맞춥니다.
    5. inline이 "start"면, element edge Cscrolling box edge C를 맞춥니다.

    6. 그렇지 않고 inline이 "end"면, element edge Dscrolling box edge D를 맞춥니다.

    7. 그렇지 않고 inline이 "center"면, target bounding border box의 중앙과 scrolling box의 중앙을 인라인 기준 방향으로 맞춥니다.

    8. 그 외의 경우 inline이 "nearest"이면:

      element edge Celement edge D가 모두 scrolling box edge Cscrolling box edge D 밖에 있으면
      아무 것도 하지 않습니다.
      element edge Cscrolling box edge C 밖에 있고 element widthscrolling box width보다 작거나,
      element edge Dscrolling box edge D 밖에 있고 element widthscrolling box width보다 크면
      element edge Cscrolling box edge C를 맞춥니다.
      element edge Cscrolling box edge C 밖에 있고 element widthscrolling box width보다 크거나,
      element edge Dscrolling box edge D 밖에 있고 element widthscrolling box width보다 작으면
      element edge Dscrolling box edge D를 맞춥니다.
    9. targetElement이고, 해당 요소가 scroll snap position을 정의한다면, UA는 scroll snap position스크롤 스냅을 적용해야 하며, 가장 가까운 스크롤 컨테이너scroll snap 컨테이너일 때 적용합니다. UA는 스크롤 컨테이너scroll-snap-type: none일 때도 적용할 수 있습니다.

    10. position을 반환합니다.

대상 스크롤하기(scroll a target into view)target에 실행한다. targetElement, pseudo-element, 또는 Range이다. 스크롤 동작 behavior, 블록 플로우 방향 위치 block, 인라인 기본 방향 위치 inline, 그리고 스크롤이 해당 지점에서 멈추는 선택적 Element container와 함께 다음 단계를 실행한다:
  1. 각 상위 요소 또는 뷰포트스크롤 박스 scrolling box를 생성하는 경우, 가장 안쪽부터 바깥쪽 스크롤 박스 순서대로 다음 하위 단계를 실행한다:

    1. target과 연결된 Document가 해당 요소 또는 뷰포트와 연결된 Document동일 출처가 아니라면 단계를 종료한다.

    2. position스크롤 위치 결정 절차를 target, behavior, block, inline, scrolling box로 실행한 결과로 설정한다.

    3. positionscrolling box의 현재 스크롤 위치와 다르거나, scrolling box에 진행 중인 부드러운 스크롤(smooth scroll)이 있다면,

      1. scrolling box가 요소와 연결된 경우
        해당 요소의 scrolling boxposition으로 스크롤 수행한다. 이때 연관된 요소는 해당 요소이고, behavior는 스크롤 동작이다.
        scrolling box뷰포트와 연결된 경우
        1. document뷰포트의 연결 Document로 설정한다.

        2. root elementdocument루트 요소로(없으면 null) 설정한다.

        3. 뷰포트 스크롤 수행뷰포트position으로, root element를 연관 요소로, behavior를 스크롤 동작으로 하여 수행한다.

    4. container가 null이 아니고 scrolling boxshadow-including inclusive ancestor이거나, 뷰포트이며 해당 documentshadow-including inclusive ancestor라면, 나머지 단계를 중단한다.

요소 스크롤하기(scroll an element) (pseudo-element 포함) elementx,y로 스크롤한다. 선택적으로 behavior 스크롤 동작(생략 시 "auto")과 함께:

  1. boxelement의 연관 스크롤 박스로 설정한다.

  2. box가 오른쪽 오버플로우 방향을 가지면
    x = max(0, min(x, element 스크롤 영역 너비 - element 패딩 엣지 너비))
    box가 왼쪽 오버플로우 방향을 가지면
    x = min(0, max(x, element 패딩 엣지 너비 - element 스크롤 영역 너비))
  3. box가 아래쪽 오버플로우 방향을 가지면
    y = max(0, min(y, element 스크롤 영역 높이 - element 패딩 엣지 높이))
    box가 위쪽 오버플로우 방향을 가지면
    y = min(0, max(y, element 패딩 엣지 높이 - element 스크롤 영역 높이))
  4. position을, box의 왼쪽과 스크롤 영역 x좌표 x가 정렬되고, box의 상단과 스크롤 영역 y좌표 y가 정렬된 스크롤 위치로 설정한다.

  5. positionbox의 현재 스크롤 위치와 같고, box에 진행 중인 부드러운 스크롤이 없다면, 단계를 중단한다.

  6. 스크롤 수행boxposition으로, element를 연관 요소로, behavior를 스크롤 동작으로 하여 실행한다.

7. HTMLElement 인터페이스 확장

partial interface HTMLElement {
  readonly attribute Element? scrollParent;
  readonly attribute Element? offsetParent;
  readonly attribute long offsetTop;
  readonly attribute long offsetLeft;
  readonly attribute long offsetWidth;
  readonly attribute long offsetHeight;
};

scrollParent 속성은 다음 단계를 실행한 결과를 반환해야 합니다:

  1. 다음 중 하나라도 참이면 null을 반환하고 알고리즘을 종료합니다:

  2. ancestorcontaining block으로 설정하고, flat tree에서 반복합니다:

    1. ancestorinitial containing block이면, 요소의 문서에 대해 scrollingElement 를 반환합니다(요소에서 closed-shadow-hidden이 아니면), 아니면 null을 반환합니다.

    2. ancestor가 요소에서 closed-shadow-hidden이 아니고, scroll container라면, 알고리즘을 종료하고 ancestor를 반환합니다.

    3. ancestorposition 속성 계산값이 fixed이고, 어떠한 상위 요소도 fixed 위치 containing block을 생성하지 않으면, 알고리즘을 종료하고 null을 반환합니다.

    4. ancestorcontaining blockflat tree에서의 상위 요소로 설정합니다.

테스트

offsetParent 속성은 다음 단계를 실행한 결과를 반환해야 합니다:

  1. 다음 중 하나라도 참이면 null을 반환하고 알고리즘을 종료합니다:

  2. ancestorflat tree에서 요소의 상위 요소로 설정하고, 반복하여 다음 하위 단계를 실행합니다:

    1. ancestor가 요소에서 closed-shadow-hidden이고, position 속성 계산값이 fixed이며, 어떠한 상위 요소도 fixed 위치 containing block을 생성하지 않으면, 알고리즘을 종료하고 null을 반환합니다.

    2. ancestor가 요소에서 closed-shadow-hidden이 아니고 아래 중 하나라도 만족하면, 알고리즘을 종료하고 ancestor를 반환합니다.

      • 요소가 fixed 위치 containing block에 있고, ancestor가 fixed 위치 자손의 containing block입니다.

      • 요소가 fixed 위치 containing block에 있지 않고:

        • ancestor가 절대 위치 자손의 containing block입니다(자손이 없어도 관계 없음).

        • ancestor가 body 요소입니다.

        • 요소의 position 속성 계산값이 static이고 ancestor가 다음 중 하나: HTML 요소 td, th, table.

      • 요소의 effective zoomancestor와 다릅니다.

    3. ancestorflat tree에서 상위 요소가 더 이상 없으면, 알고리즘을 종료하고 null을 반환합니다.

    4. ancestorflat tree에서의 상위 요소로 설정합니다.

테스트

offsetTop 속성은 다음 단계를 실행한 결과를 반환해야 합니다:

  1. 요소가 body 요소이거나, 연관된 박스가 없다면, 0을 반환하고 알고리즘을 종료합니다.

  2. 요소의 offsetParent 가 null이면, 요소의 첫 번째 border edge의 y좌표(비스케일드, initial containing block 원점 기준, 변형 무시)를 반환하고 알고리즘을 종료합니다.

  3. 요소의 offsetParent 의 첫 번째 padding edge y좌표를 요소의 첫 번째 박스border edge y좌표에서 (비스케일드, initial containing block 원점 기준, 변형 무시) 빼서 반환합니다.

    참고: 여러 줄 박스가 있는 인라인 요소는 첫 번째 박스만 고려됩니다.

테스트

offsetLeft 속성은 다음 단계의 결과를 반환해야 합니다:

  1. 요소가 body 요소이거나 연관된 박스가 없다면 0을 반환하고 알고리즘을 종료합니다.

  2. 요소의 offsetParent 가 null이면, 요소의 첫 번째 border edge의 x좌표(비스케일드, initial containing block 원점 기준, 변형 무시)를 반환하고 알고리즘을 종료합니다.

  3. 요소의 offsetParent 의 첫 번째 padding edge x좌표를 요소의 첫 번째 박스border edge x좌표에서 (비스케일드, initial containing block 원점 기준, 변형 무시) 빼서 반환합니다.

offsetWidth 속성은 다음 단계의 결과를 반환해야 합니다:

  1. 요소에 연관된 박스가 없다면 0을 반환하고 알고리즘을 종료합니다.

  2. 요소의 비스케일드(unscaled) 축 정렬 경계 박스의 너비를 반환합니다. 이는 요소의 border boxes 모든 조각(fragment)에 대해 적용되며, 요소와 상위 요소에 적용된 변형(transform)은 무시합니다.

    요소의 principal boxinline-level box이고 block-level 자손에 의해 "분할"된 경우, block-level 자손에 의해 생성된 조각들도 포함합니다. 단, 너비 또는 높이가 0인 경우는 제외합니다.

테스트

offsetHeight 속성은 다음 단계의 결과를 반환해야 합니다:

  1. 요소에 연관된 박스가 없다면 0을 반환하고 알고리즘을 종료합니다.

  2. 요소의 비스케일드(unscaled) 축 정렬 경계 박스의 높이를 반환합니다. 이는 요소의 border boxes 모든 조각(fragment)에 대해 적용되며, 요소와 상위 요소에 적용된 변형(transform)은 무시합니다.

    요소의 principal boxinline-level box이고 block-level 자손에 의해 "분할"된 경우, block-level 자손에 의해 생성된 조각들도 포함합니다. 단, 너비 또는 높이가 0인 경우는 제외합니다.

8. HTMLImageElement 인터페이스 확장

partial interface HTMLImageElement {
  readonly attribute long x;
  readonly attribute long y;
};

x 속성은 가져올 때, 요소의 첫 번째 border edge스케일된(scaled) x좌표를 initial containing block 원점 기준으로, 요소와 상위 요소에 적용된 변형(transform)을 무시하고 반환합니다. 박스가 없으면 0을 반환합니다.

y 속성은 가져올 때, 요소의 첫 번째 border edge스케일된(scaled) y좌표를 initial containing block 원점 기준으로, 요소와 상위 요소에 적용된 변형(transform)을 무시하고 반환합니다. 박스가 없으면 0을 반환합니다.

테스트

9. Range 인터페이스 확장

partial interface Range {
  DOMRectList getClientRects();
  [NewObject] DOMRect getBoundingClientRect();
};

getClientRects() 메서드는 호출 시, range가 문서에 존재하지 않으면 빈 DOMRectList 객체를 반환하며, 그 외에는 다음 조건을 만족하는 DOMRectList 객체(목록)를 반환해야 합니다:

참고: DOMRect 객체는 getClientRects() 로 반환되며 live가 아닙니다.

테스트

getBoundingClientRect() 메서드는 호출 시 다음 알고리즘 결과를 반환해야 합니다:

  1. list를 동일한 range에서 getClientRects() 를 호출한 결과로 설정합니다.

  2. list가 비어 있으면 DOMRect 객체를 반환하는데, x, y, widthheight 멤버는 모두 0입니다.

  3. list의 모든 사각형이 너비 또는 높이가 0이면, list의 첫 번째 사각형을 반환합니다.

  4. 그 외의 경우, DOMRect 객체를 반환하는데, list 내에서 높이나 너비가 0이 아닌 모든 사각형을 포함하는 가장 작은 사각형을 설명합니다.

참고: DOMRect 객체는 getBoundingClientRect() 로 반환되며 live가 아닙니다.

테스트

10. MouseEvent 인터페이스 확장

오브젝트 IDL fragment가 일부 멤버를 재정의합니다. 해결 방법이 있을까요?

partial interface MouseEvent {
  readonly attribute double screenX;
  readonly attribute double screenY;
  readonly attribute double pageX;
  readonly attribute double pageY;
  readonly attribute double clientX;
  readonly attribute double clientY;
  readonly attribute double x;
  readonly attribute double y;
  readonly attribute double offsetX;
  readonly attribute double offsetY;
};

partial dictionary MouseEventInit {
  double screenX = 0.0;
  double screenY = 0.0;
  double clientX = 0.0;
  double clientY = 0.0;
};
테스트

screenX 속성은 이벤트가 발생한 위치의 x좌표를 웹에 노출된 화면 영역의 원점 기준으로 반환해야 합니다.

screenY 속성은 이벤트가 발생한 위치의 y좌표를 웹에 노출된 화면 영역의 원점 기준으로 반환해야 합니다.

pageX 속성은 다음 단계를 따라야 합니다:

  1. 이벤트의 dispatch flag가 설정되어 있으면, 이벤트가 발생한 위치의 수평 좌표를 초기 containing block의 원점 기준으로 반환하고 단계를 종료합니다.

  2. offset을 이벤트의 연관 Window 객체의 scrollX 속성값(없으면 0)으로 설정합니다.

  3. offset과 이벤트의 clientX 속성값을 더한 값을 반환합니다.

pageY 속성은 다음 단계를 따라야 합니다:

  1. 이벤트의 dispatch flag가 설정되어 있으면, 이벤트가 발생한 위치의 수직 좌표를 초기 containing block의 원점 기준으로 반환하고 단계를 종료합니다.

  2. offset을 이벤트의 연관 Window 객체의 scrollY 속성값(없으면 0)으로 설정합니다.

  3. offset과 이벤트의 clientY 속성값을 더한 값을 반환합니다.

clientX 속성은 이벤트가 발생한 위치의 x좌표를 뷰포트 원점 기준으로 반환해야 합니다.

clientY 속성은 이벤트가 발생한 위치의 y좌표를 뷰포트 원점 기준으로 반환해야 합니다.

x 속성은 clientX 값을 반환해야 합니다.

y 속성은 clientY 값을 반환해야 합니다.

offsetX 속성은 다음 단계를 따라야 합니다:

  1. 이벤트의 dispatch flag가 설정되어 있으면, 이벤트가 발생한 위치의 x좌표를 타겟 노드의 padding edge 원점 기준으로 반환합니다. 이때 요소 및 상위 요소의 변형(transform)은 무시합니다. 그리고 단계를 종료합니다.

  2. 이벤트의 pageX 속성값을 반환합니다.

테스트

offsetY 속성은 다음 단계를 따라야 합니다:

  1. 이벤트의 dispatch flag가 설정되어 있으면, 이벤트가 발생한 위치의 y좌표를 타겟 노드의 padding edge 원점 기준으로 반환합니다. 이때 요소 및 상위 요소의 변형(transform)은 무시합니다. 그리고 단계를 종료합니다.

  2. 이벤트의 pageY 속성값을 반환합니다.

11. 기하(Geometry)

11.1. GeometryUtils 인터페이스

enum CSSBoxType { "margin", "border", "padding", "content" };
dictionary BoxQuadOptions {
  CSSBoxType box = "border";
  GeometryNode relativeTo; // XXX default document (i.e. viewport)
};

dictionary ConvertCoordinateOptions {
  CSSBoxType fromBox = "border";
  CSSBoxType toBox = "border";
};

interface mixin GeometryUtils {
  sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
  DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {});
  DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {});
  DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0
};

Text includes GeometryUtils; // like Range
Element includes GeometryUtils;
CSSPseudoElement includes GeometryUtils;
Document includes GeometryUtils;

typedef (Text or Element or CSSPseudoElement or Document) GeometryNode;

getBoxQuads(options) 메서드는 다음 단계를 실행해야 합니다:

  1. DOM 순서

    p1 = 항상 RTL에서도 좌상단

    scale이 0이면 0으로 나누기, 0x0 반환

    cross-frames 불가, WrongDocumentError 예외?

    포인트는 평면화됨(3D 변형), z=0. getClientRect와 동일

    블록 내 인라인 테스트

    pseudo-elements의 before/after는 요소의 자식으로 간주

    viewport 박스는 모두 동일

테스트

convertQuadFromNode(quad, from, options) 메서드는 다음 단계를 실행해야 합니다:

  1. ...

convertRectFromNode(rect, from, options) 메서드는 다음 단계를 실행해야 합니다:

  1. ...

convertPointFromNode(point, from, options) 메서드는 다음 단계를 실행해야 합니다:

  1. ...

12. VisualViewport

12.1. VisualViewport 인터페이스

[Exposed=Window]
interface VisualViewport : EventTarget {
  readonly attribute double offsetLeft;
  readonly attribute double offsetTop;

  readonly attribute double pageLeft;
  readonly attribute double pageTop;

  readonly attribute double width;
  readonly attribute double height;

  readonly attribute double scale;

  attribute EventHandler onresize;
  attribute EventHandler onscroll;
  attribute EventHandler onscrollend;
};

offsetLeft 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 왼쪽 모서리가 layout viewport의 왼쪽 모서리에서 얼마나 떨어져 있는지 반환합니다.

offsetTop 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 상단 모서리가 layout viewport의 상단 모서리에서 얼마나 떨어져 있는지 반환합니다.

pageLeft 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 왼쪽 모서리가 initial containing block의 왼쪽 모서리에서 얼마나 떨어져 있는지 반환합니다(해당 layout viewport문서 기준).

pageTop 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 상단 모서리가 initial containing block의 상단 모서리에서 얼마나 떨어져 있는지 반환합니다(해당 layout viewport문서 기준).

width 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 너비를 반환합니다. 단, 시각적 뷰포트에 고정된 세로 클래식 스크롤바의 너비는 제외합니다.

참고: 이 값은 CSS 픽셀로 반환되므로, 페이지 줌이나 스케일 팩터가 증가하면 값의 크기가 줄어듭니다.

참고: 시각적 뷰포트에 고정된 스크롤바란, 줌/이동해도 크기나 위치가 변하지 않는 스크롤바를 의미합니다. 이 값이 CSS 픽셀 단위이므로, 스크롤바 너비를 뺄 때 UA는 CSS 픽셀 단위의 실제 크기를 반영해야 합니다. 즉, 줌 인 시 제외되는 양은 줄어들고, 줌 아웃 시 늘어납니다.

height 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환합니다.

  2. 그 외에는, visual viewport의 높이를 반환합니다. 단, 시각적 뷰포트에 고정된 가로 클래식 스크롤바의 높이는 제외합니다.

scale 속성은 다음 단계를 실행해야 합니다:

  1. visual viewport연결된 문서완전히 활성 상태가 아니라면, 0을 반환하고 단계를 중단합니다.

  2. 출력 디바이스가 없으면 1을 반환하고 단계를 중단합니다.

  3. 그 외에는, visual viewport스케일 팩터를 반환합니다.

onresize이벤트 핸들러 IDL 속성으로, resize 이벤트에 사용됩니다.

onscroll이벤트 핸들러 IDL 속성으로, scroll 이벤트에 사용됩니다.

onscrollend이벤트 핸들러 IDL 속성으로, scrollend 이벤트에 사용됩니다.

13. 이벤트

13.1. 뷰포트 크기 조정

이 섹션은 HTML에서 정의된 이벤트 루프와 통합됩니다. [HTML]

Document doc에 대해 resize 단계 실행(run the resize steps)을 요청받으면, 다음 단계를 수행합니다:

  1. doc뷰포트의 너비나 높이가 변경된 경우 (예: 사용자가 브라우저 창 크기를 조정하거나, 페이지 줌을 변경하거나, iframe 요소의 크기가 변경된 경우) 이전 단계 실행 이후로 변경되었다면, 이벤트를 발생(fire an event)시킵니다. 이름은 resize이고, doc과 연결된 Window 객체에 발생시킵니다.

  2. doc과 연결된 VisualViewportscale, width, height 속성이 이전 단계 실행 이후로 변경되었다면, 이벤트를 발생(fire an event)시킵니다. 이름은 resize이고, VisualViewport 객체에 발생시킵니다.

테스트

13.2. 스크롤링

이 섹션은 HTML에서 정의된 이벤트 루프와 통합됩니다. [HTML]

Document 객체는 pending scroll event targets라는 연관 리스트를 가집니다. 초기에는 비어 있습니다.

Document 객체는 pending scrollend event targets라는 연관 리스트를 가집니다. 초기에는 비어 있습니다.

뷰포트가 스크롤 될 때(사용자 상호작용 또는 API에 의해), UA는 다음 단계를 실행해야 합니다:

  1. doc뷰포트의 연관 Document로 설정합니다.

  2. docsnap container라면, doc에 대해 update scrollsnapchanging targets 단계를 실행합니다. block 축의 doceventual snap target을 newBlockTarget으로, inline 축의 eventual snap target을 newInlineTarget으로 사용합니다.

  3. doc가 이미 docpending scroll event targets에 있으면, 단계를 중단합니다.

  4. docdocpending scroll event targets에 추가합니다.

요소가 스크롤 될 때(사용자 상호작용 또는 API에 의해), UA는 다음 단계를 실행해야 합니다:

  1. doc를 요소의 노드 문서로 설정합니다.

  2. 요소가 snap container라면, 그 요소에 대해 update scrollsnapchanging targets 단계를 실행합니다. block 축의 eventual snap target을 newBlockTarget으로, inline 축의 eventual snap target을 newInlineTarget으로 사용합니다.

  3. 요소가 이미 docpending scroll event targets에 있으면, 단계를 중단합니다.

  4. 요소를 docpending scroll event targets에 추가합니다.

visual viewport가 스크롤 될 때(사용자 상호작용 또는 API에 의해), UA는 다음 단계를 실행해야 합니다:

  1. vv를 스크롤된 VisualViewport 객체로 설정합니다.

  2. docvv연관 문서로 설정합니다.

  3. vv가 이미 docpending scroll event targets에 있으면, 단계를 중단합니다.

  4. vvdocpending scroll event targets에 추가합니다.

Document doc에 대해 run the scroll steps를 요청받으면, 다음 단계를 실행합니다:

  1. doc에 대해 dispatch pending scrollsnapchanging events 단계를 실행합니다.

  2. docpending scroll event targets의 각 target에 대해, 추가된 순서대로 다음 하위 단계를 실행합니다:

    1. targetDocument이면, scroll이라는 이름의 이벤트를 target에서 버블링으로 발생시킵니다.

    2. 그 외의 경우, scroll 이벤트를 target에서 발생시킵니다.

  3. docpending scroll event targets를 비웁니다.

  4. doc에 대해 dispatch pending scrollsnapchange events 단계를 실행합니다.

스크롤이 완료될 때마다, UA는 다음 단계를 실행해야 합니다:

scrollend 이벤트는 어떤 순서로 dispatch 되는가? 스크롤 시작 순서인가, 완료 순서인가?

  1. 스크롤된 각 스크롤 박스 box에 대해:

    1. box뷰포트에 속하는 경우, doc뷰포트의 연관 Document로, target뷰포트로 설정합니다. boxVisualViewport에 속하면, docVisualViewport연관 문서로, targetVisualViewport로 설정합니다. 그 외의 경우, box가 요소에 속하며 doc를 요소의 노드 문서로, target을 해당 요소로 설정합니다.

    2. boxsnap container snapcontainer에 속하면, snapcontainer에 대해 update scrollsnapchange targets 단계를 실행합니다.

    3. target이 이미 docpending scrollend event targets에 있으면, 단계를 중단합니다.

    4. targetdocpending scrollend event targets에 추가합니다.

  2. doc에 대해 dispatch pending scrollsnapchange targets 단계를 실행합니다.

  3. docpending scrollend event targetstarget에 대해, 추가된 순서대로 다음 하위 단계를 실행합니다:

    1. targetDocument이면, scrollend라는 이름의 이벤트를 target에서 버블링으로 발생시킵니다.

    2. 그 외의 경우, scrollend 이벤트를 target에서 발생시킵니다.

  4. docpending scrollend event targets를 비웁니다.

13.3. 이벤트 요약

이 섹션은 규범적이지 않습니다.

이벤트 인터페이스 관심 대상 설명
resize Event Window, VisualViewport Window 에서 뷰포트가 크기 조정될 때 발생합니다. VisualViewport 에서는 비주얼 뷰포트가 크기 조정되거나 레이아웃 뷰포트가 스케일될 때 발생합니다.
scroll Event VisualViewport, Document, 요소들 VisualViewport, Document 또는 요소에서 각각 VisualViewport, 뷰포트, 또는 요소가 스크롤될 때 발생합니다.
scrollend Event Document, 요소들, VisualViewport VisualViewport, Document, 또는 요소에서 스크롤이 완료되었을 때: VisualViewport, 뷰포트, 또는 요소가 스크롤되고, 스크롤 시퀀스가 끝나며 모든 스크롤 오프셋 변경이 적용되었을 때 발생합니다.

14. 레이아웃 이후 상태 스냅샷

일부 CSS 기능은 스크롤 위치 등 레이아웃 이후 상태를 다음 스타일 및 레이아웃 업데이트의 입력으로 사용합니다.

Document doc에 대해 레이아웃 이후 상태 스냅샷 단계를 실행(run snapshot post-layout state steps)을 요청받으면, 다음 단계를 실행합니다:

  1. 레이아웃 이후 상태를 스냅샷해야 하는 각 CSS 기능에 대해, doc의 관련 상태를 스냅샷합니다.

스냅샷되는 상태는 다른 명세에서 정의됩니다. 이러한 단계는 doc 또는 다른 Document를 무효화하여 다른 레이아웃 이후 스냅샷 단계에서 해당 스냅샷이 수행되었음을 관찰할 수 있게 하면 안 됩니다. 즉, 이러한 스냅샷의 실행 순서는 중요하지 않습니다.

15. 프라이버시 고려사항

Screen 인터페이스는 사용자의 디스플레이 구성 정보를 노출하며, 이는 지문 채취 알고리즘의 입력으로 사용될 수 있습니다. 사용자 에이전트는 사용자의 프라이버시를 보호하기 위해 화면 크기 또는 구성 정보를 숨기거나 양자화할 수 있습니다.

MouseEvent 는 이벤트의 화면 상대 좌표 정보를 포함합니다. 사용자 에이전트는 사용자의 프라이버시를 보호하기 위해 이러한 속성 값을 실제 위치를 흐리게 할 수 있습니다.

16. 보안 고려사항

이 명세에 대해 보고된 새로운 보안 고려사항은 없습니다.

17. 변경 사항

이 섹션은 이 명세의 여러 버전 간 일부 변경 사항을 문서화합니다. 이 섹션은 완전하지 않습니다. 버그 수정 및 편집 변경은 일반적으로 나열되지 않습니다.

2016년 3월 17일 워킹 드래프트 이후의 변경 사항

2013년 12월 17일 워킹 드래프트(17 December 2013 Working Draft) 이후의 변경 사항

2011년 8월 4일 워킹 드래프트(04 August 2011 Working Draft) 이후의 변경 사항

2009년 8월 4일 워킹 드래프트(04 August 2009 Working Draft) 이후의 변경 사항

2008년 2월 22일 워킹 드래프트(22 February 2008 Working Draft) 이후의 변경 사항

18. 감사의 글

편집자들은 다음 분들께 이 문서에 대한 기여에 대해 감사를 표합니다: Alan Stearns, Alexey Feldgendler, Antonio Gomes, Björn Höhrmann, Boris Zbarsky, Chris Rebert, Corey Farwell, Dan Bates, David Vest, Elliott Sprehn, Garrett Smith, Henrik Andersson, Hallvord R. M. Steen, Kang-Hao Lu, Koji Ishii, Leif Arne Storset, Luiz Agostini, Maciej Stachowiak, Michael Dyck, Mike Wilson, Morten Stenshorne, Olli Pettay, Pavel Curtis, Peter-Paul Koch, Rachel Kmetz, Rick Byers, Robert O’Callahan, Sam Weinig, Scott Johnson, Sebastian Zartner, Stewart Brodie, Sylvain Galineau, Tab Atkins, Tarquin Wilton-Jones, Thomas Moore, Thomas Shinnick, 그리고 Xiaomei Ji 이 문서에 기여해주신 모든 분들께 감사합니다.

이 초안에 명시된 많은 기능을 최초로 구현하고, Windows Internet Explorer 브라우저를 통해 널리 배포한 Microsoft 직원들에게 특별히 감사드립니다.

적합성

문서 규칙

준수 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 이 문서의 규범적 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”이라는 주요 단어는 RFC 2119에서 설명한 대로 해석되어야 합니다. 하지만 가독성을 위해 이 명세에서는 이러한 단어들이 모두 대문자로 표시되지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적임을 표시한 섹션, 예제, 참고사항을 제외하면 모두 규범적입니다. [RFC2119]

이 명세의 예제는 “예를 들어”라는 단어로 시작하거나, 아래와 같이 class="example"로 규범 텍스트와 구분됩니다:

이것은 정보성 예제의 한 예입니다.

정보성 참고사항은 “참고”라는 단어로 시작하며, 아래와 같이 class="note"로 규범 텍스트와 구분됩니다:

참고, 이것은 정보성 참고입니다.

권고(advisement)는 특별한 주의를 유도하도록 스타일링된 규범 섹션이며, 다른 규범 텍스트와는 <strong class="advisement">로 구분됩니다. 예: UA는 접근 가능한 대안을 반드시 제공해야 합니다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같이 “테스트” 블록에 문서화될 수 있습니다. 이러한 블록은 모두 비규범적입니다.


적합성 클래스

이 명세에 대한 적합성은 세 가지 준수 클래스에 대해 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
UA는 스타일 시트의 의미를 해석하고, 이를 사용하는 문서를 렌더링합니다.
작성 도구
UA는 스타일 시트를 작성합니다.

스타일 시트가 이 명세를 준수하려면, 이 모듈에서 정의된 구문을 사용하는 모든 선언이 일반 CSS 문법 및 각 기능별 문법에 따라 올바른 상태여야 합니다.

렌더러가 이 명세를 준수하려면, 적절한 명세에 따라 스타일 시트를 해석할 뿐만 아니라, 이 명세에서 정의한 모든 기능을 올바르게 파싱하고 문서를 이에 맞게 렌더링해야 합니다. 단, 디바이스의 한계로 인해 UA가 문서를 올바르게 렌더링하지 못하더라도 준수하지 않는 것으로 간주되지 않습니다. (예: UA가 흑백 모니터에서 색상을 렌더링할 필요는 없습니다.)

작성 도구가 이 명세를 준수하려면, 이 모듈의 일반 CSS 문법 및 각 기능별 문법에 따라 구문적으로 올바른 스타일 시트를 작성하고, 이 모듈에서 설명된 모든 스타일 시트 준수 요구사항을 충족해야 합니다.

부분 구현

작성자가 미래 호환 구문 분석 규칙을 활용하여 폴백 값을 지정할 수 있도록, CSS 렌더러는 반드시 지원 수준이 없는 at-rule, 속성, 속성값, 키워드 및 기타 구문 구조를 무효로 간주하고 (적절하게 무시)야 합니다. 특히, UA는 지원하지 않는 구성 요소 값만 선택적으로 무시하고 지원되는 값만 적용해서는 안 됩니다: 다중값 속성 선언에서 어떤 값이든 무효(지원되지 않는 값)로 간주되면, CSS는 전체 선언을 무시하도록 요구합니다.

불안정 및 독점 기능의 구현

향후 안정된 CSS 기능과의 충돌을 피하기 위해, CSSWG는 최선의 관행을 따라 불안정 기능 및 독점 확장을 구현할 것을 권장합니다.

비실험적 구현

명세가 후보 권고(CR) 단계에 도달하면, 비실험적 구현이 가능해지며, 구현자는 명세에 따라 올바르게 구현됨을 입증할 수 있는 모든 CR 레벨 기능에 대해 접두어 없는 구현을 배포해야 합니다.

CSS의 상호 운용성을 구축 및 유지하기 위해, CSS 워킹 그룹은 비실험적 CSS 렌더러가 접두어 없는 CSS 기능을 출시하기 전에 W3C에 구현 보고서(필요시 해당 보고서에 사용된 테스트케이스도 함께) 제출할 것을 요청합니다. W3C에 제출된 테스트케이스는 CSS 워킹 그룹의 검토 및 수정 대상이 됩니다.

테스트케이스 및 구현 보고서 제출에 관한 추가 정보는 CSS 워킹 그룹 웹사이트 https://www.w3.org/Style/CSS/Test/에서 확인할 수 있습니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 하시기 바랍니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고 문헌

규범적 참고 문헌

[CSS-ALIGN-3]
Elika Etemad; Tab Atkins Jr.. CSS Box Alignment Module Level 3. 2025년 3월 11일. WD. URL: https://www.w3.org/TR/css-align-3/
[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2024년 3월 11일. CRD. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BORDERS-4]
Elika Etemad; et al. CSS Borders and Box Decorations Module Level 4. 2025년 7월 22일. FPWD. URL: https://www.w3.org/TR/css-borders-4/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2024년 8월 4일. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-BREAK-4]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 4. 2018년 12월 18일. FPWD. URL: https://www.w3.org/TR/css-break-4/
[CSS-COLOR-4]
Chris Lilley; Tab Atkins Jr.; Lea Verou. CSS Color Module Level 4. 2025년 4월 24일. CRD. URL: https://www.w3.org/TR/css-color-4/
[CSS-CONTAIN-2]
Tab Atkins Jr.; Florian Rivoal; Vladimir Levin. CSS Containment Module Level 2. 2022년 9월 17일. WD. URL: https://www.w3.org/TR/css-contain-2/
[CSS-DEVICE-ADAPT]
Florian Rivoal; Emilio Cobos Álvarez. CSS Viewport Module Level 1. 2024년 1월 25일. FPWD. URL: https://www.w3.org/TR/css-viewport-1/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. 2024년 12월 19일. FPWD. URL: https://www.w3.org/TR/css-display-4/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2023년 3월 29일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 2025년 3월 11일. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2025년 6월 27일. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. 2014년 4월 3일. FPWD. URL: https://www.w3.org/TR/css-scoping-1/
[CSS-SCROLL-SNAP-1]
Matt Rakow; et al. CSS Scroll Snap Module Level 1. 2021년 3월 11일. CR. URL: https://www.w3.org/TR/css-scroll-snap-1/
[CSS-SCROLL-SNAP-2]
Elika Etemad; Tab Atkins Jr.; Adam Argyle. CSS Scroll Snap Module Level 2. 2024년 7월 23일. FPWD. URL: https://www.w3.org/TR/css-scroll-snap-2/
[CSS-TEXT-3]
Elika Etemad; Koji Ishii; Florian Rivoal. CSS Text Module Level 3. 2024년 9월 30일. CRD. URL: https://www.w3.org/TR/css-text-3/
[CSS-TEXT-4]
Elika Etemad; et al. CSS Text Module Level 4. 2024년 5월 29일. WD. URL: https://www.w3.org/TR/css-text-4/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS Transforms Module Level 1. 2019년 2월 14일. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-VALUES]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2024년 3월 22일. CRD. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS2/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016년 3월 17일. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[GEOMETRY-1]
Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 2018년 12월 4일. CR. URL: https://www.w3.org/TR/geometry-1/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MEDIAQUERIES-5]
Dean Jackson; et al. Media Queries Level 5. 2021년 12월 18일. WD. URL: https://www.w3.org/TR/mediaqueries-5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 2022년 11월 11일. WD. URL: https://www.w3.org/TR/selectors-4/
[SVG11]
Erik Dahlström; et al. Scalable Vector Graphics (SVG) 1.1 (Second Edition). 2011년 8월 16일. REC. URL: https://www.w3.org/TR/SVG11/
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[UIEVENTS]
Gary Kacmarcik; Travis Leithead. UI Events. 2024년 9월 7일. WD. URL: https://www.w3.org/TR/uievents/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

비규범적 참고 문헌

[CSS-UI-4]
Florian Rivoal. CSS Basic User Interface Module Level 4. 2021년 3월 16일. WD. URL: https://www.w3.org/TR/css-ui-4/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019년 12월 10일. REC. URL: https://www.w3.org/TR/css-writing-modes-3/

IDL 색인

enum ScrollBehavior { "auto", "instant", "smooth" };

dictionary ScrollOptions {
    ScrollBehavior behavior = "auto";
};
dictionary ScrollToOptions : ScrollOptions {
    unrestricted double left;
    unrestricted double top;
};

partial interface Window {
    [NewObject] MediaQueryList matchMedia(CSSOMString query);
    [SameObject, Replaceable] readonly attribute Screen screen;
    [SameObject, Replaceable] readonly attribute VisualViewport? visualViewport;

    // browsing context
    undefined moveTo(long x, long y);
    undefined moveBy(long x, long y);
    undefined resizeTo(long width, long height);
    undefined resizeBy(long x, long y);

    // viewport
    [Replaceable] readonly attribute long innerWidth;
    [Replaceable] readonly attribute long innerHeight;

    // viewport scrolling
    [Replaceable] readonly attribute double scrollX;
    [Replaceable] readonly attribute double pageXOffset;
    [Replaceable] readonly attribute double scrollY;
    [Replaceable] readonly attribute double pageYOffset;
    undefined scroll(optional ScrollToOptions options = {});
    undefined scroll(unrestricted double x, unrestricted double y);
    undefined scrollTo(optional ScrollToOptions options = {});
    undefined scrollTo(unrestricted double x, unrestricted double y);
    undefined scrollBy(optional ScrollToOptions options = {});
    undefined scrollBy(unrestricted double x, unrestricted double y);

    // client
    [Replaceable] readonly attribute long screenX;
    [Replaceable] readonly attribute long screenLeft;
    [Replaceable] readonly attribute long screenY;
    [Replaceable] readonly attribute long screenTop;
    [Replaceable] readonly attribute long outerWidth;
    [Replaceable] readonly attribute long outerHeight;
    [Replaceable] readonly attribute double devicePixelRatio;
};

[Exposed=Window]
interface MediaQueryList : EventTarget {
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
  undefined addListener(EventListener? callback);
  undefined removeListener(EventListener? callback);
           attribute EventHandler onchange;
};

[Exposed=Window]
interface MediaQueryListEvent : Event {
  constructor(CSSOMString type, optional MediaQueryListEventInit eventInitDict = {});
  readonly attribute CSSOMString media;
  readonly attribute boolean matches;
};

dictionary MediaQueryListEventInit : EventInit {
  CSSOMString media = "";
  boolean matches = false;
};

[Exposed=Window]
interface Screen {
  readonly attribute long availWidth;
  readonly attribute long availHeight;
  readonly attribute long width;
  readonly attribute long height;
  readonly attribute unsigned long colorDepth;
  readonly attribute unsigned long pixelDepth;
};

partial interface Document {
  Element? elementFromPoint(double x, double y);
  sequence<Element> elementsFromPoint(double x, double y);
  CaretPosition? caretPositionFromPoint(double x, double y, optional CaretPositionFromPointOptions options = {});
  readonly attribute Element? scrollingElement;
};

dictionary CaretPositionFromPointOptions {
  sequence<ShadowRoot> shadowRoots = [];
};

[Exposed=Window]
interface CaretPosition {
  readonly attribute Node offsetNode;
  readonly attribute unsigned long offset;
  [NewObject] DOMRect? getClientRect();
};

enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
dictionary ScrollIntoViewOptions : ScrollOptions {
  ScrollLogicalPosition block = "start";
  ScrollLogicalPosition inline = "nearest";
  ScrollIntoViewContainer container = "all";
};

enum ScrollIntoViewContainer { "all", "nearest" };

dictionary CheckVisibilityOptions {
    boolean checkOpacity = false;
    boolean checkVisibilityCSS = false;
    boolean contentVisibilityAuto = false;
    boolean opacityProperty = false;
    boolean visibilityProperty = false;
};

partial interface Element {
  DOMRectList getClientRects();
  [NewObject] DOMRect getBoundingClientRect();

  boolean checkVisibility(optional CheckVisibilityOptions options = {});

  undefined scrollIntoView(optional (boolean or ScrollIntoViewOptions) arg = {});
  undefined scroll(optional ScrollToOptions options = {});
  undefined scroll(unrestricted double x, unrestricted double y);
  undefined scrollTo(optional ScrollToOptions options = {});
  undefined scrollTo(unrestricted double x, unrestricted double y);
  undefined scrollBy(optional ScrollToOptions options = {});
  undefined scrollBy(unrestricted double x, unrestricted double y);
  attribute unrestricted double scrollTop;
  attribute unrestricted double scrollLeft;
  readonly attribute long scrollWidth;
  readonly attribute long scrollHeight;
  readonly attribute long clientTop;
  readonly attribute long clientLeft;
  readonly attribute long clientWidth;
  readonly attribute long clientHeight;
  readonly attribute double currentCSSZoom;
};

partial interface HTMLElement {
  readonly attribute Element? scrollParent;
  readonly attribute Element? offsetParent;
  readonly attribute long offsetTop;
  readonly attribute long offsetLeft;
  readonly attribute long offsetWidth;
  readonly attribute long offsetHeight;
};

partial interface HTMLImageElement {
  readonly attribute long x;
  readonly attribute long y;
};

partial interface Range {
  DOMRectList getClientRects();
  [NewObject] DOMRect getBoundingClientRect();
};

partial interface MouseEvent {
  readonly attribute double screenX;
  readonly attribute double screenY;
  readonly attribute double pageX;
  readonly attribute double pageY;
  readonly attribute double clientX;
  readonly attribute double clientY;
  readonly attribute double x;
  readonly attribute double y;
  readonly attribute double offsetX;
  readonly attribute double offsetY;
};

partial dictionary MouseEventInit {
  double screenX = 0.0;
  double screenY = 0.0;
  double clientX = 0.0;
  double clientY = 0.0;
};

enum CSSBoxType { "margin", "border", "padding", "content" };
dictionary BoxQuadOptions {
  CSSBoxType box = "border";
  GeometryNode relativeTo; // XXX default document (i.e. viewport)
};

dictionary ConvertCoordinateOptions {
  CSSBoxType fromBox = "border";
  CSSBoxType toBox = "border";
};

interface mixin GeometryUtils {
  sequence<DOMQuad> getBoxQuads(optional BoxQuadOptions options = {});
  DOMQuad convertQuadFromNode(DOMQuadInit quad, GeometryNode from, optional ConvertCoordinateOptions options = {});
  DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options = {});
  DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options = {}); // XXX z,w turns into 0
};

Text includes GeometryUtils; // like Range
Element includes GeometryUtils;
CSSPseudoElement includes GeometryUtils;
Document includes GeometryUtils;

typedef (Text or Element or CSSPseudoElement or Document) GeometryNode;

[Exposed=Window]
interface VisualViewport : EventTarget {
  readonly attribute double offsetLeft;
  readonly attribute double offsetTop;

  readonly attribute double pageLeft;
  readonly attribute double pageTop;

  readonly attribute double width;
  readonly attribute double height;

  readonly attribute double scale;

  attribute EventHandler onresize;
  attribute EventHandler onscroll;
  attribute EventHandler onscrollend;
};

이슈 색인

사용자 에이전트마다 (조정된) 뷰포트 스크롤 수행을 사용하는지, 스크롤 박스 스크롤 수행을 레이아웃 뷰포트의 스크롤 박스에서 사용하는지에 대해 합의하지 않습니다.
오브젝트 IDL 조각이 일부 멤버를 재정의합니다. 어떻게 해결할 수 있을까요?
DOM 순서

p1 = RTL에서도 좌상단(top left)

scale이 0이면 0으로 나누기이므로, 0x0 반환

크로스 프레임은 허용되지 않음, WrongDocumentError를 던져야 하나?

포인트는 평면화됨(3d 변형), z=0. getClientRect와 유사

인라인에서 블록 테스트

의사 요소 before/after는 요소의 자식으로 간주

뷰포트 박스는 모두 동일

...
...
...
scrollend 이벤트는 어떤 순서로 dispatch 되는가? 스크롤 시작 순서인가, 완료 순서인가?
CanIUse

Support:Android Browser3+Baidu Browser13.52+Blackberry Browser10+Chrome9+Chrome for Android139+Edge12+Firefox6+Firefox for Android142+IE10+IE Mobile10+KaiOS Browser2.5+Opera12.1+Opera MiniAllOpera Mobile12.1+QQ Browser14.9+Safari5.1+Safari on iOS5.0+Samsung Internet4+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser2.1+Baidu Browser13.52+Blackberry Browser7+Chrome4+Chrome for Android139+Edge12+Firefox18+Firefox for Android142+IE11+IE Mobile11+KaiOS Browser2.5+Opera11.6+Opera MiniAllOpera Mobile12+QQ Browser14.9+Safari3.1+Safari on iOS3.2+Samsung Internet4+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser2.3+Baidu Browser13.52+Blackberry Browser7+Chrome15+Chrome for Android139+Edge12+Firefox3+Firefox for Android142+IE6+IE Mobile10+KaiOS Browser2.5+Opera11+Opera MiniAllOpera Mobile12+QQ Browser14.9+Safari5+Safari on iOS4.0+Samsung Internet4+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser139+Baidu Browser13.52+Blackberry BrowserNoneChrome44+Chrome for Android139+Edge14+Firefox48+Firefox for Android142+IENoneIE MobileNoneKaiOS Browser2.5+Opera31+Opera MiniNoneOpera Mobile80+QQ Browser14.9+Safari9+Safari on iOS9.0+Samsung Internet4+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser139+Baidu Browser13.52+Blackberry BrowserNoneChrome61+Chrome for Android139+Edge79+Firefox36+Firefox for Android142+IENoneIE MobileNoneKaiOS Browser2.5+Opera48+Opera MiniNoneOpera Mobile80+QQ Browser14.9+Safari14+Safari on iOS14.5+Samsung Internet8.2+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser2.3+Baidu Browser13.52+Blackberry Browser7+Chrome4+Chrome for Android139+Edge12+Firefox12+Firefox for Android142+IE9+IE Mobile10+KaiOS Browser2.5+Opera10.6+Opera MiniAllOpera Mobile11+QQ Browser14.9+Safari4+Safari on iOS4.0+Samsung Internet4+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11

CanIUse

Support:Android Browser139+Baidu Browser13.52+Blackberry Browser (limited)7+Chrome61+Chrome for Android139+Edge79+Firefox36+Firefox for Android142+IE (limited)8+IE Mobile (limited)10+KaiOS Browser2.5+Opera48+Opera MiniNoneOpera Mobile80+QQ Browser14.9+Safari16.0+Safari on iOS16.0+Samsung Internet8.2+UC Browser for Android15.5+

Source: caniuse.com as of 2025-09-11