스와이퍼 Swiper
1. Swiper란?
Swiper는 터치 슬라이더 라이브러리. 모바일과 데스크톱 모두 지원.
주요 특징:
- 터치/드래그 지원
- 반응형 디자인
- 다양한 효과 (fade, cube, flip 등)
- 네비게이션, 페이지네이션 지원
2. 설치
2.1. CDN
<!-- CSS --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />
<!-- JS --><script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>2.2. NPM
npm install swiper3. 기본 구조
:::tip[필수 구조] 슬라이드는 반드시 두 단계로 감싸야 합니다. :::
- HTML
- CSS
- JS
<!-- 1. 메인 컨테이너 -->/* 슬라이더 크기 지정 */// Swiper 초기화
<!-- 1. 메인 컨테이너 --><div class="swiper"> <!-- 2. 슬라이드 래퍼 --> <div class="swiper-wrapper"> <!-- 3. 개별 슬라이드 --> <div class="swiper-slide">슬라이드 1</div> <div class="swiper-slide">슬라이드 2</div> <div class="swiper-slide">슬라이드 3</div> </div>
<!-- 페이지네이션 (선택) --> <div class="swiper-pagination"></div>
<!-- 이전/다음 버튼 (선택) --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div></div>
/* 슬라이더 크기 지정 */.swiper { width: 100%; height: 400px;}
// Swiper 초기화const swiper = new Swiper('.swiper');
4. 주요 옵션
API
- 파라미터
- 메서드
- 프로퍼티
- 이벤트
파라미터 설명 타입/값 예시 기본값 loop무한 반복 true / falsefalseautoplay자동 재생 { delay: 3000 } / falsefalsespeed전환 속도(ms) 300, 1000300slidesPerView보여줄 슬라이드 수 1, 2, auto1spaceBetween슬라이드 간격(px) 0, 200direction슬라이드 방향 horizontal / verticalhorizontaleffect전환 효과 slide, fade, cube 등slidecenteredSlides활성 슬라이드 중앙 배치 true / falsefalseautoHeight자동 높이 조절 true / falsefalsepagination페이지네이션 설정 { el: '.swiper-pagination' }없음 navigation이전/다음 버튼 설정 { nextEl, prevEl }없음 breakpoints반응형 설정 { 640: {...}, ... }없음 on이벤트 핸들러(콜백) { slideChange: fn }없음
Method 설명 사용 예시 slideNext()다음 슬라이드로 이동 swiper.slideNext()slidePrev()이전 슬라이드로 이동 swiper.slidePrev()slideTo(index, speed, runCallbacks)특정 인덱스로 이동 swiper.slideTo(3, 500)update()Swiper 업데이트 (크기/위치 재계산) swiper.update()destroy(deleteInstance, cleanStyles)Swiper 인스턴스 제거 swiper.destroy(true)appendSlide(slides)슬라이드 추가 (마지막) swiper.appendSlide('<div>new</div>')prependSlide(slides)슬라이드 추가 (처음) swiper.prependSlide('<div>new</div>')removeSlide(index)슬라이드 제거 swiper.removeSlide(2)removeAllSlides()모든 슬라이드 제거 swiper.removeAllSlides()updateSlides()슬라이드만 업데이트 swiper.updateSlides()updateProgress()진행 상태 업데이트 swiper.updateProgress()updateSlidesClasses()슬라이드 클래스 업데이트 swiper.updateSlidesClasses()disable()Swiper 비활성화 swiper.disable()enable()Swiper 활성화 swiper.enable()detachEvents()이벤트 리스너 제거 swiper.detachEvents()attachEvents()이벤트 리스너 추가 swiper.attachEvents()
Property 타입 설명 activeIndexnumber 현재 활성 슬라이드 인덱스 realIndexnumber 실제 슬라이드 인덱스 (loop 모드에서 유용) previousIndexnumber 이전 슬라이드 인덱스 isBeginningboolean 첫 번째 슬라이드 여부 isEndboolean 마지막 슬라이드 여부 slidesarray 모든 슬라이드 요소 배열 widthnumber Swiper 컨테이너 너비 heightnumber Swiper 컨테이너 높이 paramsobject Swiper 초기화 파라미터 elHTMLElement Swiper 컨테이너 요소 wrapperElHTMLElement Swiper wrapper 요소 navigationobject Navigation 모듈 인스턴스 paginationobject Pagination 모듈 인스턴스 scrollbarobject Scrollbar 모듈 인스턴스 autoplayobject Autoplay 모듈 인스턴스 touchesobject 터치 정보 translatenumber 현재 translate 값 progressnumber 전체 진행률 (0-1) allowSlideNextboolean 다음 슬라이드 이동 가능 여부 allowSlidePrevboolean 이전 슬라이드 이동 가능 여부 allowTouchMoveboolean 터치 이동 가능 여부
Event 설명 사용 예시 init초기화 완료 on: { init: () => {} }slideChange슬라이드 변경 시 on: { slideChange: () => {} }slideChangeTransitionStart슬라이드 전환 시작 on: { slideChangeTransitionStart: () => {} }slideChangeTransitionEnd슬라이드 전환 완료 on: { slideChangeTransitionEnd: () => {} }reachBeginning처음 도달 on: { reachBeginning: () => {} }reachEnd끝 도달 on: { reachEnd: () => {} }click클릭 시 on: { click: (swiper, e) => {} }tap탭 시 on: { tap: (swiper, e) => {} }touchStart터치 시작 on: { touchStart: () => {} }touchEnd터치 종료 on: { touchEnd: () => {} }
파라미터 설명 타입/값 예시 기본값 loop무한 반복 true / falsefalseautoplay자동 재생 { delay: 3000 } / falsefalsespeed전환 속도(ms) 300, 1000300slidesPerView보여줄 슬라이드 수 1, 2, auto1spaceBetween슬라이드 간격(px) 0, 200direction슬라이드 방향 horizontal / verticalhorizontaleffect전환 효과 slide, fade, cube 등slidecenteredSlides활성 슬라이드 중앙 배치 true / falsefalseautoHeight자동 높이 조절 true / falsefalsepagination페이지네이션 설정 { el: '.swiper-pagination' }없음 navigation이전/다음 버튼 설정 { nextEl, prevEl }없음 breakpoints반응형 설정 { 640: {...}, ... }없음 on이벤트 핸들러(콜백) { slideChange: fn }없음
Method 설명 사용 예시 slideNext()다음 슬라이드로 이동 swiper.slideNext()slidePrev()이전 슬라이드로 이동 swiper.slidePrev()slideTo(index, speed, runCallbacks)특정 인덱스로 이동 swiper.slideTo(3, 500)update()Swiper 업데이트 (크기/위치 재계산) swiper.update()destroy(deleteInstance, cleanStyles)Swiper 인스턴스 제거 swiper.destroy(true)appendSlide(slides)슬라이드 추가 (마지막) swiper.appendSlide('<div>new</div>')prependSlide(slides)슬라이드 추가 (처음) swiper.prependSlide('<div>new</div>')removeSlide(index)슬라이드 제거 swiper.removeSlide(2)removeAllSlides()모든 슬라이드 제거 swiper.removeAllSlides()updateSlides()슬라이드만 업데이트 swiper.updateSlides()updateProgress()진행 상태 업데이트 swiper.updateProgress()updateSlidesClasses()슬라이드 클래스 업데이트 swiper.updateSlidesClasses()disable()Swiper 비활성화 swiper.disable()enable()Swiper 활성화 swiper.enable()detachEvents()이벤트 리스너 제거 swiper.detachEvents()attachEvents()이벤트 리스너 추가 swiper.attachEvents()
Property 타입 설명 activeIndexnumber 현재 활성 슬라이드 인덱스 realIndexnumber 실제 슬라이드 인덱스 (loop 모드에서 유용) previousIndexnumber 이전 슬라이드 인덱스 isBeginningboolean 첫 번째 슬라이드 여부 isEndboolean 마지막 슬라이드 여부 slidesarray 모든 슬라이드 요소 배열 widthnumber Swiper 컨테이너 너비 heightnumber Swiper 컨테이너 높이 paramsobject Swiper 초기화 파라미터 elHTMLElement Swiper 컨테이너 요소 wrapperElHTMLElement Swiper wrapper 요소 navigationobject Navigation 모듈 인스턴스 paginationobject Pagination 모듈 인스턴스 scrollbarobject Scrollbar 모듈 인스턴스 autoplayobject Autoplay 모듈 인스턴스 touchesobject 터치 정보 translatenumber 현재 translate 값 progressnumber 전체 진행률 (0-1) allowSlideNextboolean 다음 슬라이드 이동 가능 여부 allowSlidePrevboolean 이전 슬라이드 이동 가능 여부 allowTouchMoveboolean 터치 이동 가능 여부
Event 설명 사용 예시 init초기화 완료 on: { init: () => {} }slideChange슬라이드 변경 시 on: { slideChange: () => {} }slideChangeTransitionStart슬라이드 전환 시작 on: { slideChangeTransitionStart: () => {} }slideChangeTransitionEnd슬라이드 전환 완료 on: { slideChangeTransitionEnd: () => {} }reachBeginning처음 도달 on: { reachBeginning: () => {} }reachEnd끝 도달 on: { reachEnd: () => {} }click클릭 시 on: { click: (swiper, e) => {} }tap탭 시 on: { tap: (swiper, e) => {} }touchStart터치 시작 on: { touchStart: () => {} }touchEnd터치 종료 on: { touchEnd: () => {} }
6. 단계별 예제
6.1. STEP 1: 기본 슬라이더
<!DOCTYPE html><html lang="ko"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>기본 Swiper</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"> <style> .swiper { width: 100%; height: 300px; } .swiper-slide { background: #eee; display: flex; align-items: center; justify-content: center; font-size: 24px; } </style></head><body> <div class="swiper"> <div class="swiper-wrapper"> <div class="swiper-slide">1</div> <div class="swiper-slide">2</div> <div class="swiper-slide">3</div> </div> </div>
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script> <script> const swiper = new Swiper('.swiper', { loop: true }); </script></body></html>
6.2. STEP 2: 네비게이션 & 페이지네이션 추가
:::tip[필수 구조]
.swiper-pagination, .swiper-button-prev, .swiper-button-next 는 반드시 .swiper-wrapper 와 형제요소로 삽입 합니다.
:::
<div class="swiper"> <div class="swiper-wrapper"> <div class="swiper-slide">1</div> <div class="swiper-slide">2</div> <div class="swiper-slide">3</div> </div> <!-- //.swiper-wrapper --> <!-- 페이지네이션 --> <div class="swiper-pagination"></div> <!-- 화살표 버튼 --> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div>
<script> const swiper = new Swiper('.swiper', { loop: true, // 페이지네이션 설정 pagination: { el: '.swiper-pagination', clickable: true }, // 네비게이션 설정 navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' } }); </script>
6.3. STEP 3: 자동 재생
const swiper = new Swiper('.swiper', { loop: true, autoplay: { delay: 3000, // 3초마다 전환 disableOnInteraction: false,// 사용자 조작 후에도 자동재생 유지 pauseOnMouseEnter: true // 마우스 올리면 일시 정지 (핵심 설정) }, pagination: { el: '.swiper-pagination', clickable: true }});
6.4. STEP 4: 여러 슬라이드 보이기
const swiper = new Swiper('.swiper', { slidesPerView: 3, // 한 번에 3개 보이기 spaceBetween: 20, // 슬라이드 간격 20px centeredSlides: true, // 활성 슬라이드 중앙 배치 loop: true});
6.5. STEP 5: 반응형 설정
const swiper = new Swiper('.swiper', { slidesPerView: 1, // 기본 (모바일) spaceBetween: 10,
// 화면 크기별 설정 breakpoints: { // 640px 이상 640: { slidesPerView: 2, spaceBetween: 20 }, // 768px 이상 768: { slidesPerView: 3, spaceBetween: 30 }, // 1024px 이상 1024: { slidesPerView: 4, spaceBetween: 40 } }});
6.6. 기타 예제
7. 이미지 갤러리 예제
swiper를 이용해 이미지갤러리를 제작한다.
가로 820픽셀 이미지 8 장을 준비하고 Swiper를 이용해서 3개의 이미지가 보여지며 페이지 이동과 이전, 다음 버튼을 이용해 이미지를 변경할 수 있도록 제작
7.1. STEP1
- HTML
- CSS
- JS
- reset.css 와 스와이퍼를 설치한다
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
- “body” 배경색을 파일 1개를 지정하고 글꼴을 지정한다. 스와이퍼를 감싸는”promotion”에도 배경색과 높이를 설정한다.
body { 'use strict';
- reset.css 와 스와이퍼를 설치한다
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" /> <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js" defer></script>
- section 태그 자식요소로 div 를 만들고 자식요소로 스와이퍼 요소를 추가한다. 스와이퍼에서 제공하는 클래스이름은 변경하지 않고 그대로 사용한다. 스와이퍼의 부모요소인 section과 div 는 필요에 따라 변경해서 사용하면된다.
<section class="notice"> <div class="promotion"> <div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"></div> </div> </div> <div class="swiper-pagination"></div> <div class="swiper-prev"></div> <div class="swiper-next"></div> </div></section>
- section 태그 자식요소로 div 를 만들고 자식요소로 스와이퍼 요소를 추가한다. 스와이퍼에서 제공하는 클래스이름은 변경하지 않고 그대로 사용한다. 스와이퍼의 부모요소인 section과 div 는 필요에 따라 변경해서 사용하면된다.
<section class="notice"> <div class="promotion"> <div class="swiper-container"> <div class="swiper-wrapper"> <div class="swiper-slide"></div> </div> </div> <div class="swiper-pagination"></div> <div class="swiper-prev"></div> <div class="swiper-next"></div> </div></section>
- 슬라이드에 추가할 이미지를img 태그를 이용해 swiper-slide 자식 요소로 입력한다.
<div class="swiper-slide"> <img src="./imgs/1.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/2.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/3.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/4.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/5.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/6.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/7.jpg" alt="" /> </div> <div class="swiper-slide"> <img src="./imgs/8.jpg" alt="" /> </div>
- 구글 머티리얼 아이콘을 이용해 좌/우 화살표를 입력한다.
<div class="swiper-prev"> <span class="material-symbols-outlined"> chevron_left </span> </div> <div class="swiper-next"> <span class="material-symbols-outlined"> chevron_right </span> </div>
- “body” 배경색을 파일 1개를 지정하고 글꼴을 지정한다. 스와이퍼를 감싸는”promotion”에도 배경색과 높이를 설정한다.
body { background-color: rgb(228, 247, 255); color: darkblue; font-size: 16px; font-weight: 400; line-height: 1.4; font-family: 'Nanum Gothic', sans-serif; } .notice .promotion { height: 740px; background-color: #3e85a3; position: relative; overflow-x: hidden; }
'use strict'; new Swiper('.promotion .swiper-container', { slidesPerView: 3, //한번에 보여줄 슬라이드 개수 spaceBetween: 20, centeredSlides: true, loop: true, autoplay: { delay: 5000, }, pagination: { el: '.swiper-pagination', clickable: true, //사용자의 페이지 번호 요소 제어 가능 여부 }, navigation: { prevEl: '.promotion .swiper-prev', nextEl: '.promotion .swiper-next', }, });
7.2. STEP2
이미지 위치조정
- CSS
- 슬라이드를 3장씩 보여주고 선택된 이미지는 중앙에 선명하게 보여 주고 양쪽에 이미지는 투명도를 0.4정도를 줘서 반투명하게 보여주 도록 한다. 세장의 이미지를 보여주기 위해 “swiper-container”의 폭을 3배 로 지정하고 간격을 20픽셀 더한 2,480픽셀로 지정한다.
.notice .promotion .swiper-container {
- 슬라이드를 3장씩 보여주고 선택된 이미지는 중앙에 선명하게 보여 주고 양쪽에 이미지는 투명도를 0.4정도를 줘서 반투명하게 보여주 도록 한다. 세장의 이미지를 보여주기 위해 “swiper-container”의 폭을 3배 로 지정하고 간격을 20픽셀 더한 2,480픽셀로 지정한다.
.notice .promotion .swiper-container { width: calc(420px * 3 + 20px); height: 540px; position: absolute; top: 40px; left: 50%; transform: translateX(-50%); }
7.3. STEP3
투명도 조정 및 버튼 배치
- CSS
- 슬라이드에서 가운데 보여지는 이미지의 투명도를 1로 하고 양쪽에 이미지는 투명도를 0.4로 지정한다. 페이지네이션 블릿은 이미지(”./imgs/promotion_slide_pager.png”)를 백그라운로 지정한다. 그후 액티브 상태의 이미지 (”./imgs/promotion_slide_pager_on.png”)를 교체하도록 설정한다.
.notice .promotion .swiper-slide {
- 슬라이드에서 가운데 보여지는 이미지의 투명도를 1로 하고 양쪽에 이미지는 투명도를 0.4로 지정한다. 페이지네이션 블릿은 이미지(”./imgs/promotion_slide_pager.png”)를 백그라운로 지정한다. 그후 액티브 상태의 이미지 (”./imgs/promotion_slide_pager_on.png”)를 교체하도록 설정한다.
.notice .promotion .swiper-slide { opacity: 0.4; transition: opacity 1s; position: relative; text-align: center; } .notice .promotion .swiper-slide img { width: 100%; height: 100%; /* 비율깨짐 */ object-fit: fill; object-fit: contain; object-fit: scale-down; object-fit: cover; /* 가로기준으로 비율에 맞게 채움 */ } .notice .promotion .swiper-slide-active { opacity: 1; } .notice .promotion .swiper-pagination { bottom: 40px; left: 0; right: 0; position: absolute; z-index: 9999; } .notice .promotion .swiper-pagination .swiper-pagination-bullet { background-color: transparent; background: url('./imgs/promotion_slide_pager.png') no-repeat center center/100%; width: 20px; height: 20px; margin-right: 6px; outline: none; } .notice .promotion .swiper-pagination .swiper-pagination-bullet:last-child { margin-right: 0; } .notice .promotion .swiper-pagination .swiper-pagination-bullet-active { background: url('./imgs/promotion_slide_pager_on.png') no-repeat center center/100%; }
- 좌우로 이동하는 화살표에 호버를 설정한다.
.notice .promotion .swiper-prev, .notice .promotion .swiper-next { width: 42px; height: 42px; border: 2px solid rgb(255, 255, 255); border-radius: 50%; color: white; position: absolute; top: 300px; z-index: 1; cursor: pointer; outline: none; display: flex; justify-content: center; align-items: center; transition: 0.4s; user-select: none; } .notice .promotion .swiper-prev { left: 50%; margin-left: -480px; } .notice .promotion .swiper-next { right: 50%; margin-right: -480px; } .notice .promotion .swiper-prev:hover, .notice .promotion swiper-next:hover { background-color: rgb(255, 255, 255); color: rgb(0, 0, 0); }
8. 동영상 슬라이더
- HTML
- Css
- js
<div class="swiper video-slider"> .video-slider { function stopAll() {
<div class="swiper video-slider"> <div class="swiper-wrapper"> <div class="swiper-slide"> <video controls loop muted autoplay> <source src="imgs/1.mp4" type="video/mp4" /> </video> </div> <div class="swiper-slide"> <video controls loop muted autoplay> <source src="imgs/2.mp4" type="video/mp4" /> </video> </div> <div class="swiper-slide"> <video controls loop muted autoplay> <source src="imgs/3.mp4" type="video/mp4" /> </video> </div> </div> <div class="swiper-button-prev"></div> <div class="swiper-button-next"></div> </div>
.video-slider { width: 100%; height: 500px; } .video-slider iframe, .video-slider video { width: 100%; height: 100%; border: 0; }
function stopAll() { document.querySelectorAll(".video-slider video").forEach((v) => { v.pause(); v.currentTime = 0; }); }
function playCur(sw) { const v = sw.slides[sw.activeIndex].querySelector("video"); if (v) v.play(); }
const vs = new Swiper(".video-slider", { autoplay: { delay: 5000 }, loop: true, navigation: { nextEl: ".swiper-button-next", prevEl: ".swiper-button-prev", }, on: { slideChange: function () { stopAll(); playCur(this); }, init: function () { playCur(this); }, }, });
- stopAll() - 모든 비디오를 정지하고 처음으로 되돌림
- playCur(sw) - 현재 활성화된 슬라이드의 비디오만 재생
- slideChange 이벤트 - 슬라이드가 바뀔 때마다: 모든 비디오 정지, 새로운 슬라이드의 비디오만 재생
- init 이벤트 - 페이지 로드 시 첫 번째 슬라이드 비디오 자동 재생
- autoplay - 5초마다 자동으로 다음 슬라이드로 이동
9. 수직 슬라이더
<div class="swiper vertical"> <div class="swiper-wrapper"> <div class="swiper-slide">1</div> <div class="swiper-slide">2</div> <div class="swiper-slide">3</div> </div> <div class="swiper-pagination"></div></div>
<style> .vertical { width: 100%; height: 100vh; }</style>
<script> const vertical = new Swiper('.vertical', { direction: 'vertical', // 수직 방향 slidesPerView: 1, mousewheel: true, // 마우스 휠로 이동 pagination: { el: '.swiper-pagination', clickable: true } });</script>
10. 페이지네이션 종류
10.1. 기본 (bullets)
pagination: { el: '.swiper-pagination', clickable: true}
10.2. 숫자형
pagination: { el: '.swiper-pagination', clickable: true, renderBullet: function(index, className) { return '<span class="' + className + '">' + (index + 1) + '</span>'; }}
10.3. 프로그래스바
pagination: { el: '.swiper-pagination', type: 'progressbar'}
10.4. 분수형
pagination: { el: '.swiper-pagination', type: 'fraction'}
11. 이벤트 활용
const swiper = new Swiper('.swiper', { on: { // 초기화 완료 init: function() { console.log('Swiper 초기화 완료'); }, // 슬라이드 변경 slideChange: function() { console.log('현재 슬라이드:', this.realIndex); }, // 슬라이드 변경 완료 slideChangeTransitionEnd: function() { console.log('전환 완료'); } }});
12. 참고 링크