자바 스크립트(java script)/개념 조각

크기가 0인 요소도 IntersectionObserver의 대상이 될 수 있나?

lamarcK 2025. 3. 31. 16:44

Q1. loader는 IntersectionObserver의 대상이 되기도 하거든. 그런데 width 를 0으로 해도 작동할까? height도 0이야. 그럼 뭘 기준으로 교차를 확인 하지?

🤔 width: 0, height: 0 요소와 IntersectionObserver

아주 좋은 질문이다. IntersectionObserver는 **관찰 대상 요소의 경계 상자(Bounding Box)**가 루트(Root)의 경계 상자(및 rootMargin으로 조정된 영역)와 **교차(intersect)**하는지를 기반으로 작동한다.


⚙️ IntersectionObserver의 작동 기준: Bounding Box

  • Bounding Box: 요소가 화면에 렌더링될 때 차지하는 사각형 영역을 의미한다. 이 크기는 요소의 width, height 뿐만 아니라 padding, border 에도 영향을 받는다 (box-sizing 속성에 따라 계산 방식이 달라짐). margin은 요소의 위치에는 영향을 주지만, 바운딩 박스 자체의 크기에는 직접적인 영향을 주지 않는다 (교차 판정 시에는 중요하지 않음).
  • 교차 판정: 옵저버는 이 타겟 요소의 바운딩 박스와 루트의 바운딩 박스가 겹치는 영역이 있는지를 확인한다.

❌ 제로(0) 크기 요소의 교차 판정 문제

그런데 width 를 0으로 해도 작동할까? height도 0이야. 그럼 뭘 기준으로 교차를 확인 하지?

 

만약 #loader 요소의 CSS 스타일이 width: 0; 이고 height: 0; 이며, 추가적으로 padding: 0; 이고 border: 0; 이라면, 이 요소의 렌더링된 바운딩 박스는 실제로 면적(area)이 0이 된다.

면적이 0인 요소는 루트의 경계 상자와 물리적으로 겹칠 수 있는 영역이 없다. 따라서, IntersectionObserver는 이 요소가 루트(뷰포트)와 교차한다고 판단하기 매우 어렵거나 불가능하다. 결과적으로 isIntersecting 상태가 true가 되지 않아 콜백 함수가 전혀 호출되지 않을 가능성이 매우 높다.

즉, width와 height가 모두 0이고 다른 크기를 주는 속성(패딩, 보더)도 없다면, IntersectionObserver는 해당 요소를 효과적으로 감지하지 못할 것이다.

(참고: 만약 width: 0; height: 0; 이지만 padding이나 border 값이 있다면, 요소는 실제 크기를 가지게 되므로 옵저버가 감지할 수 있다.)


✅ 해결 방안: 관찰 가능한 loader 만들기

loader 요소가 무한 스크롤의 트리거 역할을 하지만 시각적으로는 보이지 않게 만들고 싶다면, width: 0; height: 0; 대신 다음과 같은 방법을 사용하는 것이 일반적이다.

  1. 최소 높이 부여 (Give Minimum Height) - 권장:
    • #loader 요소에 너비는 100% (이전 질문처럼 한 줄을 차지하게 하려면) 또는 다른 적절한 너비를 주고, 높이는 매우 작게(예: 1px) 설정한다. 이렇게 하면 바운딩 박스가 존재하여 옵저버가 감지할 수 있다.
    • 시각적으로 보이지 않게 하려면 opacity: 0;, visibility: hidden;, 또는 background-color: transparent; 등을 사용한다.
    • 주의: display: none; 을 사용하면 안 된다! display: none; 은 요소를 렌더링 트리에서 완전히 제거하므로 레이아웃에 영향을 주지 않고 크기도 가지지 않게 되어 IntersectionObserver가 감지할 수 없게 된다.
    CSS 예시:
    #loader {
      width: 100%; /* 또는 필요한 너비 */
      height: 1px;  /* 옵저버가 감지할 수 있는 최소 높이 */
      padding: 0;
      border: 0;
      margin: 0; /* 불필요한 여백 제거 */
      /* 시각적으로 숨기기 (선택 사항) */
      opacity: 0;
      visibility: hidden;
      /* 또는 */
      /* background-color: transparent; */
    }
    
  2. padding 또는 border 활용 (Use Padding or Border):
    • width: 0; height: 0; 으로 설정하더라도, padding: 10px; 와 같이 패딩을 주거나 border: 1px solid transparent; 와 같이 투명한 테두리를 주면 요소는 크기를 가지게 되어 옵저버가 감지할 수 있다. 하지만 보통 1번 방법(최소 높이)이 더 명확하다.

💡 요약

  • IntersectionObserver는 요소의 **렌더링된 크기(Bounding Box)**를 기준으로 교차 여부를 판단한다.
  • width, height, padding, border가 모두 0이어서 실제 면적이 0인 요소는 루트와 교차할 수 없으므로 옵저버가 감지하기 매우 어렵거나 불가능하다.
  • loader 요소를 옵저버가 감지하게 하려면, 최소한의 크기(예: height: 1px;)를 가지도록 스타일을 설정해야 한다. 시각적으로 숨겨야 한다면 opacity: 0 이나 visibility: hidden 등을 사용한다 (display: none 사용 금지).