CSS 및 JavaScript로 사용자 정의 전체 페이지 슬라이더 빌드

게시 됨: 2022-03-11

저는 사용자 정의 전체 화면 레이아웃으로 거의 매일 작업합니다. 일반적으로 이러한 레이아웃은 상당한 양의 상호 작용 및 애니메이션을 의미합니다. 시간에 따라 트리거되는 복잡한 전환 타임라인이든 스크롤 기반 사용자 중심 이벤트 집합이든, 대부분의 경우 UI에는 몇 가지 조정 및 변경으로 즉시 사용 가능한 플러그인 솔루션을 사용하는 것 이상이 필요합니다. . 반면에 많은 JavaScript 개발자는 특정 플러그인이 제공하는 모든 기능이 필요하지 않더라도 작업을 더 쉽게 하기 위해 좋아하는 JS 플러그인을 찾는 경향이 있습니다.

면책 조항: 시중에 나와 있는 많은 플러그인 중 하나를 사용하면 물론 장점이 있습니다. 코딩을 많이 하지 않고도 필요에 맞게 조정할 수 있는 다양한 옵션이 제공됩니다. 또한 대부분의 플러그인 작성자는 코드를 최적화하고 브라우저 간 및 플랫폼 간 호환 등을 수행합니다. 그러나 여전히 프로젝트에 포함된 전체 크기 라이브러리는 프로젝트에서 제공하는 한두 가지에 불과합니다. 어떤 종류의 타사 플러그인을 사용하는 것이 당연히 나쁜 일이라고 말하는 것이 아니라 프로젝트에서 매일 사용합니다. 일반적으로 각 접근 방식의 장단점을 있는 그대로 평가하는 것이 좋습니다. 코딩의 좋은 습관. 이런 식으로 자신의 일을 할 때 찾고있는 것을 알기 위해서는 조금 더 많은 코딩 지식과 경험이 필요하지만 결국에는 한 가지와 한 가지 방법으로만 수행하는 코드 조각을 얻어야 합니다. 당신은 그것을 원합니다.

이 기사는 사용자 정의 콘텐츠 애니메이션을 사용하여 전체 화면 스크롤 트리거 슬라이더 레이아웃을 개발하는 순수한 CSS/JS 접근 방식을 보여주기 위한 것입니다. 이 축소된 접근 방식에서는 CMS 백엔드에서 제공될 것으로 예상되는 기본 HTML 구조, 최신 CSS(SCSS) 레이아웃 기술 및 완전한 상호 작용을 위한 기본 JavaScript 코딩을 다룰 것입니다. 기본적으로 이 개념은 더 큰 규모의 플러그인으로 쉽게 확장되거나 핵심에 종속성이 없는 다양한 응용 프로그램에서 사용할 수 있습니다.

우리가 만들 디자인은 각 프로젝트의 주요 이미지와 제목이 있는 미니멀리즘 건축가 포트폴리오 쇼케이스입니다. 애니메이션이 포함된 전체 슬라이더는 다음과 같습니다.

건축가 포트폴리오의 샘플 슬라이더입니다.

여기에서 데모를 확인할 수 있으며 자세한 내용은 내 Github 리포지토리에 액세스할 수 있습니다.

HTML 개요

다음은 작업할 기본 HTML입니다.

 <div> <div class="mask"> <!-- Textual logo will go here --> </div> <div> <div class="slides"> <!-- Featured image slides will go here --> </div> <div class="slides mask"> <!-- Slide titles will go here --> </div> </div> <div> <!-- Static info on the right --> </div> <nav> <!-- Current slide indicator --> </nav> </div>

id가 hero-slider div가 주요 보유자입니다. 내부에서 레이아웃은 섹션으로 나뉩니다.

  • 로고(정적 섹션)
  • 우리가 주로 작업할 슬라이드쇼
  • 정보(정적 섹션)
  • 현재 활성 슬라이드와 총 슬라이드 수를 나타내는 슬라이더 탐색

슬라이드쇼 섹션이 이 기사에서 관심의 대상이 되므로 이 섹션에 집중해 보겠습니다. 여기에는 mainaux 의 두 부분이 있습니다. Main은 추천 이미지를 포함하는 div이고 aux는 이미지 제목을 포함합니다. 이 두 홀더 내부의 각 슬라이드 구조는 매우 기본적입니다. 여기 메인 홀더 내부에 이미지 슬라이드가 있습니다.

 <div class="slide" data-index="0"> <div class="abs-mask"> <div class="slide-image"> </div> </div> </div>

