웹페이지의 일반적인 패턴은 새 전체 HTML 문서를 로드하지 않고 JavaScript를 사용하여 페이지의 콘텐츠를 동적으로 대체하는 것입니다. 이를 단일 페이지 애플리케이션(SPA)이라고 합니다. 뷰 전환을 사용하면 SPA의 페이지 간에 연속성이나 컨텍스트를 표시할 수 있습니다.
전체 페이지 전환
사용자가 SPA에서 새 뷰로 이동하면 프레임워크에서 DOM을 새 콘텐츠로 바꿉니다. 이렇게 하면 콘텐츠가 바로 표시되지만 현재 콘텐츠와 새 콘텐츠 간에 전환을 제공하려면 어떻게 해야 할까요?
전환은 이전 뷰와 새 뷰를 동시에 표시하는 경우가 많습니다(예: 이전 뷰를 페이드 아웃하는 동안 새 뷰를 페이드 인). 기존 콘텐츠가 대체되므로 뷰 전환 전에는 이 문제가 있었습니다.
뷰 전환을 사용하려면 DOM 변경 로직을 콜백으로 래핑해야 합니다. 이 예에서는 MyRouter
라는 웹 구성요소에서 제공하는 기본 라우터 구현이 있습니다. 뷰 전환을 사용 설정하는 방법은 사용 중인 라우터와 프레임워크에 따라 다릅니다.
document.startViewTransition(() => updateTheDOMSomehow());
이렇게 하면 이전 뷰가 페이드 아웃되는 동안 새 뷰가 페이드 인되는 기본 전환이 사용 설정됩니다.
어떤 상황인가요? document.startViewTransition()
를 호출하면 브라우저에서 이전 뷰의 스냅샷을 찍습니다. 그런 다음 전달한 콜백 함수를 호출하여 DOM을 새 뷰로 업데이트합니다 (아직 표시하지는 않음). 콜백 함수가 완료되면 브라우저에서 새 콘텐츠로의 전환을 시작합니다.
// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
updateTheDOMSomehow();
return;
} else {
// With a View Transition:
document.startViewTransition(() => updateTheDOMSomehow());
}
전환 맞춤설정
이전 예에서 본 것처럼 기본 뷰 전환은 새 뷰를 페이드 인하는 동시에 이전 뷰를 페이드 아웃합니다. 뷰 전환으로 생성된 가상 요소를 스타일링하여 사이트의 스타일에 더 잘 맞게 전환을 맞춤설정할 수 있습니다.
::view-transition-old()
로 나가는 전환을 지정하고 ::view-transition-new()
로 들어오는 전환을 지정할 수 있습니다. ::view-transition-group()
을 사용하여 두 값 모두 지정할 수도 있습니다.
이 예에서는 이전 뷰가 slide-out-to-left
전환을 사용하여 전환되고 새 뷰가 slide-in-from-right
전환을 사용하여 전환됩니다. 둘 다 200밀리초의 지속 시간을 갖습니다.
::view-transition-group(root){
animation-duration: 200ms;
}
::view-transition-old(root) {
animation-name: slide-out-to-left;
}
::view-transition-new(root) {
animation-name: slide-in-from-right;
}
컨텍스트에 따라 다른 전환
사용자가 무엇을 하고 있는지에 따라 전환을 다르게 할 수 있습니다. 예를 들어 홈페이지의 링크를 클릭하면 오른쪽에서 새 뷰가 슬라이드되는 경우 홈페이지로 돌아가는 링크를 클릭하면 왼쪽에서 홈 뷰가 슬라이드될 것으로 예상됩니다.
:active-view-transition-type()
가상 클래스를 사용하여 다양한 애니메이션을 지정할 수 있습니다.
html:active-view-transition-type(forwards) {
&::view-transition-old(root) {
animation-name: slide-out-to-left;
}
&::view-transition-new(root) {
animation-name: slide-in-from-right;
}
}
그런 다음 document.startViewTransition()
를 호출할 때 사용할 뷰 전환 유형을 선택할 수 있습니다.
const direction = next === 'home' ? 'backwards' : 'forwards';
document.startViewTransition({
update: updateTheDOMSomehow,
types: [direction],
});
특정 요소 전환
지금까지는 전체 뷰를 전환하기 위해 루트 요소에만 전환을 적용했습니다. 하지만 뷰 전환을 사용하여 페이지의 특정 부분에 애니메이션을 적용할 수도 있습니다.
예를 들어 이전 뷰의 콘텐츠가 새 뷰의 콘텐츠와 일치할 수 있습니다. 콘텐츠 제목 또는 이미지일 수 있습니다. 이전 보기에서는 썸네일 이미지, 새 보기에서는 동영상일 수도 있습니다.
먼저 view-transition-name
속성을 사용하여 전환할 요소를 지정해야 합니다. 뷰 전환이 작동하려면 각 view-transition-name
에 document.startViewTransition()
를 호출하기 전의 요소가 정확히 하나여야 하고 document.startViewTransition()
의 콜백이 완료된 후의 요소도 정확히 하나여야 합니다.
이 예에는 앨범 아트, 제목, 아티스트를 표시하는 음악 플레이어가 있습니다. 대체 뷰에는 동일한 콘텐츠가 재정렬되어 표시되며 노래 가사가 추가됩니다.
위의 예에서는 전환된 요소가 이전 뷰와 새 뷰에 각각 하나씩 있으며 동일한 선택기를 공유합니다. 전환된 요소는 크기와 위치 사이에서 이동하는 것처럼 보입니다. 전환되지 않은 뷰 부분이 서서히 나타나고 서서히 사라집니다.
더 복잡한 예를 살펴보겠습니다. 예를 들어 블로그의 홈페이지에는 각 게시물의 헤드라인과 이미지가 표시되며, 블로그 게시물의 전체 페이지 보기에도 표시됩니다. 홈페이지에서 특정 게시물로 이동할 때 제목과 이미지가 새 위치로 전환되는 것처럼 표시하여 컨텍스트를 제공할 수 있습니다.
제목에 대해 이를 수행하려면 이전 뷰에서 고유하고, 새 뷰의 제목 요소와 공유되며, 새 뷰에서 고유한 제목 요소에 view-transition-name
가 있어야 합니다. 홈페이지에는 여러 헤드라인과 이미지가 있으며 사용자가 어떤 항목을 클릭할지 알 수 없으므로 이는 어려운 문제입니다.
이 문제를 해결하는 방법에는 두 가지 옵션이 있습니다. 홈페이지의 각 게시물에 고유한 view-transition-name
를 추가한 다음 각 전체 페이지 게시물에서 해당 이름을 일치시킬 수 있습니다. 게시물의 ID를 사용하여 이를 생성할 수 있습니다. 다른 옵션은 일반 view-transition-name
를 사용하는 것입니다. 하지만 사용자가 게시물을 클릭한 후 document.startViewTransition()
를 호출하기 전에만 적용해야 합니다.
전환 설계
뷰 전환은 사용자를 안내하고 추가 브랜드 또는 컨텍스트 힌트를 제공하는 데 사용할 수 있는 도구 모음입니다. 사이트에 적합한 전환을 찾기 위해 여러 기법을 사용할 수 있습니다.
원하는 효과에 따라 요소나 애니메이션을 조정해야 할 수도 있습니다. 이전 예에서는 부드러운 전환을 위해 여러 스타일이 조정되었습니다.
헤드라인에는 width: fit-content
규칙이 있습니다. 이는 텍스트가 줄바꿈되지 않거나 이전 뷰와 새 뷰에서 줄바꿈이 동일한 경우 유용한 스타일입니다. 그렇지 않으면 너비가 다른 요소 간에 전환이 발생하여 전환이 매끄럽지 않을 수 있습니다.
이전 보기와 새 보기에서 이미지의 가로세로 비율도 다릅니다. 이 예에서는 전환이 부드럽게 표시되도록 애니메이션과 object-fit
속성을 수정합니다.
prefers-reduced-motion
존중
사용자가 동작 감소를 요청하는 일반적인 이유는 뷰 전환으로 구현할 수 있는 전체 화면 애니메이션이 전정 기관 운동 장애가 있는 사람에게 불편함을 줄 수 있기 때문입니다. prefers-reduced-motion
미디어 쿼리를 사용하여 애니메이션을 사용 중지할 수 있습니다. 요소가 어떻게 연결되는지 전달하면서도 더 미묘한 대체 애니메이션을 제공할 수도 있습니다.
@media (prefers-reduced-motion) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
이해도 확인
document.startViewTransition()
가 호출되기 전의 뷰를 나타내는 의사 요소의 이름은 무엇인가요?
::view-transition-previous
::view-transition-prior
::view-transition-old
::view-transition-initial
뷰 전환의 기본 애니메이션은 무엇인가요?
페이지의 기본 view-transition-name
는 무엇인가요?
document
shadow-root
root
body