This post contains a total of 5+ Vue Carousel Examples with Source Code. All these Carousels are made using Vue.
You can use the source code of these examples with credits to the original owner.
Related Posts
Vue Carousel Examples
1. Vue Carousel
Made by Florence Bolsée. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<style>
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
h2 {
font-size: 24px;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
text-align: center;
max-width: 600px;
margin: 0 auto;
}
.carousel {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.slide {
flex: 0 0 100%;
display: flex;
justify-content: center;
padding: 50px 0;
transition: all .3s;
background: #ddd;
margin: 20px 0;
}
.carousel-controls__button {
cursor: pointer;
background: tomato;
border: 0;
color: #fff;
border-radius: 3px;
padding: 5px 10px;
font-size: 18px;
}
</style>
</head>
<body>
<div id="app">
<h2>Carousel with Vue.js</h2>
<div class="carousel-container">
<transition-group class='carousel' tag="div">
<div v-for="slide in slides" class='slide' :key="slide.id">
<h4> {{ slide.title }} </h4>
</div>
</transition-group>
<div class='carousel-controls'>
<button class='carousel-controls__button' @click="previous"><</button>
<button class='carousel-controls__button' @click="next">></button>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js'></script>
<script>
new Vue({
el: "#app",
data: {
slides: [
{
title: 'Slide 1',
id: 1 },
{
title: 'Slide 2',
id: 2 },
{
title: 'Slide 3',
id: 3 },
{
title: 'Slide 4',
id: 4 },
{
title: 'Slide 5',
id: 5 }] },
methods: {
next() {
const first = this.slides.shift();
this.slides = this.slides.concat(first);
},
previous() {
const last = this.slides.pop();
this.slides = [last].concat(this.slides);
} } });
</script>
</body>
</html>
2. Vue carousel with Animation
Made by SparoSpace. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>
<link rel='stylesheet' href='https://fonts.googleapis.com/earlyaccess/cwtexhei.css.css'>
<style>
* {
font-family: "cwTeXHei", serif;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #1c1c1c;
margin: 0;
padding: 0;
}
#app {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.postarea {
width: 930px;
height: 250px;
white-space: nowrap;
}
.posts {
height: 100%;
position: relative;
transition: 0.5s;
}
.post_box {
display: inline-block;
height: 100%;
}
.post_box .cover {
width: 330px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
margin-left: 300px;
margin-right: 300px;
background-size: cover;
background-position: center center;
transition: 0.3s;
cursor: pointer;
}
.post_box .cover:hover {
width: 340px;
height: 110%;
}
.post_box .cover:hover .infos {
transform: translate(-220px, -10px);
}
.post_box .cover .infos {
color: white;
transform: translate(-200px, 0);
text-shadow: 0px 0px 30px rgba(0, 0, 0, 0.3);
transition: 0.3s;
}
.post_box .cover .infos * {
margin: 0;
}
.post_box .cover .infos h1 {
font-size: 40px;
font-weight: 400;
margin-bottom: 10px;
}
.post_box .cover .infos h5 {
background-color: white;
color: black;
padding: 4px 12px;
font-size: 20px;
font-weight: 300;
box-shadow: 0px 0px 30px rgba(0, 0, 0, 0.3);
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translate(30px, 0);
filter: saturate(0);
}
100% {
opacity: 1;
transform: translate(0px, 0);
}
}
@keyframes silceIn {
0% {
transform: translateX(-50px);
}
100% {
transform: translateX(0px);
}
}
.cur_item .cover {
animation: fadeIn 1s ease both;
}
.cur_item .infos h5 {
animation: silceIn 1s 0.1s ease;
}
.control_left, .control_right {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
border: solid 1px white;
position: fixed;
color: white;
font-size: 30px;
transition: 0.3s;
}
.control_left:hover, .control_right:hover {
background-color: white;
color: black;
}
.control_left {
left: 50px;
}
.control_right {
right: 50px;
}
</style>
</head>
<body>
<div id="app" @keyup.13.native="delta(1)">
<div class="postarea">
<div class="posts" :style="computed_left">
<div class="post_box" v-for="(w,id) in works" :class="{cur_item: id==now_index}">
<div class="cover" :style="bg_css(w.cover)">
<div class="infos">
<h1>{{w.title}}</h1>
<h5>{{w.description}}</h5>
</div>
</div>
</div>
</div>
</div>
<div class="control_left" @click="delta(-1)"><i class="fa fa-angle-left"></i></div>
<div class="control_right" @click="delta(1)"><i class="fa fa-angle-right"></i></div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js'></script>
<script>
var works = [
{
title: "在水中央",
description: "男女迷途在大海之中",
cover: "https://unsplash.it/600/400?image=1083" },
{
title: "沖泡咖啡",
description: "用最經典的濾紙沖泡",
cover: "https://unsplash.it/600/400?image=1060" },
{
title: "熊在野",
description: "孩子,這是你們的世界",
cover: "https://unsplash.it/600/400?image=1020" },
{
title: "鹿兒",
description: "可愛的小鹿",
cover: "https://unsplash.it/600/400?image=1003" },
{
title: "城堡",
description: "聳立於林中",
cover: "https://unsplash.it/600/400?image=1040" }];
var vm = new Vue({
el: "#app",
data: {
works: works,
now_index: 0,
span_width: 930 },
computed: {
computed_left: function () {
var result = {
"left": -this.now_index * this.span_width + "px" };
// console.log(result);
return result;
} },
methods: {
delta(d) {
this.now_index =
(this.now_index + d + this.works.length) % this.works.length;
},
bg_css(url) {
return {
"background-image": "url(" + url + ")" };
} } });
</script>
</body>
</html>
3. Simple Vue carousel
Made by Luke Taylor. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
margin: 0;
}
.carousel {
background-color: #ddd;
height: 100vh;
position: relative;
}
.carousel > div {
background-color: #000;
color: #fff;
width: 10vw;
height: 10vw;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
line-height: 10vw;
font-family: sans-serif;
font-size: 6vw;
}
.carousel .dots {
position: absolute;
bottom: 0;
padding: 5%;
width: 100%;
}
.carousel .dots .dot {
background-color: #000;
}
</style>
</head>
<body>
<div id="app">
<carousel>
<!-- Numbers 1-10 in divs -->
<div v-for="i in [...Array(10).keys()]">{{i+1}}</div>
</carousel>
</div>
<script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-1b93190375e9ccc259df3a57c1abc0e64599724ae30d7ea4c6877eb615f89387.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.min.js'></script>
<script>
Vue.component('carousel-dot', {
template: '<div class="dot" v-bind:style="style"></div>',
data: () => ({ selected: false }),
computed: {
style: () => ({
opacity: this.selected ? 1 : 0.5 }) } });
Vue.component('carousel-dots', {
props: ['numDots'],
template: '<div class="dots"><carousel-dot v-for="i in numDots"></carousel-dot></div>' });
// Items displayed in the carousel
Vue.component('carousel-item', {
template: '<div class="carousel-item" v-bind:style="style" v-on:click="centerSelf"><slot></slot></div>',
data: () => ({
zIndex: 0,
xtrans: 0,
ytrans: 0,
scale: 1,
opacity: 1 }),
computed: {
style() {
return {
transition: 'transform 0.5s, opacity 0.5s',
transform: this.transform,
'z-index': this.zIndex,
opacity: this.opacity };
},
transform() {
return [
`translate(${this.xtrans - 50}%, ${this.ytrans - 50}%)`,
`scale(${this.scale})`].
join(' ');
} },
methods: {
centerSelf() {
this.$parent.arrange(this.$parent.$children.indexOf(this));
} } });
// Carousel component
Vue.component('carousel', {
// Render function wraps all children in carousel-item components
render(createElement) {
return createElement(
'div',
{
class: 'carousel',
ref: 'carousel' },
this.$slots.default.map(el => createElement('carousel-item', [el])));
},
data: () => ({}),
// Begin by centering the first element in the carousel
mounted() {this.arrange(0);},
methods: {
// http://stackoverflow.com/q/4467539
_mod: (n, m) => (n % m + m) % m,
// Distribute elements so that they align with the selected elemenent in the center
arrange(centerIndex) {
const center = this.$children[centerIndex];
const half = (this.$children.length - 1) / 2;
// Items that will be displayed to the left of the item at centerIndex
const before = [];
// Keep adding items before until half the non-centerIndex items have been added
for (let i = centerIndex - 1; before.length < half; i--) {if (window.CP.shouldStopExecution(0)) break;
// this._mod is used to emulate a toroidal array by mapping elements below index 0 or beyond
// the max index to elements in the valid array range
before.push(this.$children[this._mod(i, this.$children.length)]);
}
// Items that will be displayed to the right of the item at centerIndex
window.CP.exitedLoop(0);const after = [];
for (let i = centerIndex + 1; after.length < this.$children.length - before.length - 1; i++) {if (window.CP.shouldStopExecution(1)) break;
after.push(this.$children[this._mod(i, this.$children.length)]);
}
// Position all elements
// Position center
window.CP.exitedLoop(1);center.xtrans = 0;
center.scale = 1;
center.opacity = 1;
center.zIndex = Math.max(before.length, after.length) + 1;
// Position elements to left and right
[before, after].forEach((list, listIndex) => {
// Tracks the amount by which the parent was translated
let parentTrans = 0;
// Apply styles for each element in selected list
list.forEach((item, i) => {
// Set size
item.scale = 0.8 ** (i + 1);
// Set x offset. Negative for before, positive for after
const absolute = 105 * item.scale * 1.125 + parentTrans;
parentTrans = absolute; // Update how much parent was translated by
item.xtrans = (listIndex == 0 ? -1 : 1) * absolute;
// Set opacity
item.opacity = Math.max(1 - 0.25 * (i / 2 + 1) ** 2, 0);
// Set z-index
item.zIndex = Math.max(before.length, after.length) - i;
});
});
} } });
const app = new Vue({
el: '#app' });
</script>
</body>
</html>
4. Vue Carousel Bootstrap Vue Cards
Made by David Hutto. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/css/bootstrap.min.css'>
<link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/bootstrap-vue.css'>
<style>
.row{
margin-top:100px;
}
</style>
</head>
<body>
<div id="app">
<b-container>
<b-row>
<b-col cols="12">
<carousel :perPage="3">
<slide class="p-2">
<b-card title="Card Title 1" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
<b-card-text>
Some quick example text to build on the card title and make up the bulk of the card's content.
</b-card-text>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
</slide>
<slide class="p-2">
<b-card title="Card Title 2" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
<b-card-text>
Some quick example text to build on the card title and make up the bulk of the card's content.
</b-card-text>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
</slide>
<slide class="p-2">
<b-card title="Card Title 3" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
<b-card-text>
Some quick example text to build on the card title and make up the bulk of the card's content.
</b-card-text>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
</slide>
<slide class="p-2">
<b-card title="Card Title 4" img-src="https://picsum.photos/600/300/?image=25" img-alt="Image" img-top tag="article">
<b-card-text>
Some quick example text to build on the card title and make up the bulk of the card's content.
</b-card-text>
<b-button href="#" variant="primary">Go somewhere</b-button>
</b-card>
</slide>
</carousel>
</b-col>
</b-row>
</b-container>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js'></script>
<script src='https://unpkg.com/[email protected]/dist/bootstrap-vue.js'></script>
<script src='https://ssense.github.io/vue-carousel/js/vue-carousel.min.js'></script>
<script>
new Vue({
el: "#app",
components: {
'carousel': VueCarousel.Carousel,
'slide': VueCarousel.Slide },
data: {
slide: 0,
sliding: null },
methods: {
onSlideStart(slide) {
this.sliding = true;
},
onSlideEnd(slide) {
this.sliding = false;
} } });
</script>
</body>
</html>
5. The simplest Vue carousel
Made by Ada. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<style>
@import url("https://fonts.googleapis.com/css?family=Crimson+Text");
/* FADE IN */
.fade-enter-active {
transition: opacity 1s;
}
.fade-enter {
opacity: 0;
}
/* GO TO NEXT SLIDE */
.slide-next-enter-active,
.slide-next-leave-active {
transition: transform 0.5s ease-in-out;
}
.slide-next-enter {
transform: translate(100%);
}
.slide-next-leave-to {
transform: translate(-100%);
}
/* GO TO PREVIOUS SLIDE */
.slide-prev-enter-active,
.slide-prev-leave-active {
transition: transform 0.5s ease-in-out;
}
.slide-prev-enter {
transform: translate(-100%);
}
.slide-prev-leave-to {
transform: translate(100%);
}
/* SLIDES CLASSES */
.blue {
background: #4a69bd;
}
.red {
background: #e55039;
}
.yellow {
background: #f6b93b;
}
/* SLIDER STYLES */
body {
overflow: hidden;
margin: 0;
font-size: 50px;
font-family: "Crimson Text", sans-serif;
color: #fff;
}
#slider {
width: 100%;
height: 100vh;
position: relative;
}
.slide {
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}
.btn {
z-index: 10;
cursor: pointer;
border: 3px solid #fff;
display: flex;
justify-content: center;
align-items: center;
width: 70px;
height: 70px;
position: absolute;
top: calc(50% - 35px);
left: 1%;
transition: transform 0.3s ease-in-out;
user-select: none;
}
.btn-next {
left: auto;
right: 1%;
}
.btn:hover {
transform: scale(1.1);
}
</style>
</head>
<body>
<div id="slider">
<transition-group tag="div" :name="transitionName" class="slides-group">
<div v-if="show" :key="current" class="slide" :class="slides[current].className">
<p>I'm {{slides[current].className}}!</p>
</div>
</transition-group>
<div class="btn btn-prev" aria-label="Previous slide" @click="slide(-1)">
❮
</div>
<div class="btn btn-next" aria-label="Next slide" @click="slide(1)">
❯
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js'></script>
<script>
var slider = new Vue({
el: "#slider",
data: {
current: 0,
direction: 1,
transitionName: "fade",
show: false,
slides: [
{ className: "blue" },
{ className: "red" },
{ className: "yellow" }] },
methods: {
slide(dir) {
this.direction = dir;
dir === 1 ?
this.transitionName = "slide-next" :
this.transitionName = "slide-prev";
var len = this.slides.length;
this.current = (this.current + dir % len + len) % len;
} },
mounted() {
this.show = true;
} });
</script>
</body>
</html>
6. Slider carousel
Made by Dima. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#app {
display: flex;
height: 100vh;
}
.CROP {
height: 96px;
overflow: hidden;
width: 100%;
padding: 8px 0;
}
.Carousel {
margin: auto;
width: 480px;
}
.Carousel_chunk {
display: flex;
justify-content: space-between;
align-items: center;
}
.Carousel .currImg {
cursor: pointer;
}
.chunk_item {
height: 80px;
margin: 2px;
padding: 2px;
border: 1px solid transparent;
cursor: pointer;
}
.chunk_item:hover {
border: 1px solid #2196f3;
}
.chunk_item.CURR {
background: #ffd700;
outline: 2px solid #000;
border-color: transparent;
}
.chunk_item img {
display: inline-block;
height: 100%;
}
.Carousel-controls {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
display: flex;
justify-content: space-between;
align-items: center;
}
.Carousel-controls_dot,
.Carousel-controls svg {
cursor: pointer;
}
.Carousel-controls svg:hover {
fill: #ff0;
}
.Carousel-controls_dot {
border-radius: 50%;
width: 1.2rem;
line-height: 1.2rem;
text-align: center;
background-color: #222;
font-family: sans-serif;
font-size: 0.5em;
color: #fff;
}
.Carousel-controls_dot:hover {
transform: scale(1.4, 1.4);
}
.Carousel-controls_dot.CURR {
cursor: none;
background-color: #ffd700;
color: #000;
font-weight: bold;
transform: scale(1.4, 1.4);
}
.slide_next-enter-active,
.slide_prev-enter-active {
transition: transform 0.3s;
}
.slide_next-enter {
transform: translateX(100%);
}
.slide_prev-enter {
transform: translateX(-100%);
}
.lightbox {
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #616574 url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='80' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round' stroke='gold'><line x1='4' y1='4' x2='6' y2='6' /><line x1='6' y1='4' x2='4' y2='6' /></svg>") top right no-repeat;
display: flex;
}
.lightbox img {
cursor: default;
margin: auto;
max-width: 90%;
max-height: 100%;
}
.prev,
.next {
position: absolute;
top: 50%;
width: 40px;
height: 60px;
margin: -30px 4% 0;
background: #444 url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='gold' d='M6,2 L4,5 L6,8'/></svg>") center/cover no-repeat;
}
.prev:hover,
.next:hover {
background-color: #222;
}
.next {
right: 0;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10' fill='none' stroke-linecap='round' stroke-linejoin='round'><path stroke='gold' d='M4,2 L6,5 L4,8'/></svg>");
}
</style>
</head>
<body>
<div id="app">
<div class="Carousel">
<div class="lightbox" v-show="lightboxActive" @click.self="lightboxActive=false; currLightboxImg = currImgIdx"><img :src="imgList[currLightboxImg].src"/>
<div class="prev" @click="goToImg(currLightboxImg-1)"></div>
<div class="next" @click="goToImg(currLightboxImg+1)"></div>
</div><img class="currImg" :src="imgList[currImgIdx].src" @click="lightboxActive=true"/>
<transition-group class="CROP" :name="transition_name" tag="div">
<div class="Carousel_chunk" v-for="(chunk,i) in arrChunk" v-show="currSlide == i" :key="i">
<div class="chunk_item" v-for="(item,j) in chunk" :key="j" @click="currImgIdx = j+(i*chunkSize)" :class="{CURR: item.src == imgList[currImgIdx].src}"><img :src="item.src"/></div>
</div>
</transition-group>
<div class="Carousel-controls">
<svg @click="prev" width="48" height="48" viewBox="0 0 24 24" fill="gold" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 8 8 12 12 16"></polyline>
<line x1="16" y1="12" x2="8" y2="12"></line>
</svg>
<div class="Carousel-controls_dot" v-for="(dot, i) in arrChunk" :class="{CURR : currSlide == i}" @click="goToChunk(i)">{{i+1}}</div>
<svg @click="next" width="48" height="48" viewBox="0 0 24 24" fill="gold" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12 16 16 12 12 8"></polyline>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
</div>
</div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js'></script>
<script>
const imgList = Array.from({ length: 33 }, (v, i) => ({ src: `//raw.githubusercontent.com/codrops/HoverEffectIdeas/master/img/${i + 1}.jpg` }));
const vm = new Vue({
el: "#app",
data() {
return {
chunkSize: 4,
imgList: imgList,
currSlide: 0,
currImgIdx: 15,
transition_name: "slide_next",
lightboxActive: false,
currLightboxImg: 15 };
},
watch: {
currImgIdx(newVal) {
this.currLightboxImg = newVal;
} },
computed: {
arrChunk() {
return Array.
from({ length: Math.ceil(this.imgList.length / this.chunkSize) }, (v, i) =>
this.imgList.slice(i * this.chunkSize, i * this.chunkSize + this.chunkSize));
} },
methods: {
prev() {
this.transition_name = "slide_prev";
this.currSlide = this.currSlide == 0 ? this.arrChunk.length - 1 : this.currSlide - 1;
},
next() {
this.transition_name = "slide_next";
this.currSlide = this.currSlide == this.arrChunk.length - 1 ? 0 : this.currSlide + 1;
},
goToImg(n) {
this.currLightboxImg = n < 0 ? this.imgList.length - 1 : n % this.imgList.length;
},
goToChunk(idx) {
this.transition_name = idx < this.currSlide ? "slide_prev" : "slide_next";
this.currSlide = idx;
} } });
</script>
</body>
</html>