[Experimental] Transitions for bespoke template (Second iteration)
Expreimental transitions are available in Marp CLI v2.0.0 and later + Google Chrome / Chromium 101 and later.
This issue is for tracking an experimental transitions support for bespoke template, and the content may change actively. Welcome your feedback about this experiment!
See "Guide" section of this issue for how to use transitions experiment. ⬇️
Quick look
https://marp-cli-page-transitions.glitch.me/ (Chrome 104+)
https://user-images.githubusercontent.com/3993388/169697466-283dd2f2-b6e5-4b33-86d4-b10cc0a6c3e9.mp4
Try this command to preview transitions on Marp CLI:
curl -o ./showcase.md https://gist.githubusercontent.com/yhatt/d9e86ee53eb8816aaf9c996e773b6f82/raw/transition-showcase.md
marp --bespoke.transition --preview ./showcase.md
Or see a transition showcase at Gist: https://gist.github.com/yhatt/d9e86ee53eb8816aaf9c996e773b6f82
Background
A slide transition is a very common feature in several full-featured presentation tools. However, handling transition tends to become complex due to rendering 2 pages while performing transitions.
Even in a simple case, where content fades from one screen to another, it means rendering your page with both states at once, performing a cross-fade, then removing the old state.
This is harder than it sounds. You need to make sure that the outgoing page can't receive additional interactions, and that the outgoing state doesn't jank the transition by updating its own state. You also need to ensure the presence of both states doesn't create a confusing experience for those using accessibility technology.
― Smooth and simple page transitions with the shared element transition API - Chrome Developers
We believe that holding a complex logic makes hard to maintain the ecosystem, and will bring burnout eventually as like as a classic app. So we had ever not worked on transitions for Marp.
But it becomes a different story if provided a simple solution by the browser. Shared Element Transition API proposal provides a simple and high-level API for transition animations.
By using this proposal, transitions for Marp CLI bespoke template can get both of effective transitions for Marp slides and the ecosystem sustainability.
Helpful resources to know API
- WICG/shared-element-transitions
- Smooth and simple page transitions with the shared element transition API - Chrome Developers
- Shared Element Transitions - Chrome Platform Status
- Bringing page transitions to the web - YouTube
Guide
Prerequisite
The experimental transition feature is relied on Shared Element Transition API proposal. It is still early phase of proposal and not generally available in the most of browsers at this time.
This API requires Chromium 101 and later, with enabled documentTransition API experiment (chrome://flags/#document-transition or Origin Trials).
You can try experimental transitions easily by using Marp CLI preview window (--preview). The preview window will turn on a depending experiment automatically.
Enable experimental transitions
Add --bespoke.transition option.
marp --bespoke.transition --preview slide.md
The transition feature is bespoke template specific so it would not work in non-HTML format and other templates like bare template.
If you are using a custom engine which have supported
transitioncustom directive like reveal.js based Marpit engine, the output HTML may break due to an overridden directive definition by a CLI option.
transition local directive
To use transition animations, you have to choose a transition effect for slide(s) by defining transition local directive in your Markdown.
---
transition: fade
---
# Slide
As same as other local directives like header and class, you can change the kind of transition in the middle of slides by defining the transition directive through HTML comment, or apply a specific transition into a single slide by using a scoped local directive (_transition: as known as spot directive).
---
transition: fade
---
# Fade transition
---
<!-- transition: cover -->
Changed the kind of transition to `cover`.
---
<!-- _transition: none -->
Disabled transition for this slide.
---
Got back cover transition.
transitiondirective will set the animation for "the next boundary between slides" (in another words "the next ruler---"). It also means settingtransitiondirective at the last slide would have no meaning.
Built-in effects
clockwisecounterclockwisecovercoverflowcubecylinderdiamonddropexplodefadefade-outfallflipglowimplodein-outiris-iniris-outmeltoverlappivotpullpushrevealrotateslidestarswapswipeswooshwipewiperzoom
Check the video at the top section of this issue.
You also can turn off the transition effect by setting none.
Set custom duration
The default duration of transition is 0.5s in all transitions, but you can set custom duration by adding a space-separated parameter to transition directive definition.
transition: fade 1s
Custom duration should have a unit s or ms.
Custom transition 🌠
In the second iteration of transition experiment, you can define the custom transition through CSS. You can make your own transition effect just by declaring animation keyframes.
@keyframes marp-incoming-transition-triangle {
from { clip-path: polygon(0% 0%, 0% 0%, 0% 0%); }
to { clip-path: polygon(0% 0%, 200% 0%, 0% 200%); }
}
@keyframes marp-incoming-transition-backward-triangle {
from { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); }
to { clip-path: polygon(-100% 100%, 100% -100%, 100% 100%); }
}
This is very exciting and so creative feature! We are using exist CSS @keyframes declarations and never adding Marp specific syntax to CSS, so there should be no CSS complexity losing too. You also can tweak animation of built-in transitions by overloading keyframes.
We are really looking forward to what creative transitions our community will create!!
:arrow_right: See blog article: "Marp CLI Experimental: How to make custom transition"
Features from Shared Element Transition proposal
Transition with shared elements (v2.0.2 and later)
By using page-transition-tag CSS property, you can make the specific elements move individually during transition, just like as PowerPoint Morph and Keynote Magic Move.
In a below example, the first <h1> element in each slide page and the image <img> that has shared space-separated keyword in alt attribute are marked as shared elements. If there were a pair of tagged elements with the same name in the outgoing slide and incoming slide, these will have a morph animation during transition.
---
theme: gaia
_class: lead
transition: slide 1s
style: |
section > h1:first-of-type {
contain: paint;
page-transition-tag: title;
}
img[alt~="shared"] {
contain: paint;
page-transition-tag: image;
}
---

