position: sticky 요소가 stuck일 경우에만 CSS를 적용하는 방법

 

이번 포스팅에서는 position: sticky 인 요소가 stuck 상태인 경우, 즉 브라우저 상에서 원하는 위치에 달라 붙었을 경우에만 해당 요소에 CSS를 적용하는 방법에 대해서 알아보겠습니다.

 

이러한 작업은 주로 웹사이트의 헤더가 스크롤을 내리면 상단에 달라붙어야 하는 경우, 해당 헤더의 스타일을 바꾸는 경우에 필요합니다. 물론 그 밖에 다른 영역들에도 적용이 필요한 경우도 있겠죠. 먼저 해결 방법을 알아보기에 앞서 해결 방법에 사용되는 개념을 간략히 정리해보겠습니다.

 

1. IntersectionObserver란?

Intersection observer는 브라우저 뷰포트와 설정한 요소의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지, 더 쉽게는 사용자 화면에 지금 보이는 요소인지 아닌지를 구별하는 기능을 제공합니다.

 

기존에는 jQuery의 scroll 이벤트를 통해 특정 요소가 화면 안에 있는지를 체크하고는 했는데요. 이 방법은 끊임없이 브라우저를 일하게 하기 때문에 좋은 방법이 아닙니다. 이를 보완할 수 있게 나온 개념이 바로 Intersection observer 입니다. 특정 요소가 뷰포트에 포함되는지 아닌지 그 상태만을 관찰해서 알려주는 역할을 하기 때문에 scroll 이벤트를 이용하는 것보다 훨씬 경제적이고 좋은 방법입니다. 그럼 이제 이 개념을 이용해 sticky 요소에 .stuck 이라는 클래스를 추가하여 문제를 해결하는 방법을 알아보겠습니다.

 

2. 해결 방법

2.1. IntersectionObserver 사용해 .stuck 클래스 추가하기

<style>
    .sticky-el {
        position: sticky;
        top: -1px; /* 중요! */
    }

    /* 고정됐을 때 적용될 CSS */
    .sticky-el.stuck {
        color: red;
    }
</style>

<div class="sticky-el">고정될 요소</div>

<script>
    const el = document.querySelector('.sticky-el')
    const observer = new IntersectionObserver( 
      ([e]) => e.target.classList.toggle('stuck', e.intersectionRatio < 1),
      { threshold: [1] }
    );

    observer.observe(el);
</script>

위 소스는 앞서 언급한 IntersectionObserver를 이용해 sticky 요소가 브라우저를 벗어났는지를 관찰하다가, 벗어나는 순간 .stuck 이라는 클래스를 붙여주는 소스입니다.

 

sticky 요소는 화면을 벗어나는 게 아니라 상단에 달라 붙는 것인데 어떻게 벗어나는 순간을 체크하는 기능으로 이를 가능하게 하는 걸까? 라는 의문이 생길 수 있는데요. 이를 가능하게 해주는 게 바로 .sticky-el 요소에 부여해준 CSS top: -1px 속성입니다. 상단에 고정되는 요소를 0px이 아닌 -1px 지점에서 고정되게 하여 1px 만큼 화면 상에 벗어난 순간 클래스가 붙도록 처리한 것이지요.

 

이번 포스팅에서는 position: sticky 인 요소가 stuck 상태인 경우 그 상태에 대하여 별도 스타일을 지정할 수 있는 방법에 대해 함께 살펴보았습니다.

도움이 되셨길 바랍니다.

 

감사합니다.

 

참고 문서