React의 Netflix 스타일 가로 스크롤 행

모든 스트리밍 사이트에서 넘겨보는 포스터 행은 캐러셀이 아니라 메뉴입니다. 아무것도 스냅되지 않고 자동 재생도 없습니다. 위에 화살표를 겹쳐 놓은 채 네이티브 모멘텀 스크롤을 그대로 사용합니다. react-horizontal-scrolling-menu가 제공하는 것이 정확히 이것입니다: 여러분의 카드, 네이티브 스크롤, 그리고 화살표가 언제 숨어야 하는지 아는 항목별 가시성.

드래그하거나 행에 마우스를 올려보세요 — 화살표가 가장자리 위로 서서히 나타나고, 행의 끝에 도달하면 각각 사라집니다.

캐러셀로 풀 문제가 아닌 이유

Netflix 행은 한 번에 하나의 슬라이드만 보여주지 않습니다. 항목은 일부러 가장자리에서 잘려 보이는데, 이 잘린 포스터가 "더 있다"는 것을 알려주는 어포던스입니다. 캐러셀 엔진은 이와 반대로 동작합니다: JavaScript 트랜스폼으로 제스처 레이어를 직접 소유하고, 슬라이드 경계에 스냅하며, 사용자 브라우저가 이미 가지고 있는 모멘텀을 다시 구현합니다. 클릭 가능한 카드 행에서는 이 모든 것이 오버헤드일 뿐입니다.

네이티브 스크롤은 모멘텀, 터치, 트랙패드, 스크롤바를 공짜로 제공합니다. 다만 오버레이 화살표와 어떤 카드가 화면에 보이는지 아는 것, 이 두 가지는 제공하지 않습니다 — 이 라이브러리가 추가하는 것이 바로 이 두 가지로, 항목별 useIsVisible과 가장자리 인식 화살표 상태로 구현됩니다.

효과를 완성하는 세 가지 디테일

확장하기: 지연 로딩 행과 긴 레일

스트리밍 UI는 수백 개의 카드가 담긴 행을 수십 개씩 쌓습니다. 항목이 네이티브 스크롤 컨테이너 안의 평범한 DOM이기 때문에 스크롤 시 아무것도 다시 렌더링되지 않습니다 — 성능 예제는 가상화 없이 300개 항목을 실행합니다. 항목별 가시성은 이미지 지연 로딩도 공짜로 제공합니다: useIsVisible이 카드가 화면에 보인다고 알릴 때까지 플레이스홀더를 렌더링하면 됩니다.

행이 끝에서 순환해야 한다면, 그것이 슬라이드 시맨틱이 정말로 도움이 되는 유일한 지점입니다 — 캐러셀 엔진에 손을 뻗기 전에 무한 루프 레시피에서 ~60줄짜리 유저랜드 버전을 확인하세요.

패턴, 최소 구성

네이티브 스크롤 행 위에 화살표를 겹칩니다 — 위 데모는 이 구조에 스타일링을 더한 것입니다. 드래그와 가장자리 페이드까지 포함한 완전한 드롭인 소스는 아래 shadcn 컴포넌트로 제공됩니다.

MediaRow.tsx
function MediaRow({ children }: { children: React.ReactNode }) {
  return (
    <div className="group relative">
      <ScrollMenu Header={<OverlayArrows />} wrapperClassName="edge-fade">
        {children}
      </ScrollMenu>
    </div>
  );
}

// Rendered as Header, so it lives inside the menu's VisibilityContext
// and can sit absolutely positioned over the row ends.
function OverlayArrows() {
  const api = React.useContext<publicApiType>(VisibilityContext);
  const atStart = api.useLeftArrowVisible();
  const atEnd = api.useRightArrowVisible();
  return (
    <>
      <button
        className="overlay-arrow left-0"
        hidden={atStart}
        onClick={() => api.scrollPrev()}
      >

      </button>
      <button
        className="overlay-arrow right-0"
        hidden={atEnd}
        onClick={() => api.scrollNext()}
      >

      </button>
    </>
  );
}

/* .edge-fade — the Netflix edge, one CSS line:
   mask-image: linear-gradient(to right,
     transparent, black 40px, black calc(100% - 40px), transparent); */

또는 shadcn 컴포넌트로 설치하기

media-row 레지스트리 아이템은 이 패턴 그대로입니다 — 호버 화살표, 그라디언트 가장자리 페이드, 드래그 스크롤 — components/ui/에 Tailwind 스타일 컴포넌트로 설치되어 자유롭게 수정할 수 있습니다:

shadcn
npx shadcn@latest add https://react-horizontal-scrolling-menu.dev/r/media-row.json

관련 예제

예제 전체 21개