Skip to content

Animations

Click Animations

NOTE

Since v0.48.0, we are rewritten the click animations system with much more consistent behaviors. It might change the behaviors of your existing slides in edge cases. While this page is showing the new click system, you can find more details about the refactor in #1279.

v-click

To apply "click animations" for elements, you can use the v-click directive or <v-click> components

md
<!-- Component usage:
     this will be invisible until you press "next" -->
<v-click> Hello World! </v-click>

<!-- Directive usage:
     this will be invisible until you press "next" the second time -->
<div v-click class="text-xl"> Hey! </div>

v-after

v-after is only provided as a directive. It will turn the element visible when the previous v-click is triggered.

md
<div v-click> Hello </div>
<div v-after> World </div>

When you press "next", both Hello and World will show up together.

Hide after clicking

Add a .hide modifier to v-click or v-after to make the element invisible after clicking, instead of showing up.

md
<div v-click> Visible after 1 click </div>
<div v-click.hide> Hidden after 2 click </div>
<div v-after.hide> Hidden after 2 click </div>

For v-click component, you can use the hide prop to achieve the same effect:

md
<v-click> Visible after 1 click </v-click>
<v-click hide> Hidden after 2 click </v-click>

v-clicks

v-clicks is only provided as a component. It's a shorthand to apply the v-click directive to all its child elements. It is especially useful when working with lists and tables.

md
<v-clicks>

- Item 1
- Item 2
- Item 3

</v-clicks>

An item will become visible each time you click "next". It accepts a depth prop for nested list:

md
<v-clicks depth="2">

- Item 1
  - Item 1.1
  - Item 1.2
- Item 2
  - Item 2.1
  - Item 2.2

</v-clicks>

Also, you can use the every prop to specify the number of items to show after each click:

md
<v-clicks every="2">

- Item 1 (part 1)
- Item 1 (part 2)
- Item 2 (part 1)
- Item 2 (part 2)

</v-clicks>

Positioning

By default, the clicking animations take place one by one. You can customize the animation position of elements by using the at prop or the v-click directive with value.

Like the CSS layout system, click-animated elements can be "relative" or "absolute":

Relative Position

This actual position of relative elements is calculated based on the previous relative elements:

md
<div v-click> visible after 1 click </div>
<v-click at="+2"><div> visible after 3 clicks </div></v-click>
<div v-click.hide="'-1'"> hidden after 2 clicks </div>

```js {none|1|2}{at:'+5'}
1  // highlighted after 7 clicks
2  // highlighted after 8 clicks
```

NOTE

The default value of v-click is '+1' when you don't specify it.

In fact, v-after are just shortcuts for v-click with at prop:

md
<!-- The following 2 usages are equivalent -->
<img v-after />
<img v-click="'+0'" />

<!-- The following 3 usages are equivalent -->
<img v-click />
<img v-click="'+1'" />
<v-click-gap size="1" /><img v-after />

INFO

Only string values starting with '+' or '-' like '+1' are treated as relative positions:

ValueKind
'-1', '+1'Relative
+1 === 1Absolute
'1'Absolute

So don't forget the single quotes for the relative values.

Absolute Position

The given value is the exact click count to show the element:

md
<div v-click="3"> visible after 3 clicks </div>
<v-click at="2"><div> visible after 2 clicks </div></v-click>
<div v-click.hide="1"> hidden after 1 click </div>

```js {none|1|2}{at:3}
1  // highlighted after 3 clicks
2  // highlighted after 4 clicks
```

Mixed Case

You can mix the absolute and relative positions:

md
<div v-click> visible after 1 click </div>
<div v-click="3"> visible after 3 clicks </div>
<div v-click> visible after 2 click </div>
<div v-click="'-1'"> visible after 1 click </div>
<div v-click="4"> visible after 4 clicks </div>

The following example synchronizes the highlighting of the two code blocks:

md
```js {1|2}{at:1}
1 + 1
'a' + 'b'
```

