TailwindCss로 도막도막 끊기는 스크롤 화면 구현하기: Full Page Scroll과 Scroll snap

2025. 5. 17. 15:37·개발이야기

웹사이트들을 돌아다니다보면, 내린만큼 화면이 스크롤 되는 것이 아니라 특정구간마다 탁탁 걸리면서 정지하는 스크롤을 이용한 사이트들이 많이 보인다. 이 사이트는 스크롤을 내릴때마다 화면 전체의 배경색이 바뀌면서 극적인 효과를 준다. 눈으로 보면 쉽지만, 말로 설명하자면 어려운 이런 스크롤 방식을 "scroll snap"이라고 부른다.

Scroll Snap

CSS의 scroll-snap-type을 이용해서 구현된다. 스크롤이 멈출 수 있는 지점을 지정하는 것이다. 이 멈춤 지점을 앵커(anchor)라고 부른다. 예를 들어, tailwind 에서는 가로로 이미지를 스크롤하는 예시를 보여준다.

가로로 화면을 스크롤하면, 이미지의 중간 지점에서만 스크롤이 멈춘다. 위의 tailwind 링크를 눌러 해 볼 수 있다.

비슷한 용어로 "Full Page Scroll"이라는 표현이 있다. 이는 scroll snap을 활용해 구현되며, 페페이지 전체가 스크롤할 때마다 한 화면씩 전환되는 형식이다. 글의 초반에 링크한 이 사이트가 그 예시이다. 이러한 Full Page Scroll 형식의 사이트들을 보면, 대개 주소에 #pageN와 같이 #으로 시작하는 식별자가 달려있다. 이것이 바로 앵커이며, 이 앵커 값을 포함한 주소를 브라우저에 전달하면, 특정 화면으로 스크롤된 상태로 바로 진입할 수 있다.

오해할 수 있는 용어로 "smooth scroll"이 있다. Smooth scoll은 scroll snap과 함께 자주 사용되지만, 다른 개념이다. CSS에서는 'scroll-behavior' 를 통해 구현한다. a 태그안에 앵커를 포함한 주소를 심어, 사용자가 링크를 누르면 특정 화면으로 이동시키는 기능을 구현하고자 할 때, 해당 화면으로 곧장 전환되는게 아니라 부드러운 트랜잭션으로 전환시키는 기능이다. 이 사이트를 참고하자.

이제 Full Page Scroll을 구현하는 방법을 살펴보자.

라이브러리 이용하기

Full Page 기능을 쉽게 이용할 수 있게 해주는 라이브러리들이 많이 있다. 나도 이 기능이 들어간 사이트를 이번에 구현해보면서 조사해보았다. 결론부터 말하자면, 이거다! 싶은 라이브러리를 찾지 못하여, 직접 구현했다. 사실 라이브러리를 꼭 써야할 정도로 구현난이도가 높지도 않다고 생각한다. 탐색해본 라이브러리들을 소개한다.

  • fullpage.js
    라이브러리를 사용하고 싶다면, 이 도구가 적절한 선택이 될 수 있다. 특히 lazy-loading처럼 페이지에 동영상 등의 리소스가 많이 포함된 경우에는 유용하게 활용할 수 있다. 다만, 이 라이브러리는 React element에 CSS 속성을 암묵적으로 추가한다는 점에서 아쉬움이 있었다.
    구현 방식상 class="section"이라는 CSS selector를 기준으로 다양한 스타일 속성을 설정하는데, 이로 인해 원하지 않는 영역에 Flex 속성이나 가운데 정렬 같은 스타일이 적용되는 문제가 발생했다. 만약 이러한 스타일을 피하고 싶다면 overrides.css 같은 별도의 파일을 만들어 더 강한 selector로 덮어써야 한다. 이는 나에게 번거로울 뿐 아니라, 어떤 속성이 자동으로 추가되었는지 명확히 알기 어려워 찝찝하게 느껴졌다.
  • @fullpage/react-fullpage
    위 fullpage.js를 react component로 쓰기 좋게 감싼 공식 라이브러리라고 한다. 확실히 react에서 쓰기 좋게 간결한 docs와 문법을 갖고 있어서, 금방 적용할 수 있었다. 그러나 여전히 fullpage.js의 단점을 답습하고 있거니와, 유료라서 무료로 사용하면 사이트에 "Made by @fullpage/react-fullpage"같은 플로팅이 떠다녀서 거슬린다.
  • react-fullpage
    Deprecated되었다. 쓰지말자. 그럼에도 불구하고 이 글에서 소개한 이유는, GPT 한테 full page scroll 구현하는 법을 물어보면 이 라이브러리를 알려준다.