인덱스 데이터 속성은 슬라이드쇼에서 현재 위치를 추적하는 데 사용할 것입니다. 흥미로운 전환 효과를 만드는 데 사용할 abs-mask div와 슬라이드 이미지 div에는 특정 기능 이미지가 포함되어 있습니다. 이미지는 CMS에서 직접 가져온 것처럼 인라인으로 렌더링되며 최종 사용자가 설정합니다.

유사하게, 제목은 Aux 홀더 내부로 미끄러집니다:

 <h2 class="slide-title slide" data-index="0"><a href="#">#64 Paradigm</a></h2>

각 슬라이드 제목은 해당하는 데이터 속성과 해당 프로젝트의 단일 페이지로 연결되는 링크가 있는 H2 태그입니다.

HTML의 나머지 부분도 매우 간단합니다. 상단에 로고가 있고 사용자에게 현재 페이지가 어떤 페이지인지 알려주는 정적 정보, 일부 설명 및 슬라이더 현재/총 표시기가 있습니다.

CSS 개요

소스 CSS 코드는 CSS 전처리기인 SCSS로 작성된 다음 브라우저가 해석할 수 있는 일반 CSS로 컴파일됩니다. SCSS는 변수, 중첩 선택, 믹스인 및 기타 멋진 것들을 사용하는 이점을 제공하지만 브라우저가 코드를 제대로 읽도록 하려면 CSS로 컴파일해야 합니다. 이 튜토리얼의 목적을 위해 Scout-App을 사용하여 최소한의 도구를 사용하고 싶었기 때문에 컴파일을 처리했습니다.

flexbox를 사용하여 기본 병렬 레이아웃을 처리했습니다. 아이디어는 한쪽에는 슬라이드쇼가 있고 다른 한쪽에는 정보 섹션이 있는 것입니다.

 #hero-slider { position: relative; height: 100vh; display: flex; background: $dark-color; } #slideshow { position: relative; flex: 1 1 $main-width; display: flex; align-items: flex-end; padding: $offset; } #info { position: relative; flex: 1 1 $side-width; padding: $offset; background-color: #fff; }

위치를 자세히 살펴보고 다시 슬라이드쇼 섹션에 집중해 보겠습니다.

 #slideshow { position: relative; flex: 1 1 $main-width; display: flex; align-items: flex-end; padding: $offset; } #slides-main { @extend %abs; &:after { content: ''; @extend %abs; background-color: rgba(0, 0, 0, .25); z-index: 100; } .slide-image { @extend %abs; background-position: center; background-size: cover; z-index: -1; } } #slides-aux { position: relative; top: 1.25rem; width: 100%; .slide-title { position: absolute; z-index: 300; font-size: 4vw; font-weight: 700; line-height: 1.3; @include outlined(#fff); } }

기본 슬라이더를 절대 위치로 설정하고 background-size: cover 속성을 사용하여 배경 이미지가 전체 영역을 확장하도록 했습니다. 슬라이드 제목에 대해 더 많은 대비를 제공하기 위해 오버레이 역할을 하는 절대 유사 요소를 설정했습니다. 슬라이드 제목이 포함된 보조 슬라이더는 화면 하단과 이미지 상단에 위치합니다.

한 번에 하나의 슬라이드만 표시되므로 각 제목도 절대적으로 설정하고 JS를 통해 홀더 크기를 계산하여 잘림이 없는지 확인하도록 합니다. 여기에서 확장이라는 SCSS 기능의 사용을 볼 수 있습니다.

 %abs { position: absolute; top: 0; left: 0; height: 100%; width: 100%; }

절대 위치 지정을 많이 사용했기 때문에 이 CSS를 다양한 선택기에서 쉽게 사용할 수 있도록 확장 가능한 것으로 가져왔습니다. 또한 제목과 메인 슬라이더 제목을 스타일링할 때 DRY 접근 방식을 제공하기 위해 "outlined"라는 믹스인을 만들었습니다.

 @mixin outlined($color: $dark-color, $size: 1px) { color: transparent; -webkit-text-stroke: $size $color; }

