Quarto: Unleash Dynamic Tabset Navigation & Polished PDF Exports

Discover how to supercharge your Quarto presentations with interactive tabset navigation in Reveal.js and create stunning, professional PDFs. Get ready to dazzle your audience!

Author
Published

Monday, the 21st of April, 2025

1 Introduction

Creating presentations with Quarto’s Reveal.js format comes with great flexibility, but navigating tabsets and exporting polished PDFs can be challenging.

In this post, you’ll learn how to streamline these tasks, making your workflow smoother and ensuring your slides are both interactive and well-formatted for sharing. With the right techniques, you can:

  1. Craft slides with tabset navigation that flows as naturally as your ideas.
  2. Transform your interactive presentations into sleek, professionally polished PDFs.

Let’s dive in and start elevating your slide game!

2 Setting Up the Presentation

Let’s kick off by creating a basic Reveal.js presentation with the essential YAML header.

title: "A Title"
subtitle: "A Subtitle"
author: "Mickaël Canouil, *Ph.D.*"
institute: "mickael.canouil.fr"
date: today
format: revealjs

3 Structuring Your Content

Break free from linear storytelling by organising your slides into engaging segments. Use the .panel-tabset class in your markdown content to create a dynamic, tabbed interface that keeps your audience on the edge of their seats:

## New slide {.smaller}

{{< lipsum 1 >}}

## Tabset {.smaller}

:::: {.panel-tabset}

### Lipsum

{{< lipsum 1-1 >}}

### Placeholder

{{< placeholder 600 400 >}}

### Lipsum 2

{{< lipsum 2-2 >}}

### Placeholder 2

{{< placeholder 600 400 >}}

:::

## Another slide {.smaller}

![An image]({{< placeholder 900 300>}})

4 Default Navigation Limitations

Out of the box, Quarto’s default configuration requires a manual click on every tab—a small, yet frustrating interruption in the flow of your presentation. Imagine having to constantly click through your content when you could be gliding from idea to idea!

quarto render assets/_demo-default.qmd

5 Enhanced Tabset Navigation

What if you could navigate through your tabs with the fluid grace of arrow keys? Inspired by Emil Hvitfeldt’s Slidecraft 101: Fragments - JS, I’ve taken tabset navigation to the next level with a custom JavaScript solution.

Here’s how you can make your presentation navigation as smooth as silk:

  1. Create a Custom JavaScript stored as an HTML file.
    Save the following code snippet in an HTML file. This script leverages Reveal.js’s fragment feature to enable arrow key navigation, letting you effortlessly glide between your tabs as if they were different slides.

    <script type="text/javascript" id="panel-tabset-fragments">
      Reveal.on("ready", function () {
        const tabsetSlides = document.querySelectorAll(".reveal .slides section .panel-tabset");
        tabsetSlides.forEach(function (tabset) {
          const tabCount = tabset.querySelectorAll("ul.panel-tabset-tabby li").length;
          for (let i = 0; i < tabCount - 1; i++) {
            const fragmentDiv = document.createElement("div");
            fragmentDiv.className = "panel-tabset-fragment fragment";
            fragmentDiv.dataset.tabIndex = i + 1;
            fragmentDiv.style.display = "none";
            tabset.parentNode.appendChild(fragmentDiv);
          }
        });
      });
    
      Reveal.on("fragmentshown", (event) => {
        if (event.fragment.classList.contains("panel-tabset-fragment")) {
          const tabIndex = parseInt(event.fragment.dataset.tabIndex);
          const tabset = Reveal.getCurrentSlide().querySelector(".panel-tabset");
          const tabLinks = tabset.querySelectorAll("ul.panel-tabset-tabby li a");
          if (tabIndex < tabLinks.length) {
            tabLinks[tabIndex].click();
          }
        }
      });
    
      Reveal.on("fragmenthidden", (event) => {
        if (event.fragment.classList.contains("panel-tabset-fragment")) {
          const tabIndex = parseInt(event.fragment.dataset.tabIndex);
          const tabset = Reveal.getCurrentSlide().querySelector(".panel-tabset");
          const tabLinks = tabset.querySelectorAll("ul.panel-tabset-tabby li a");
          if (tabIndex > 0) {
            tabLinks[tabIndex - 1].click();
          } else {
            tabLinks[0].click();
          }
        }
      });
    </script>
  2. Embed the Script in Your YAML Header.
    Integrate this new functionality by including the script in your Quarto presentation’s YAML header:

    title: "A Title"
    subtitle: "A Subtitle"
    author: "Mickaël Canouil, *Ph.D.*"
    institute: "mickael.canouil.fr"
    date: today
    format:
      revealjs:
        include-after-body:
          - file: revealjs-tabset.html

Render your updated slides and experience a newfound freedom in navigation:

quarto render assets/_demo-tabset.qmd

Now, simply use the left and right arrow keys to seamlessly transition between tabs—it’s like your presentation has its own rhythm!

6 Exporting to PDF

To export your presentation to PDF, you can use the decktape tool, which is a headless Chrome utility for capturing web pages as PDFs.

Your interactive masterpiece deserves to be preserved. With the decktape tool, you can convert your dynamic Reveal.js slides into a beautifully formatted PDF that retains every engaging detail and nuance of your presentation.

  1. Install decktape using npm:

    bash
    npm install -g decktape
  2. Use the following command to generate a PDF from your Reveal.js presentation:

    bash
    npx -y decktape reveal \
      --chrome-arg=--no-sandbox \
      --chrome-arg=--disable-setuid-sandbox \
      --fragments \
      "my-slides.html" "my-slides.pdf"

This command ensures every fragment and tab is captured in the PDF, preserving the aesthetic and functionality of your presentation.

Default Quarto Reveal.js

Unable to display PDF file. Download instead.

Tabset Quarto Reveal.js

Unable to display PDF file. Download instead.

7 Conclusion

By blending Quarto’s interactive Reveal.js tabset navigation with the crisp sophistication of PDF exports, you’re not merely creating presentations—you’re crafting immersive experiences. Whether delivered live or shared as a document, your slides will captivate and inspire.

And now, instead of wrestling with LaTeX or Typst and losing your hard-earned theming, you can focus entirely on refining your content and delivering a presentation that truly shines.

Elevate your storytelling and let your slides flow!

Back to top

Footnotes

  1. Or download the file directly using the link under the table of contents.↩︎