Because images can take a few seconds to load (or not at all), use the image
container to specify a precisely sized container so that your layout isn't broken because of image loading or image errors - Bulma image.
Carousel
A Slideshow for cycling images in confined spaces
<template>
<b-carousel>
<b-carousel-item v-for="(carousel, i) in carousels" :key="i">
<section :class="`hero is-medium is-${carousel.color}`">
<div class="hero-body has-text-centered">
<h1 class="title">{{carousel.text}}</h1>
</div>
</section>
</b-carousel-item>
</b-carousel>
</template>
<script>
export default {
data(){
return {
carousels: [
{ text: 'Slide 1', color: 'primary' },
{ text: 'Slide 2', color: 'info' },
{ text: 'Slide 3', color: 'success' },
{ text: 'Slide 4', color: 'warning' },
{ text: 'Slide 5', color: 'danger' }
]
}
}
}
</script>
# Custom
Slide 1
A link that goes to arrow
<template>
<section>
<div class="example-component">
<b-field grouped group-multiline>
<div class="control">
<b-switch v-model="autoPlay">Autoplay</b-switch>
</div>
<div class="control">
<b-switch v-model="pauseHover" :disabled="!autoPlay">Pause on hover</b-switch>
</div>
<div class="control">
<b-switch v-model="pauseInfo" :disabled="!pauseHover">Pause info</b-switch>
</div>
<div class="control">
<b-switch v-model="drag">Drag event</b-switch>
</div>
<div class="control">
<b-switch v-model="repeat" :disabled="!autoPlay">Repeat</b-switch>
</div>
</b-field>
<b-field grouped group-multiline>
<b-field label="Value">
<b-numberinput v-model="carousel" min="0" :max="carousels.length - 1" controls-position="compact"/>
</b-field>
<b-field label="Interval">
<b-numberinput v-model="interval" min="0" controls-position="compact" step="1000" :disabled="!autoPlay"/>
</b-field>
<b-field label="Animated">
<b-field>
<b-radio-button v-model="animated"
native-value="fade">
Fade
</b-radio-button>
<b-radio-button v-model="animated"
native-value="slide">
Slide
</b-radio-button>
</b-field>
</b-field>
<b-field label="Pause Type">
<b-select v-model="pauseType" :disabled="!pauseInfo">
<option value="is-white">is-white</option>
<option value="is-dark">is-dark</option>
<option value="is-primary">is-primary</option>
</b-select>
</b-field>
</b-field>
</div>
<b-carousel
v-model="carousel"
:animated="animated"
:has-drag="drag"
:autoplay="autoPlay"
:pause-hover="pauseHover"
:pause-info="pauseInfo"
:pause-info-type="pauseType"
:interval="interval"
:repeat="repeat"
@change="info($event)">
<b-carousel-item v-for="(carousel, i) in carousels" :key="i">
<section :class="`hero is-medium is-${carousel.color} is-bold`">
<div class="hero-body has-text-centered">
<h1 class="title">{{carousel.title}}</h1>
<b-input :placeholder="carousel.title"></b-input>
<p>A link that <a href="#arrow">goes to arrow</a></p>
</div>
</section>
</b-carousel-item>
</b-carousel>
</section>
</template>
<script>
export default {
data() {
return {
carousel: 0,
animated: 'fade',
drag: false,
autoPlay: false,
pauseHover: false,
pauseInfo: false,
repeat: false,
pauseType: 'is-primary',
interval: 3000,
carousels: [
{ title: 'Slide 1', color: 'dark' },
{ title: 'Slide 2', color: 'primary' },
{ title: 'Slide 3', color: 'info' },
{ title: 'Slide 4', color: 'success' },
{ title: 'Slide 5', color: 'warning' },
{ title: 'Slide 6', color: 'danger' }
]
}
},
methods: {
info(value) {
this.carousel = value
this.$buefy.toast.open({
message: `This Slide ${value} !`,
type: 'is-info'
})
}
}
}
</script>
# Arrow
<template>
<section>
<div class="example-component">
<b-field grouped group-multiline>
<div class="control">
<b-switch v-model="arrow"><strong>Arrow</strong></b-switch>
</div>
<div class="control">
<b-switch v-model="arrowBoth" :disabled="!arrow">Both</b-switch>
</div>
<div class="control">
<b-switch v-model="arrowHover" :disabled="!arrow">Hover</b-switch>
</div>
</b-field>
<b-field grouped group-multiline>
<b-field label="Icon Pack">
<b-input v-model="iconPack" placeholder="e.g. mdi, fa or other"/>
</b-field>
<b-field label="Icon Size">
<b-select v-model="iconSize">
<option value="">default</option>
<option value="is-small">is-small</option>
<option value="is-medium">is-medium</option>
<option value="is-large">is-large</option>
</b-select>
</b-field>
<b-field label="Icon Prev">
<b-input v-model="iconPrev"/>
</b-field>
<b-field label="Icon Next">
<b-input v-model="iconNext"/>
</b-field>
</b-field>
</div>
<b-carousel
:arrow="arrow"
:repeat="arrowBoth"
:arrow-hover="arrowHover"
:icon-pack="iconPack"
:icon-prev="iconPrev"
:icon-next="iconNext"
:icon-size="iconSize">
<b-carousel-item v-for="(carousel, i) in carousels" :key="i">
<section :class="`hero is-medium is-${carousel.color}`">
<div class="hero-body has-text-centered">
<h1 class="title">{{carousel.title}}</h1>
</div>
</section>
</b-carousel-item>
</b-carousel>
</section>
</template>
<script>
export default {
data() {
return {
arrow: true,
arrowBoth: false,
arrowHover: false,
iconPack: 'mdi',
iconPrev: 'arrow-left',
iconNext: 'arrow-right',
iconSize: '',
carousels: [
{ title: 'Slide 1', color: 'info' },
{ title: 'Slide 2', color: 'success' },
{ title: 'Slide 3', color: 'warning' },
{ title: 'Slide 4', color: 'danger' }
]
}
}
}
</script>
# Progress
<template>
<section>
<div class="example-component">
<b-field grouped group-multiline>
<div class="control">
<b-switch v-model="progress"><strong>Progress</strong></b-switch>
</div>
<b-field label="Type" label-position="on-border">
<b-select v-model="progressType" :disabled="!progress">
<option value="is-primary">is-primary</option>
<option value="is-info">is-info</option>
<option value="is-success">is-success</option>
<option value="is-warning">is-warning</option>
<option value="is-danger">is-danger</option>
<option value="is-white">is-white</option>
<option value="is-light">is-light</option>
<option value="is-dark">is-dark</option>
</b-select>
</b-field>
</b-field>
</div>
<b-carousel
:progress="progress"
:progress-type="progressType">
<b-carousel-item v-for="(carousel, i) in carousels" :key="i">
<section :class="`hero is-medium is-${carousel.color}`">
<div class="hero-body has-text-centered">
<h1 class="title">{{carousel.title}}</h1>
</div>
</section>
</b-carousel-item>
</b-carousel>
</section>
</template>
<script>
export default {
data() {
return {
progress: true,
progressType: 'is-primary',
carousels: [
{ title: 'Slide 1', color: 'grey' },
{ title: 'Slide 2', color: 'dark' },
{ title: 'Slide 3', color: 'primary' },
{ title: 'Slide 4', color: 'info' }
]
}
}
}
</script>
# Indicator
<template>
<section>
<div class="example-component">
<b-field grouped group-multiline>
<div class="control">
<b-switch v-model="indicator"><strong>Indicator</strong></b-switch>
</div>
<div class="control">
<b-switch v-model="indicatorBackground" :disabled="!indicator">Background</b-switch>
</div>
<div class="control">
<b-switch v-model="indicatorInside" :disabled="!indicator">Inside</b-switch>
</div>
</b-field>
<b-field grouped group-multiline>
<b-field label="Position" :disabled="!indicator">
<b-select v-model="indicatorPosition">
<option value="is-bottom">is-bottom</option>
<option value="is-top">is-top</option>
</b-select>
</b-field>
<b-field label="Mode">
<b-field>
<b-radio-button v-model="indicatorMode" native-value="click" :disabled="!indicator">
<span>Click</span>
</b-radio-button>
<b-radio-button v-model="indicatorMode" native-value="hover" :disabled="!indicator">
<span>Hover</span>
</b-radio-button>
</b-field>
</b-field>
<b-field label="Style">
<b-field>
<b-radio-button v-model="indicatorStyle" native-value="is-boxes" :disabled="!indicator">
<span>Boxes</span>
</b-radio-button>
<b-radio-button v-model="indicatorStyle" native-value="is-dots" :disabled="!indicator">
<span>Dots</span>
</b-radio-button>
<b-radio-button v-model="indicatorStyle" native-value="is-lines" :disabled="!indicator">
<span>Lines</span>
</b-radio-button>
</b-field>
</b-field>
</b-field>
</div>
<b-carousel
:indicator="indicator"
:indicator-background="indicatorBackground"
:indicator-inside="indicatorInside"
:indicator-mode="indicatorMode"
:indicator-position="indicatorPosition"
:indicator-style="indicatorStyle">
<b-carousel-item v-for="(carousel, i) in carousels" :key="i">
<section :class="`hero is-medium is-${carousel.color}`">
<div class="hero-body has-text-centered">
<h1 class="title">{{carousel.title}}</h1>
</div>
</section>
</b-carousel-item>
</b-carousel>
</section>
</template>
<script>
export default {
data() {
return {
indicator: true,
indicatorBackground: true,
indicatorInside: true,
indicatorMode: 'hover',
indicatorPosition: 'is-top',
indicatorStyle: 'is-lines',
carousels: [
{ title: 'Slide 1', color: 'info' },
{ title: 'Slide 2', color: 'success' },
{ title: 'Slide 3', color: 'warning' },
{ title: 'Slide 4', color: 'danger' }
]
}
}
}
</script>
Some source by Picsum and Images from Unsplash.
# Custom Indicators
When there are more than 6 images, add
If you want custom indicator to stay big, use
indicator-custom
If you want custom indicator to stay big, use
is-medium
on indicator-custom-size
<template>
<b-carousel :indicator-inside="false">
<b-carousel-item v-for="(item, i) in 6" :key="i">
<b-image class="image" :src="getImgUrl(i)"></b-image>
</b-carousel-item>
<template #indicators="props">
<b-image class="al image" :src="getImgUrl(props.i)" :title="props.i"></b-image>
</template>
</b-carousel>
</template>
<script>
export default {
methods: {
getImgUrl(value) {
return `https://picsum.photos/id/43${value}/1230/500`
}
}
}
</script>
<style>
.is-active .al img {
filter: grayscale(0%);
}
.al img {
filter: grayscale(100%);
}
</style>
# Switch like a gallery
You may also want to add the is-clipped
modifier to a containing element (usually html
) to stop scroll overflow.
<template>
<b-carousel :autoplay="false" indicator-custom :indicator-inside="false" :overlay="gallery" @click="switchGallery(true)">
<b-carousel-item v-for="(item, i) in 20" :key="i">
<a class="image ">
<img :src="getImgUrl(i)">
</a>
</b-carousel-item>
<span v-if="gallery" @click="switchGallery(false)" class="modal-close is-large"/>
<template #indicators="props">
<figure class="al image" :draggable="false">
<img :draggable="false" :src="getImgUrl(props.i)" :title="props.i">
</figure>
</template>
</b-carousel>
</template>
<script>
export default {
data() {
return {
gallery: false
}
},
methods: {
getImgUrl(value) {
value += 50
return `https://picsum.photos/id/10${value}/1230/500`
},
switchGallery(value) {
this.gallery = value
if (value) {
return document.documentElement.classList.add('is-clipped')
} else {
return document.documentElement.classList.remove('is-clipped')
}
}
}
}
</script>
<style>
.is-active .al img {
border: 1px solid #fff;
filter: grayscale(0%);
}
.al img {
border: 1px solid transparent;
filter: grayscale(100%);
}
</style>
# Carousel List
An imposing carousel list to showcase viewer something.
<template>
<section>
<div class="example-component">
<b-field grouped group-multiline>
<div class="control">
<b-switch v-model="arrow">Arrow</b-switch>
</div>
<div class="control">
<b-switch v-model="arrowHover" :disabled="!arrow">Arrow on hover</b-switch>
</div>
<div class="control">
<b-switch v-model="drag">Drag event</b-switch>
</div>
<div class="control">
<b-switch v-model="gray" :disabled="opacity">Grayscale</b-switch>
</div>
<div class="control">
<b-switch v-model="opacity" :disabled="gray">Opacity</b-switch>
</div>
<div class="control">
<b-switch v-model="repeat">Repeat</b-switch>
</div>
</b-field>
<b-field grouped group-multiline>
<b-field label="Value">
<b-numberinput v-model="values" min="0" :max="items.length - 1" controls-position="compact"/>
</b-field>
<b-field label="Items to Show">
<b-numberinput v-model="perList" min="1" :max="items.length" controls-position="compact"/>
</b-field>
<b-field label="Items to List">
<b-numberinput v-model="increment" min="1" :max="items.length - 1" controls-position="compact"/>
</b-field>
</b-field>
</div>
<b-carousel-list
v-model="values"
:data="items"
:arrow="arrow"
:arrow-hover="arrowHover"
:items-to-show="perList"
:items-to-list="increment"
:repeat="repeat"
:has-drag="drag"
:has-grayscale="gray"
:has-opacity="opacity" />
</section>
</template>
<script>
export default {
data() {
return {
arrow: true,
arrowHover: true,
drag: true,
gray: false,
opacity: false,
values: 1,
perList: 4,
increment: 1,
repeat: false,
items: [
{
alt: 'Slide 1',
title: 'Slide 1',
image: 'https://picsummm.photos/id/0/1230/500',
srcFallback: 'https://picsum.photos/id/0/1230/500'
},
{
title: 'Slide 2',
image: 'https://picsum.photos/id/1/1230/500'
},
{
title: 'Slide 3',
image: 'https://picsum.photos/id/2/1230/500'
},
{
title: 'Slide 4',
image: 'https://picsum.photos/id/3/1230/500'
},
{
title: 'Slide 5',
image: 'https://picsum.photos/id/4/1230/500'
},
{
title: 'Slide 6',
image: 'https://picsum.photos/id/5/1230/500'
},
{
title: 'Slide 7',
image: 'https://picsum.photos/id/6/1230/500'
},
{
title: 'Slide 8',
image: 'https://picsum.photos/id/7/1230/500'
}
]
}
}
}
</script>
# Custom With Card
<template>
<b-carousel-list v-model="test" :data="items" :items-to-show="2">
<template #item="list">
<div class="card">
<div class="card-image">
<figure class="image is-5by4">
<a @click="info(list.index)"><img :src="list.image"></a>
</figure>
<b-tag type="is-danger" rounded style="position: absolute; top: 0;"><b>50%</b></b-tag>
</div>
<div class="card-content">
<div class="content">
<p class="title is-6">{{ list.title }}</p>
<p class="subtitle is-7">@johnsmith</p>
<b-field grouped >
<p class="control" v-if="list.rating">
<b-rate :value="list.rating" show-score disabled/>
</p>
<p class="control" style="margin-left: auto">
<b-button size="is-small" type="is-danger" icon-left="heart" outlined />
</p>
</b-field>
</div>
</div>
</div>
</template>
</b-carousel-list>
</template>
<script>
export default {
data() {
return {
test: 0,
items: [
{
title: 'Slide 1',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 4.4
},
{
title: 'Slide 2',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 3.5
},
{
title: 'Slide 3',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 5
},
{
title: 'Slide 4',
image: 'https://buefy.org/static/img/placeholder-1280x960.png'
},
{
title: 'Slide 5',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 5
},
{
title: 'Slide 6',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 4
},
{
title: 'Slide 7',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 2.7
},
{
title: 'Slide 8',
image: 'https://buefy.org/static/img/placeholder-1280x960.png',
rating: 1.5
}
]
}
},
methods: {
info(value) {
this.test = value
}
}
}
</script>
# Custom As indicators
With Breakpoint and Switch like a Gallery.
<template>
<b-carousel
:autoplay="false"
with-carousel-list
:indicator="false"
:overlay="gallery"
@click="switchGallery(true)">
<b-carousel-item v-for="(item, i) in items" :key="i">
<figure class="image">
<img :src="item.image">
</figure>
</b-carousel-item>
<span v-if="gallery" @click="switchGallery(false)" class="modal-close is-large"/>
<template #list="props">
<b-carousel-list
v-model="props.active"
:data="items"
v-bind="al"
@switch="props.switch($event, false)"
as-indicator />
</template>
<template #overlay>
<div class="has-text-centered has-text-white">
Hello, I'm an overlay!
</div>
</template>
</b-carousel>
</template>
<script>
export default {
data() {
return {
gallery: false,
al: {
hasGrayscale: true,
itemsToShow: 2,
breakpoints: {
768: {
hasGrayscale: false,
itemsToShow: 4
},
960: {
hasGrayscale: true,
itemsToShow: 6
}
}
},
items: [
{
title: 'Slide 1',
image: 'https://picsum.photos/id/0/1230/500'
},
{
title: 'Slide 2',
image: 'https://picsum.photos/id/1/1230/500'
},
{
title: 'Slide 3',
image: 'https://picsum.photos/id/2/1230/500'
},
{
title: 'Slide 4',
image: 'https://picsum.photos/id/3/1230/500'
},
{
title: 'Slide 5',
image: 'https://picsum.photos/id/4/1230/500'
},
{
title: 'Slide 6',
image: 'https://picsum.photos/id/5/1230/500'
},
{
title: 'Slide 7',
image: 'https://picsum.photos/id/6/1230/500'
},
{
title: 'Slide 8',
image: 'https://picsum.photos/id/7/1230/500'
}
]
}
},
methods: {
switchGallery(value) {
this.gallery = value
if (value) {
document.documentElement.classList.add('is-clipped')
} else {
document.documentElement.classList.remove('is-clipped')
}
}
}
}
</script>
# API
Carousel
Name | Description | Type | Values | Default |
---|---|---|---|---|
v-model | Binding value | Number | — | 0 |
animated | Transition effect | String | fade , slide | slide |
interval | Interval of the autoplay , in milliseconds | Number | — | 3500 |
has-drag | Toggle touch dragging, when touch not detected. Auto switch mouse dragging | Boolean | — | true |
autoplay | Whether to automatically loop the slides | Boolean | — | true |
pause-hover | Pause carousel when autoplay and mouse enter | Boolean | — | true |
pause-info | Show information about pause when autoplay and pause-hover | Boolean | — | true |
pause-info-type | Type (color) of the pause-info, optional | String | is-white , is-black , is-light ,
is-dark , is-primary , is-info , is-success ,
is-warning , is-danger ,
and any other colors you've set in the $colors list on Sass | is-white |
pause-text | Text when pause | String | — | Pause |
arrow | Display the "next" and "prev" action | Boolean | — | true |
arrow-hover | Display the "next" and "prev" action when hover, but hidden on mobile | Boolean | — | true |
repeat | Controls whether the carousel loops around at the start and end | Boolean | — | true |
icon-pack | Icon pack to use | String | mdi , fa , fas , far , fab , fad , fal | mdi |
icon-size | Arrow icon size, optional | String | is-small , is-medium , is-large | — |
icon-prev | Icon to use for previous arrow | String | — | chevron-left |
icon-next | Icon to use for next arrow | String | — | chevron-right |
indicator | Display the indicator for jumping to specific item | Boolean | — | true |
indicator-background | Adds background to indicator | Boolean | — | false |
indicator-custom | Use when there are more than 6 images so that the indicator is not too small | Boolean | — | false |
indicator-custom-size | Image size of the indicator when the indicator-custom is used | String | is-small , is-medium | is-small |
indicator-inside | Display the indicator inside the carousel | Boolean | — | true |
indicator-mode | Trigger for action indicator | String | click , hover | click |
indicator-position | Position indicator only when indicator-inside | String | is-bottom , is-top | is-bottom |
indicator-style | Style for indicator of carousel | String | is-boxes , is-dots , is-lines | is-dots |
overlay | Switch like a gallery | Boolean | — | false |
progress | Display the progress item of carousel | Boolean | — | false |
progress-type | Type (color) of the progress, optional | String | is-white , is-black , is-light ,
is-dark , is-primary , is-info , is-success ,
is-warning , is-danger ,
and any other colors you've set in the $colors list on Sass | is-primary |
with-carousel-list | Use when indicator custom with b-carousel-list | Boolean | — | false |
Item
Name | Description | Parameters |
---|---|---|
click | Non-native click event, will trigger only on an element that should normally not be clickable/focusable |
List
Name | Description | Type | Values | Default |
---|---|---|---|---|
v-model | Binding value | Number | — | 0 |
data | Carousel-list data (any b-image prop can be used) | Array | — | — |
has-drag | Toggle touch dragging, when touch not detected. Auto switch mouse dragging | Boolean | — | true |
has-grayscale | Give a grayscale effect to img | Boolean | — | false |
has-opacity | Give an opacity effect to img | Boolean | — | false |
repeat | Returns carousel to start when active item matches length of data | Boolean | — | false |
items-to-show | Count of items to be showed per view (supports a decimal). | Number | — | 4 |
items-to-list | Count of items to list when using navigation buttons | Number | 1-5 | 1 |
as-indicator | Switch mode to indicator for carousel | Boolean | — | false |
refresh | Refresh for carousel overlay | Boolean | — | false |
arrow | Display the "next" or "prev" action when first or last item | Boolean | — | true |
arrow-hover | Display arrow action when hovered. Hidden on mobile | Boolean | — | true |
icon-pack | Icon pack to use | String | mdi , fa , fas , far , fab , fad , fal | mdi |
icon-size | Arrow icon size, optional | String | is-small , is-medium , is-large | — |
icon-prev | Icon to use for previous arrow | String | — | chevron-left |
icon-next | Icon to use for next arrow | String | — | chevron-right |
# Variables
You can use these variables to customize this component.
Name | Description | Default |
---|---|---|
$carousel-min-height | The carousel default height before image load | 120px |
$carousel-arrow-background | The carousel arrow background | $scheme-main |
$carousel-arrow-color | The carousel color border | $primary |
$carousel-arrow-icon-spaced | The carousel arrow icon spaced left and right | 1.5rem |
$carousel-arrow-top | The carousel position by top | 50% |
$carousel-indicator-background | The carousel indicator background | rgba($scheme-invert, 0.45) |
$carousel-indicator-border | The carousel indicator color border | $scheme-main |
$carousel-indicator-color | The carousel indicator color | $primary |
$carousel-indicator-spaced | The carousel indicator spaced | .5rem |
$carousel-overlay-background | The carousel background when overlay | rgba($scheme-invert, 0.86) |
$carousel-overlay-z | The carousel z-index for overlay | 40 |
This page is open source. Noticed a typo or something's unclear?