# Transition with shared elements
---
# It's a Magic! 🪄


Currently contain: paint; is also required to work the morph animation.
Please note that the tagged element with the same name should have determined uniquely for each slide. If there are duplicate elements in the same slide, the whole of transition animation will fail due to the runtime error.
For marking page-transition-tag with more flexibility, you can also use the <span> element with a custom class by enabling HTML tag rendering through --html option.
---
transition: cube 1s
style: |
.shared-title {
display: inline-block;
contain: paint;
page-transition-tag: shared-title;
}
---
# <span class="shared-title">Shared</span> Element Transition
---

## <span class="shared-title">Morphed!</span>
Reference: https://github.com/WICG/shared-element-transitions/blob/main/explainer.md#via-css
Opt-out transitions
Of course, not everyone is fun of dizzy animation from a transition effect. Transitions in the presentation often may have too much movings, and someone may feel it like as motion sickness.
So we respect prefers-reduced-motion media query in the converted HTML, to be able to make the slide viewer opt-out transition animations. If a user preference in response to prefers-reduced-motion has set, all kind of transitions are forced to a constant dissolve effect as same as fade built-in transition. Shared elements defined by author have no animations too.
Status in Marp ecosystem
In Marp CLI, --bespoke.transition is going to keep experimental and optional until Shared Element Transition API proposal makes stable and generally available in at least one of major browsers.
If become stable, we are going to add support of transitions for downstream tools too. (e.g. auto-complete of transition directive in Marp for VS Code)
Known topics
- Don't forget this is cutting edge of Chrome currently. Sometimes you might meet not working transition or crashed tab.
- [as-designed] Animation for transition is targeting to whole of the view that includes slide letterbox / pillarbox.
- ~~[enhancement] A local-scoped keyframes set by
<style scoped>cannot use as transition keyframes.~~- Fixed in v2.0.2: #456
Changelog
See #382 to see about previous iteration.
Is this transition can used for vscode extention?
@tianfanghan Not yet. Please read "Status in Marp ecosystem" section.
If become stable, we are going to add support of transitions for downstream tools too. (e.g. auto-complete of transition directive in Marp for VS Code)
Hi yhatt, I just wanted to say a big thank you to you and the team for this long awaited transition feature! I've tried in Ubuntu and Arch Linux and it works like a charm with the provided instructions and the downloaded marp-cli binary. Great work :)
PSA: the
viewTransition.domUpdatedpromise is nowviewTransition.updateCallbackDone.Hopefully that'll be our last rename on the road to shipping! https://groups.google.com/a/chromium.org/g/blink-dev/c/AJJiH6Pjr50
— https://twitter.com/jaffathecake/status/1616422515684810753
This property is not referenced by bespoke transition plugin in reality, so (probably) there is nothing to worry about breaking transitions in exist slides. On the other hand, we may have to modify a defined type interface and unit testing. https://github.com/search?q=repo%3Amarp-team%2Fmarp-cli%20domUpdated&type=code
Thank you for all your work on this! Are there any plans to allow transitions such as "fade" to also work with .pptx exports?
Thanks for your feedback! We have thought that transition effects can be applied to PPTX if Markdown is using the built-in effect that is compatible with PPTX. Actually I have already tried the implementation for getting transition effects in PDF, and worked well. However, I've postponed PDF transition effects due to lacked support in Acrobat Reader for Mac
At this moment, it's difficult to implement transition effects to PPTX shortly, because PptxGenJS (a presentation generation library Marp is using) has no support about slide transitions, and I'm not familiar with a specification of PPTX file format.
If received more feedbacks, we consider to work on the transition support for other file formats. Of course, we are welcome to contribute from community.