```js {1|2}{at:1}
2
'ab'
```

Enter & Leave

You can also specify the enter and leave index for the v-click directive by passing an array. The end index is exclusive.

md
<div v-click.hide="[2, 4]">
  This will be hidden at click 2 and 3.
</div>
<div v-click />
<div v-click="'[+1, +1]'">
  This will be shown at click 3, and hidden since click 4.
</div>

You can also use v-switch to achieve the same effect:

md
<v-switch>
  <template #1> show at click 1, hide at click 2. </template>
  <template #2> show at click 2, hide at click 5. </template>
  <template #5-7> show at click 5, hide at click 7. </template>
</v-switch>

See VSwitch Component for more details.

Custom Total Clicks Count

By default, Slidev counts how many steps are needed before going to the next slide. You can override this setting by passing the clicks frontmatter option:

yaml
---
# 10 clicks in this slide, before going to the next
clicks: 10
---

Element Transitions

When you apply the v-click directive to your elements, it will attach the class name slidev-vclick-target to it. When the elements are hidden, the class name slidev-vclick-hidden will also be attached. For example:

html
<div class="slidev-vclick-target slidev-vclick-hidden">Text</div>

After a click, it will become

html
<div class="slidev-vclick-target">Text</div>

By default, a subtle opacity transition is applied to those classes:

css
/* below shows the default style */

.slidev-vclick-target {
  transition: opacity 100ms ease;
}

.slidev-vclick-hidden {
  opacity: 0;
  pointer-events: none;
}

You can override them to customize the transition effects in your custom stylesheets.

For example, you can achieve the scaling up transitions by:

css
/* styles.css */

.slidev-vclick-target {
  transition: all 500ms ease;
}

.slidev-vclick-hidden {
  transform: scale(0);
}

To specify animations for only certain slides or layouts

scss
.slidev-page-7,
.slidev-layout.my-custom-layout {
  .slidev-vclick-target {
    transition: all 500ms ease;
  }

  .slidev-vclick-hidden {
    transform: scale(0);
  }
}

Learn more about customizing styles.

Direction Specific Animations

Available since v0.48.0

In some cases, you might want to have different animations going forward and backward. Slide will apply the .slidev-nav-go-forward or .slidev-nav-go-backward class to slide container when navigating.

So you can leverage this to apply different animations for different directions, for example:

css
/* example: delay on only forward but not backward */
.slidev-nav-go-forward .slidev-vclick-target {
  transition-delay: 500ms;
}
.slidev-nav-go-backward .slidev-vclick-target {
  transition-delay: 0;
}

To make it easier, we also provided some UnoCSS variants built-in, that you can add forward: or backward: prefix to any utility classes to apply them conditionally.

html
<div v-click class="transition delay-300">Element</div>
<div v-click class="transition forward:delay-300">Element</div>

Rough Markers

Available since v0.48.0

Slidev integrates Rough Notation to allow marking or highlighting elements in your slides.

v-mark

Rough Notation integrates comes with the v-mark directive.

Type

v-mark.underline for Underline mark, v-mark.circle for Circle mark, etc. Default to underline

Color

v-mark.red makes the notation red. Supported built-in color themes from UnoCSS. For custom colors, use object syntax v-mark="{ color: '#234' }"

Clicks

v-mark works like v-click and will trigger after a click. Same as v-click, it allows you to pass a custom click value, like v-mark="5" or v-mark="'+1'".

Options

Optionally you can pass an object to v-mark to specify the options, for example:

vue
<span v-mark="{ at: 5, color: '#234', type: 'circle' }">
Important text
</span>

Preview

Motion

Slidev has @vueuse/motion built-in. You can use the v-motion directive to any elements to apply motion to them. For example

html
<div
  v-motion
  :initial="{ x: -80 }"
  :enter="{ x: 0 }"
  :leave="{ x: 80 }"
>
  Slidev
</div>

