본문으로 건너뛰기
0
r/jeffnews HN 약 5분

Apple Cover Flow를 JS 없이 순수 CSS만으로 재현하기

frontend

요약

CSS Scroll Snap과 Scroll-Driven Animations API를 조합하면 JS 한 줄 없이 Apple의 Cover Flow를 재현할 수 있음. GPU 가속, 메인 스레드 밖 실행으로 성능도 뛰어남.

기사 전체 정리

Cover Flow, 이제 순수 CSS만으로 된다

  • Apple이 2006년 iTunes 7에 도입해서 iPod, Finder까지 퍼졌던 그 Cover Flow를 HTML + CSS만으로 재현할 수 있게 됨. JS 한 줄 없이. CSS Scroll Snap + Scroll-Driven Animations API 조합 덕분임

  • 역사적으로 Cover Flow 웹 구현은 고통의 연속이었음. Flash 시절에는 ActionScript로, CSS3 나오고 나서는 jQuery 플러그인이나 직접 requestAnimationFrame 돌리면서 rotateY/translateX 수동 계산. 심지어 WebGL/Canvas까지 동원한 사례도 있었음

핵심 기술: Scroll Snap + View Timeline

  • CSS Scroll Snap: scroll-snap-type: x mandatory로 수평 스크롤 컨테이너에서 아이템이 항상 중앙에 딱 맞게 스냅되게 만듦. JS 없이 기본 캐러셀 인터랙션이 완성됨

  • CSS Scroll-Driven Animations: 시간 기반이 아니라 스크롤 위치 기반으로 애니메이션을 구동하는 새로운 CSS 기능. view() 함수로 각 엘리먼트가 스크롤 뷰포트에서 어디에 있는지 추적 — 진입 0%, 중앙 50%, 퇴장 100%

  • Bramus Van Damme의 순수 CSS 데모가 이 구현의 핵심인데, 구조가 엄청 깔끔함:

    • HTML은 그냥 <ul> 안에 <li><img></li> 나열
    • view-timeline-name: --li-in-and-out-of-view로 각 <li>에 뷰 타임라인 선언
    • z-index 애니메이션: 50% 지점(중앙)에서 z-index: 100으로 올려서 앞으로 튀어나오게
    • 3D 회전 애니메이션: 0%에서 rotateY(-45deg) → 50%에서 rotateY(0) scale(1.5) → 100%에서 rotateY(45deg)

💡

> 3D 트랜스폼을 <li> 대신 내부 <img> 적용하는 게 핵심 트릭임. <li> 자체를 변환하면 바운딩 박스가 바뀌면서 스크롤 너비에 영향을 줘서 화면이 덜덜 떨림. 내부 엘리먼트만 변환하면 레이아웃은 안정적으로 유지됨

성능과 접근성

  • 성능 면에서 엄청난 이점이 있음. Scroll-Driven Animations는 메인 스레드 밖에서 돌아감. transform, opacity만 애니메이션하니까 GPU 가속도 자동으로 먹고, 60fps 이상 나옴. JS로 scroll 이벤트 리스닝하면서 스타일 업데이트하던 시절의 쟁크(jank)와는 차원이 다름

  • 접근성도 챙겨야 할 부분이 있음: 스크롤 컨테이너에 tabindex="0" 추가해서 키보드 탐색 가능하게 하고, aria-roledescription="carousel" 지정, 각 이미지에 alt 텍스트 필수, @media (prefers-reduced-motion)으로 애니메이션 축소 대응

  • 반사(reflection) 효과는 -webkit-box-reflect로 구현 가능하지만 WebKit/Blink 전용이고 Firefox 미지원. 성능에도 영향을 줄 수 있으니 모바일에서는 끄는 게 나음

  • React 버전도 있고 Three.js로 만든 예제도 GitHub에 공개되어 있음. Swiper.js의 Coverflow 모드 같은 유지보수되는 라이브러리도 있지만, 순수 CSS로 이 정도가 된다는 게 2025년 웹 기술의 현주소임

핵심 포인트

  • CSS view timeline으로 각 엘리먼트의 스크롤 위치 기반 3D 애니메이션 구현
  • 내부 img에만 transform 적용하는 트릭으로 레이아웃 안정성 확보
  • 60fps 이상 성능, 접근성(키보드/스크린리더/reduce motion) 고려 필요

인사이트

GSAP이나 jQuery로 하던 걸 CSS 몇 줄로 해결하는 시대. Scroll-Driven Animations는 Cover Flow 너머 패럴랙스, 프로그레스바 등에도 활용 가능.

댓글

댓글

댓글을 불러오는 중...

frontend

Firefox 149에 Split View 기능 추가 — 같은 창에서 탭 두 개를 나란히

Firefox 149부터 Split View가 정식 지원된다. 탭 우클릭으로 두 탭을 나란히 배치할 수 있으며, 캘린더 확인하며 예약하기, 문서 읽으며 노트 정리 같은 멀티탭 작업이 편해진다.

frontend

아니요, Windows 시작 메뉴는 React로 만들어지지 않았음

Windows 시작 메뉴가 React로 만들어졌다는 Windows Central 기사의 오보를 반박하는 글. 실제로는 하단 '추천' 섹션만 React Native for Windows를 사용하며, 이는 네이티브 코드로 컴파일되는 프레임워크임

frontend

내 사이트에 먼저 올리고 SNS는 그냥 배포 채널로 써라 - POSSE 전략

POSSE(Publish on your Own Site, Syndicate Elsewhere)는 콘텐츠를 내 사이트에 먼저 올리고, 트위터/인스타/페북 같은 SNS에는 복사본만 뿌리는 방식임. 데이터 소유권도 챙기고 SNS 팔로워도 놓치지 않는 ㄹㅇ 실용적인 전략. IndieWeb 운동의 핵심 철학이기도 함.

frontend

윈도우 네이티브 앱 개발이 이렇게 개판인 줄 몰랐음 (현직 개발자 회고)

윈도우 개발 추억 있는 개발자가 소소한 유틸리티 앱 하나 만들려다 현실에 박살난 썰. Win32부터 WinUI 3까지 수십 년간 쌓인 레거시와 미완성 API들 때문에 결국 '그냥 Electron 쓰는 게 맞다'는 결론에 도달함. 마이크로소프트가 자기 플랫폼을 방치하는 수준이 ㄹㅇ 심각함.

frontend

JS 번들 뚱뚱해지는 진짜 이유 3가지 - npm 의존성 다이어트 해야 할 때

npm 패키지 트리가 왜 이렇게 무거워졌는지 분석한 글. 레거시 엔진 지원, 원자적 패키지 설계, 오래된 ponyfill 세 가지가 주범임. e18e 커뮤니티가 이 문제를 해결하려고 열심히 삽질 중ㅋㅋ