섬네일 갤러리 구현 / Gallery with Thumbnail Slider / Swiper - Thumbs gallery

준비하기


CDN 연결

섬네일형 갤러리 생성을 위해 캐러셀 플러그인 코어 소스를 연결합니다. 본 글에서는 Swiper API 를 사용합니다. 아래 코드를 head 태그 사이에 붙여 넣어줍니다.

<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/swiper@7/swiper-bundle.min.css" />

<!-- JS -->
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>

마크업하기


총 두 개의 swiper 마크업이 필요합니다. 이미지를 크게 보여줄 메인 슬라이드와 섬네일로 사용할 섬네일 슬라이드를 각각 마크업합니다.

<div class="gallery-box">
    <!-- main slider -->
    <div class="gallery-main-box gallery-main-swiper swiper-container">
        <div class="swiper-wrapper">
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932761-33a8f83e-f88b-468f-9b8c-d999ef3a7b71.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932791-367654ba-bae0-422b-a468-9a636359fcec.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932804-842f1dd9-dd65-4d30-8831-cf17a0ade596.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932809-ec3231be-03c8-48b7-a89c-9257f2d136e2.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932832-3ece527c-b984-418e-8181-2e8ff83b02a2.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932834-1bfb63a6-209f-4141-ab3c-bf2806ac7c53.jpg" alt="Sample"></p>
            </div>
        </div>
        <div class="control-wrap">
            <div class="swiper-gallery-prev">
            </div>
            <div class="swiper-gallery-next">
            </div>
        </div>
    </div>
    <!-- // main slider -->
    <!-- thumbnail slider -->
    <div class="gallery-thumb-box gallery-thumb-swiper swiper-container">
        <div class="swiper-wrapper">
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932761-33a8f83e-f88b-468f-9b8c-d999ef3a7b71.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932791-367654ba-bae0-422b-a468-9a636359fcec.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932804-842f1dd9-dd65-4d30-8831-cf17a0ade596.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932809-ec3231be-03c8-48b7-a89c-9257f2d136e2.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932832-3ece527c-b984-418e-8181-2e8ff83b02a2.jpg" alt="Sample"></p>
            </div>
            <div class="swiper-slide">
                <p class="info-img object-fit"><img src="https://user-images.githubusercontent.com/33821863/148932834-1bfb63a6-209f-4141-ab3c-bf2806ac7c53.jpg" alt="Sample"></p>
            </div>
        </div>
    </div>
    <!-- // thumbnail slider -->
</div>

CSS


기본 코어 소스의 CSS 덕분에 사용하는 데에 크게 문제가 없지만, 원하는 디자인이 있다면 CSS를 추가해줍니다.

.gallery-box{margin:0 auto;max-width:800px;}

.gallery-box .gallery-main-box{padding:0 0 10px;}
.gallery-box .gallery-main-box .swiper-slide .info-img{position:relative;padding:0 0 62.5%;height:0;box-sizing:border-box;}
.gallery-box .gallery-main-box .swiper-slide .info-img img{position:absolute;}

.gallery-box .gallery-main-box .control-wrap{position:absolute;top:50%;left:0;z-index:20;width:100%;box-sizing:border-box;}
.gallery-box .gallery-main-box .control-wrap > div{position:absolute;top:50%;width:60px;height:60px;background-color:rgba(0,0,0,0.5);background-repeat:no-repeat;background-position:center center;text-indent:-99999px;transform:translateY(-50%);-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%);cursor:pointer;}
.gallery-box .gallery-main-box .control-wrap .swiper-gallery-prev{left:0;background-image:url(https://user-images.githubusercontent.com/33821863/148932372-4b639bb5-17b1-4884-b18d-3445b530701b.png);}
.gallery-box .gallery-main-box .control-wrap .swiper-gallery-next{right:0;background-image:url(https://user-images.githubusercontent.com/33821863/148932378-7ff3135f-0dd9-4d6d-abd1-376acbf577d4.png);}
.gallery-box .gallery-main-box .control-wrap > div:hover{background-color:#000;}

.gallery-box .gallery-thumb-box .swiper-slide{cursor:pointer;}
.gallery-box .gallery-thumb-box .swiper-slide.swiper-slide-active{position:relative;}
.gallery-box .gallery-thumb-box .swiper-slide.swiper-slide-active:after{content:'';display:block;position:absolute;top:0;left:0;width:100%;height:100%;border:2px solid #1976d2;box-sizing:border-box;} 
.gallery-box .gallery-thumb-box .swiper-slide .info-img{position:relative;padding:0 0 62.5%;height:0;box-sizing:border-box;}
.gallery-box .gallery-thumb-box .swiper-slide .info-img img{position:absolute;}

.object-fit img{width:100%;height:100%;object-fit:cover;}

@media screen and (max-width:768px) {
    .gallery-box .gallery-main-box .control-wrap > div{width:40px;height:40px;background-size:7px;}
}

JS


Swiper 실행하기

swiper 마크업을 두 개 했으므로 실행도 두 번 해줍니다.

$(document).ready(function() {
    // main slider 실행
    var thumbSwiper = new Swiper('.gallery-thumb-swiper', {
        spaceBetween: 10,
        watchSlidesProgress: true,
        slideToClickedSlide: true,
        loop: true,
        breakpoints: {
            1024: {
                slidesPerView: 5, // 한 화면에 보일 섬네일 개수
                loopedSlides: 5 // 위 섬네일 개수와 동일한 수치 설정
            },
            768: {
                slidesPerView: 3.5,
                loopedSlides: 3.5
            },
            480: {
                slidesPerView: 2.5,
                loopedSlides: 2.5
            }
        }
    });
    // main slider 실행
    var mainSwiper = new Swiper('.gallery-main-swiper', {
        effect: 'fade',
        spaceBetween: 10,
        allowTouchMove: false,
        loop: true,
        navigation: {
            nextEl: '.swiper-gallery-next',
            prevEl: '.swiper-gallery-prev'
        },
        breakpoints: {
            1024: {
                loopedSlides: 5
            },
            768: {
                loopedSlides: 3.5
            },
            480: {
                loopedSlides: 2.5
            }
        }
    })
})

슬라이드 연결하기

이제 두 개의 슬라이드가 하나처럼 움직이도록 연결해줍니다. 두 슬라이드가 서로를 바라보도록 swiper 실행문 바로 아래에 다음 소스를 추가합니다.

mainSwiper.controller.control = thumbSwiper;
thumbSwiper.controller.control = mainSwiper;

완성입니다! 🎉

Demo

See the Pen swiper custom thumbnail gallery by likeanewstar (@likeanewstar) on CodePen.

참고