The text Slidev will move from -80px to its original position when entering the slide. When leaving, it will move to 80px.

Before v0.48.9, you need to add preload: false to the slide's frontmatter to enable motion.

Motion with Clicks

Available since v0.48.9

You can also trigger the motion by clicks. For example

html
<div
  v-motion
  :initial="{ x: -80 }"
  :enter="{ x: 0, y: 0 }"
  :click-1="{ x: 0, y: 30 }"
  :click-2="{ y: 60 }"
  :click-2-4="{ x: 40 }"
  :leave="{ y: 0, x: 80 }"
>
  Slidev
</div>

Or combine v-click with v-motion:

html
<div v-click="[2, 4]" v-motion
  :initial="{ x: -50 }"
  :enter="{ x: 0 }"
  :leave="{ x: 50 }"
>
  Shown at click 2 and hidden at click 4.
</div>

The meanings of variants:

  • initial: When currentPage < thisPage, or v-click hides the current element because $clicks is too small.
  • enter: When currentPage === thisPage, and v-click shows the element. Priority: lowest
  • click-x: x is a number representing the absolute click num. The variant will take effect if $clicks >= x. Priority: x
  • click-x-y: The variant will take effect if x <= $clicks < y. Priority: x
  • leave: currentPage > thisPage, or v-click hides the current element because $clicks is too large.

The variants will be combined according to the priority defined above.

WARNING

Due to a Vue internal bug, currently only v-click to the same element of v-motion can control the motion animation. As a workaround, you can use something like v-if="3 < $clicks" to achieve the same effect.

Learn mode: Demo | @vueuse/motion | v-motion | Presets

Slide Transitions

Available since v0.39.0

Slidev supports slide transitions out of the box. You can enable it by setting the transition frontmatter option:

md
---
transition: slide-left
---

This will give you a nice sliding effects on slide switching. Setting it in the frontmatter will apply to all slides. You can also set different transitions per slide.

Builtin Transitions

  • fade - Crossfade in/out
  • fade-out - Fade out and then fade in
  • slide-left - Slides to the left (slide to right when going backward)
  • slide-right - Slides to the right (slide to left when going backward)
  • slide-up - Slides to the top (slide to bottom when going backward)
  • slide-down - Slides to the bottom (slide to top when going backward)
  • view-transition - Slides with the view transitions API

View Transitions

Available since v0.43.0

The View Transitions API provides a mechanism for easily creating animated transitions between different DOM states. Learn more how it works in View Transitions API - MDN Web Docs - Mozilla.

WARNING

Experimental: This is not supported by all browsers. Check the Browser compatibility table carefully before using this.

You can use the view-transition-name CSS property to name view transitions, which creates connections between different page elements and smooth transitions when switching slides.

You can enable MDC (Markdown Component) Syntax support to conveniently name view-transitions:

md
---
transition: view-transition
mdc: true
---

# View Transition {.inline-block.view-transition-title}

---

# View Transition {.inline-block.view-transition-title}

Custom Transitions

Slidev's slide transitions are powered by Vue Transition. You can provide your custom transitions by:

md
---
transition: my-transition
---

and then in your custom stylesheets:

css
.my-transition-enter-active,
.my-transition-leave-active {
  transition: opacity 0.5s ease;
}

.my-transition-enter-from,
.my-transition-leave-to {
  opacity: 0;
}

Learn more about how it works in Vue Transition.

Forward & Backward Transitions

You can specify different transitions for forward and backward navigation using | as a separator in the transition name:

md
---
transition: go-forward | go-backward
---

With this, when you go from slide 1 to slide 2, the go-forward transition will be applied. When you go from slide 2 to slide 1, the go-backward transition will be applied.

Advanced Usage

The transition field accepts an option that will passed to the <TransitionGroup> component. For example:

md
---
transition:
  name: my-transition
  enterFromClass: custom-enter-from
  enterActiveClass: custom-enter-active
---

Released under the MIT License.