직접 TailwindCSS로 구현하기

코드로 남긴다.

function App() {
  return (
    <div className="min-h-screen w-full">
      <main className="container h-screen w-full overflow-y-scroll snap-y snap-mandatory scroll-smooth mx-auto">
        <Section1 />
        <Section2 />
      </main>
    </div>
  )
}

function Section1() {
  return (
    <section id="section_1" className="h-screen w-full snap-center">
        <div>
        ...
        </div>
    </section>
   );
 }
  • snap-mandatory: 반드시 지정한 지점에서만 스크롤이 멈추게 한다. 약간 유도리 있게 snap-proximity로 설정할수도 있다.
  • scroll-smooth: 글 초반에 설명했듯이, 글 내에서 a 태그 등으로 앵커가 변경되어 보여지는 화면이 달라져야할때, 부드럽게 이동한다.
  • id="section_1": 이렇게 id를 설정하면 /#section_1의 앵커로 이 화면에 접근할 수 있다.

대신 이렇게 하면 문제가 있는것이, 화면 오른쪽에 못생긴 스크롤 바가 생긴다. 이것은 스택오버플로우에서 긁어온 아래의 코드를 index.css 혹은 다른 import하는 css 파일에 추가함으로써 해결한다.

.container {
    -ms-overflow-style: none;  /* Internet Explorer 10+ */
    scrollbar-width: none;  /* Firefox */
}
.container::-webkit-scrollbar { 
    display: none;  /* Safari and Chrome */
}

추가로, 아래와 같은 니즈가 더 있을 수 있다.

  • 지금 보여지고 있는 화면이 무엇인지 알고 싶음.
  • 특정화면이 보여질때 실행되는 훅을 만들고 싶음.
  • 사이트에 진입할때, 모든 화면을 랜더링 해두지 않고, 그 화면이 보여야할때 랜더링 하는 lazy-loading을 구현하고 싶음

이럴 때에는 IntersectionObserver API를 활용하여 구현할 수 있다. 다음에 또 다른 글로 소개해보겠다.

저작자표시 (새창열림)

'개발이야기' 카테고리의 다른 글

OCaml에 대해 실전 속성 압축으로 익혀보기  (0) 2025.06.22
VSCode 환경에서 make로 빌드되는 c파일 gdb로 디버깅하기  (0) 2025.06.16
속터지는 Google Play Console 본인인증하기  (3) 2025.02.06
Cursor AI 사용 후기 - 위기의 내 밥그릇  (0) 2025.01.12
Node.js에서 csv 파일 다루기 및 ios-윈도우 간 한글 깨짐 문제 해결  (1) 2024.01.06
'개발이야기' 카테고리의 다른 글
  • OCaml에 대해 실전 속성 압축으로 익혀보기
  • VSCode 환경에서 make로 빌드되는 c파일 gdb로 디버깅하기
  • 속터지는 Google Play Console 본인인증하기
  • Cursor AI 사용 후기 - 위기의 내 밥그릇
준별
준별
  • 준별
    준별개발
    준별
  • 전체
    오늘
    어제
    • 분류 전체보기 (58)
      • 개발이야기 (25)
        • 토막글 (11)
      • 일상이야기 (6)
      • 개인 공부 (23)
      • 생각과 기록 (2)
  • 블로그 메뉴

    • 홈
    • 방명록
    • Github
    • Linkedin
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    맥북세팅
    데이터베이스
    터미널세팅
    터미널꾸미기
    http pipelining
    persistent connection
    artillery
    데스크셋업
    zsh-autosuggestion
    전산기조직
    http2.0
    맥북
    이산구조
    k9s
    맥북터미널세팅
    http1.1
    nodejs
    바이브코딩
    클램쉘
    powerlevel10k
    필수툴
    Zsh
    실전압축
    nestjs
    http1.0
    http3.0
    맥북초기세팅
    조합형
    zsh세팅
    정보보호개론
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
준별
TailwindCss로 도막도막 끊기는 스크롤 화면 구현하기: Full Page Scroll과 Scroll snap
상단으로

티스토리툴바