이 레이아웃의 정적 부분은 복잡하지 않지만 일반적인 흐름 대신 Y축에 있어야 하는 텍스트를 배치할 때 흥미로운 방법을 볼 수 있습니다.

 .slider-title-wrapper { position: absolute; top: $offset; left: calc(100% - #{$offset}); transform-origin: 0% 0%; transform: rotate(90deg); @include outlined; }

이 유형의 레이아웃에 대해 실제로 제대로 사용되지 않는 것으로 나타났기 때문에 transform-origin 속성에 주의를 기울이고 싶습니다. 이 요소가 배치되는 방식은 해당 앵커가 요소의 왼쪽 상단 모서리에 유지되어 회전 지점을 설정하고 다른 화면 크기와 관련하여 문제 없이 해당 지점에서 아래쪽으로 텍스트가 계속 흐르도록 하는 것입니다.

더 흥미로운 CSS 부분인 초기 로딩 애니메이션을 살펴보겠습니다.

슬라이더의 애니메이션을 로드합니다.

일반적으로 이러한 종류의 동기화된 애니메이션 동작은 라이브러리를 사용하여 달성됩니다. 예를 들어 GSAP는 최고의 렌더링 기능을 제공하고 사용하기 쉬우며 개발자가 프로그래밍 방식으로 요소를 연결할 수 있도록 하는 타임라인 기능이 있는 최고 중 하나입니다. 서로 전환합니다.

그러나 이것은 순수한 CSS/JS 예제이므로 여기에서 정말 기본적인 것으로 결정했습니다. 따라서 각 요소는 기본적으로 시작 위치로 설정됩니다. 변형 또는 불투명도에 의해 숨겨지고 JS에 의해 트리거되는 슬라이더 로드 시 표시됩니다. 모든 전환 속성은 수동으로 조정되어 각 전환이 다른 전환으로 이어지는 자연스럽고 흥미로운 흐름을 보장하여 쾌적한 시각적 경험을 제공합니다.

 #logo:after { transform: scaleY(0); transform-origin: 50% 0; transition: transform .35s $easing; } .logo-text { display: block; transform: translate3d(120%, 0, 0); opacity: 0; transition: transform .8s .2s, opacity .5s .2s; } .current, .sep:before { opacity: 0; transition: opacity .4s 1.3s; } #info { transform: translate3d(100%, 0, 0); transition: transform 1s $easing .6s; } .line { transform-origin: 0% 0; transform: scaleX(0); transition: transform .7s $easing 1s; } .slider-title { overflow: hidden; >span { display: block; transform: translate3d(0, -100%, 0); transition: transform .5s 1.5s; } }

여기서 한 가지 봤으면 하는 것이 transform 속성의 사용입니다. 트랜지션이든 애니메이션이든 HTML 요소를 이동할 때 transform 속성을 사용하는 것이 좋습니다. 여백이나 패딩, 오프셋(상단, 왼쪽 등)을 사용하는 경향이 있는 많은 사람들이 렌더링과 관련하여 적절한 결과를 생성하지 못하는 것을 봅니다.

대화형 동작을 추가할 때 CSS를 사용하는 방법을 더 깊이 이해하기 위해 다음 기사를 충분히 추천할 수 없었습니다.

Chrome 엔지니어인 Paul Lewis가 작성했으며 CSS든 JS든 웹에서 픽셀 렌더링에 대해 알아야 할 거의 모든 것을 다룹니다.

JavaScript 개요 및 슬라이더 논리

JavaScript 파일은 두 개의 고유한 기능으로 나뉩니다.

여기에 필요한 모든 기능을 처리하는 heroSlider 함수와 몇 가지 재사용 가능한 유틸리티 함수를 추가한 utils 함수가 있습니다. 프로젝트에서 재사용하려는 경우 컨텍스트를 제공하기 위해 이러한 유틸리티 함수 각각에 대해 설명했습니다.

main 함수는 initresize 라는 두 가지 분기가 있는 방식으로 코딩됩니다. 이러한 분기는 주 함수의 반환을 통해 사용할 수 있으며 필요할 때 호출됩니다. init 는 메인 함수의 초기화이며 창 로드 이벤트에서 트리거됩니다. 마찬가지로 크기 조정 분기는 창 크기 조정 시 트리거됩니다. 크기 조정 기능의 유일한 목적은 제목 글꼴 크기가 다를 수 있으므로 창 크기 조정 시 제목의 슬라이더 크기를 다시 계산하는 것입니다.

heroSlider 함수에서 필요한 모든 데이터와 선택기를 포함하는 슬라이더 객체를 제공했습니다.

 const slider = { hero: document.querySelector('#hero-slider'), main: document.querySelector('#slides-main'), aux: document.querySelector('#slides-aux'), current: document.querySelector('#slider-nav .current'), handle: null, idle: true, activeIndex: -1, interval: 3500 };

참고로 이 접근 방식은 예를 들어 React를 사용하는 경우 데이터를 상태에 저장하거나 새로 추가된 후크를 사용할 수 있으므로 쉽게 조정할 수 있습니다. 요점을 유지하기 위해 여기에 있는 각 키-값 쌍이 나타내는 내용을 살펴보겠습니다.

  • 처음 4개의 속성은 우리가 조작할 DOM 요소에 대한 HTML 참조입니다.
  • handle 속성은 자동 재생 기능을 시작 및 중지하는 데 사용됩니다.
  • idle 속성은 슬라이드가 전환되는 동안 사용자가 강제로 스크롤하지 못하도록 하는 플래그입니다.
  • activeIndex 를 사용하면 현재 활성 슬라이드를 추적할 수 있습니다.
  • interval 은 슬라이더의 자동 재생 간격을 나타냅니다.

슬라이더 초기화 시 두 가지 함수를 호출합니다.

 setHeight(slider.aux, slider.aux.querySelectorAll('.slide-title')); loadingAnimation();

setHeight 함수는 유틸리티 함수에 도달하여 최대 제목 크기를 기반으로 aux 슬라이더의 높이를 설정합니다. 이렇게 하면 적절한 크기가 제공되고 내용이 두 줄로 줄어들더라도 슬라이드 제목이 잘리지 않습니다.

loadingAnimation 함수는 인트로 CSS 전환을 제공하는 요소에 CSS 클래스를 추가합니다.

 const loadingAnimation = function () { slider.hero.classList.add('ready'); slider.current.addEventListener('transitionend', start, { once: true }); }

슬라이더 표시기는 CSS 전환 타임라인의 마지막 요소이므로 전환이 끝날 때까지 기다렸다가 시작 기능을 호출합니다. 추가 매개변수를 객체로 제공하여 이것이 한 번만 트리거되도록 합니다.

시작 기능을 살펴보겠습니다.

 const start = function () { autoplay(true); wheelControl(); window.innerWidth <= 1024 && touchControl(); slider.aux.addEventListener('transitionend', loaded, { once: true }); }

따라서 레이아웃이 완료되면 loadingAnimation 함수에 의해 초기 전환이 트리거되고 시작 함수가 인계받습니다. 그런 다음 자동 재생 기능을 트리거하고, 휠 제어를 활성화하고, 터치 또는 데스크톱 장치를 사용 중인지 확인하고, 제목 슬라이드가 먼저 전환되어 적절한 CSS 클래스를 추가할 때까지 기다립니다.

자동 재생

이 레이아웃의 핵심 기능 중 하나는 자동 재생 기능입니다. 해당 기능을 살펴보겠습니다.

 const autoplay = function (initial) { slider.autoplay = true; slider.items = slider.hero.querySelectorAll('[data-index]'); slider.total = slider.items.length / 2; const loop = () => changeSlide('next'); initial && requestAnimationFrame(loop); slider.handle = utils().requestInterval(loop, slider.interval); }

먼저 자동 재생 플래그를 true로 설정하여 슬라이더가 자동 재생 모드임을 나타냅니다. 이 플래그는 사용자가 슬라이더와 상호 작용한 후 자동 재생을 다시 트리거할지 여부를 결정할 때 유용합니다. 그런 다음 활성 클래스를 변경하고 모든 항목을 더하고 두 개의 동기화된 슬라이더 레이아웃(기본 및 보조)이 있으므로 2로 나누어 슬라이더의 총 반복 횟수를 계산하므로 모든 슬라이더 항목(슬라이드)을 참조합니다. 그러나 둘 다 동시에 변경하는 자체 "슬라이더"는 하나뿐입니다.

이 코드에서 가장 흥미로운 부분은 루프 기능입니다. 이것은 우리가 잠시 후에 살펴볼 슬라이드 방향을 제공하는 slideChange 를 호출하지만 루프 함수는 몇 번 호출됩니다. 왜 그런지 봅시다.

초기 인수가 true로 평가되면 루프 함수를 requestAnimationFrame 콜백으로 호출합니다. 이것은 즉각적인 슬라이드 변경을 트리거하는 첫 번째 슬라이더 로드 시에만 발생합니다. requestAnimationFrame 을 사용하여 다음 프레임 다시 그리기 직전에 제공된 콜백을 실행합니다.

슬라이더를 만드는 데 사용되는 단계의 다이어그램입니다.

그러나 자동 재생 모드에서 슬라이드를 계속 진행하기를 원하므로 동일한 기능을 반복적으로 호출할 것입니다. 이것은 일반적으로 setInterval을 사용하여 수행됩니다. 그러나 이 경우 유틸리티 함수 중 하나인 requestInterval 을 사용합니다. setInterval 은 잘 작동하지만 requestIntervalrequestAnimationFrame 에 의존하고 보다 성능이 뛰어난 접근 방식을 제공하는 고급 개념입니다. 브라우저 탭이 활성화된 경우에만 기능이 다시 트리거되도록 합니다.

이 멋진 기사에서 이 개념에 대한 자세한 내용은 CSS 트릭에서 찾을 수 있습니다. 이 함수의 반환 값을 slider.handle 속성에 할당합니다. 함수가 반환하는 이 고유 ID는 사용할 수 있으며 나중에 cancelAnimationFrame 을 사용하여 자동 재생을 취소하는 데 사용합니다.

슬라이드 변경

slideChange 기능은 전체 개념의 주요 기능입니다. 자동 재생이든 사용자 트리거이든 슬라이드를 변경합니다. 슬라이더 방향을 인식하고 루핑을 제공하므로 마지막 슬라이드에 올 때 첫 번째 슬라이드를 계속할 수 있습니다. 제가 코딩한 방법은 다음과 같습니다.

 const changeSlide = function (direction) { slider.idle = false; slider.hero.classList.remove('prev', 'next'); if (direction == 'next') { slider.activeIndex = (slider.activeIndex + 1) % slider.total; slider.hero.classList.add('next'); } else { slider.activeIndex = (slider.activeIndex - 1 + slider.total) % slider.total; slider.hero.classList.add('prev'); } //reset classes utils().removeClasses(slider.items, ['prev', 'active']); //set prev const prevItems = [...slider.items] .filter(item => { let prevIndex; if (slider.hero.classList.contains('prev')) { prevIndex = slider.activeIndex == slider.total - 1 ? 0 : slider.activeIndex + 1; } else { prevIndex = slider.activeIndex == 0 ? slider.total - 1 : slider.activeIndex - 1; } return item.dataset.index == prevIndex; }); //set active const activeItems = [...slider.items] .filter(item => { return item.dataset.index == slider.activeIndex; }); utils().addClasses(prevItems, ['prev']); utils().addClasses(activeItems, ['active']); setCurrent(); const activeImageItem = slider.main.querySelector('.active'); activeImageItem.addEventListener('transitionend', waitForIdle, { once: true }); }

아이디어는 HTML에서 얻은 데이터 인덱스를 기반으로 활성 슬라이드를 결정하는 것입니다. 각 단계를 살펴보겠습니다.

  1. 슬라이더 유휴 플래그를 false로 설정합니다. 이것은 슬라이드 변경이 진행 중이며 휠 및 터치 제스처가 비활성화되었음을 나타냅니다.
  2. 이전 슬라이더 방향 CSS 클래스가 재설정되고 새 클래스가 있는지 확인합니다. 방향 매개변수는 자동 재생 기능에서 오는 경우 기본적으로 'next'로 제공되거나 사용자가 호출한 함수 wheelControl 또는 touchControl )에 의해 제공됩니다.
  3. 방향을 기반으로 활성 슬라이드 인덱스를 계산하고 슬라이더에 현재 방향 CSS 클래스를 제공합니다. 이 CSS 클래스는 사용할 전환 효과를 결정하는 데 사용됩니다(예: 오른쪽에서 왼쪽 또는 왼쪽에서 오른쪽으로).
  4. 슬라이드는 CSS 클래스를 제거하지만 단일 DOM 요소가 아닌 NodeList에서 호출할 수 있는 다른 유틸리티 기능을 사용하여 "상태" CSS 클래스(이전, 활성)를 재설정합니다. 이후에는 이전 및 현재 활성 슬라이드에만 해당 CSS 클래스가 추가됩니다. 이렇게 하면 CSS가 해당 슬라이드만 대상으로 하고 적절한 전환을 제공할 수 있습니다.
  5. setCurrent 는 activeIndex를 기반으로 슬라이더 표시기를 업데이트하는 콜백입니다.
  6. 마지막으로 사용자가 이전에 중단한 경우 자동 재생을 다시 시작하는 waitForIdle 콜백을 트리거하기 위해 활성 이미지 슬라이드의 전환이 끝날 때까지 기다립니다.

사용자 컨트롤

화면 크기에 따라 휠과 터치라는 두 가지 유형의 사용자 컨트롤을 추가했습니다. 휠 컨트롤:

 const wheelControl = function () { slider.hero.addEventListener('wheel', e => { if (slider.idle) { const direction = e.deltaY > 0 ? 'next' : 'prev'; stopAutoplay(); changeSlide(direction); } }); }

여기에서 우리는 휠을 수신하고 슬라이더가 현재 유휴 모드(현재 슬라이드 변경에 애니메이션을 적용하지 않음)에 있는 경우 휠 방향을 결정하고 stopAutoplay 를 호출하여 진행 중인 경우 자동 재생 기능을 중지하고 방향에 따라 슬라이드를 변경합니다. stopAutoplay 함수는 autoplay 플래그를 false 값으로 설정하고 적절한 핸들을 전달하는 cancelRequestInterval 유틸리티 함수를 호출하여 간격을 취소하는 단순한 함수일 뿐입니다.

 const stopAutoplay = function () { slider.autoplay = false; utils().clearRequestInterval(slider.handle); }

wheelControl 과 유사하게 터치 제스처를 처리하는 touchControl 이 있습니다.

 const touchControl = function () { const touchStart = function (e) { slider.ts = parseInt(e.changedTouches[0].clientX); window.scrollTop = 0; } const touchMove = function (e) { slider.tm = parseInt(e.changedTouches[0].clientX); const delta = slider.tm - slider.ts; window.scrollTop = 0; if (slider.idle) { const direction = delta < 0 ? 'next' : 'prev'; stopAutoplay(); changeSlide(direction); } } slider.hero.addEventListener('touchstart', touchStart); slider.hero.addEventListener('touchmove', touchMove); }

우리는 두 가지 이벤트를 수신합니다: touchstarttouchmove . 그런 다음 차이를 계산합니다. 음수 값을 반환하면 사용자가 오른쪽에서 왼쪽으로 스와이프하므로 다음 슬라이드로 변경됩니다. 반면에 값이 양수이면 사용자가 왼쪽에서 오른쪽으로 스와이프했음을 의미하며 "이전"으로 전달된 방향으로 slideChange 를 트리거합니다. 두 경우 모두 자동 재생 기능이 중지됩니다.

이것은 매우 간단한 사용자 제스처 구현입니다. 이를 기반으로 이전/다음 버튼을 추가하여 클릭 slideChange 을 트리거하거나 글머리 기호 목록을 추가하여 인덱스를 기반으로 슬라이드로 직접 이동할 수 있습니다.

CSS에 대한 요약 및 최종 생각

이제 최신 전환 효과를 사용하여 비표준 슬라이더 레이아웃을 코딩하는 순수한 CSS/JS 방법입니다.

이 접근 방식이 사고 방식으로 유용하고 일반적으로 설계되지 않은 프로젝트를 코딩할 때 프런트 엔드 프로젝트에서 유사한 것을 사용할 수 있기를 바랍니다.

이미지 전환 효과에 관심이 있는 분들을 위해 다음 몇 줄에서 이에 대해 설명하겠습니다.

소개 섹션에서 제공한 슬라이드 HTML 구조를 다시 방문하면 각 이미지 슬라이드 주위에 abs-mask 의 CSS 클래스가 있는 div 가 있음을 알 수 있습니다. 이 div 가 하는 일은 overflow:hidden 을 사용하고 이미지와 다른 방향으로 오프셋하여 보이는 이미지의 일부를 일정량 숨기는 것입니다. 예를 들어 이전 슬라이드가 코딩된 방식을 보면 다음과 같습니다.

 &.prev { z-index: 5; transform: translate3d(-100%, 0, 0); transition: 1s $easing; .abs-mask { transform: translateX(80%); transition: 1s $easing; } }

이전 슬라이드는 X축에 -100% 오프셋이 있어 현재 슬라이드의 왼쪽으로 이동하지만 내부 abs-mask div는 오른쪽으로 80% 변환되어 더 좁은 뷰포트를 제공합니다. 이것은 활성 슬라이드에 대해 더 큰 z-인덱스를 갖는 것과 결합하여 일종의 커버 효과를 가져옵니다. 활성 이미지는 이전 이미지를 덮는 동시에 전체 보기를 제공하는 마스크를 이동하여 가시 영역을 확장합니다.