quarto-revealjs-chat-bubbles
iOS-style chat bubbles for Quarto Reveal.js presentations
Add iMessage-style chat bubbles to your Quarto Reveal.js presentations. Messages appear one at a time as fragments, and long conversations scroll automatically to keep the latest message in view.
Installation
quarto add EmilHvitfeldt/quarto-revealjs-chat-bubblesUsage
Enable the plugin in your presentation front matter:
format:
revealjs: default
revealjs-plugins:
- chat-bubblesThen write a conversation using .chat and bubble classes. Add .fragment to any bubble you want to reveal on a keypress:
::: {.chat}
::: {.bubble-right}
Hey, are you coming tonight?
:::
::: {.fragment .bubble-left}
Yeah! What time does it start?
:::
::: {.fragment .bubble-right}
Doors open at 7
:::
:::Bubble classes
| Class | Side | Color |
|---|---|---|
.bubble-right |
Right | iMessage blue |
.bubble-left |
Left | Light gray |
.bubble-left-2 |
Left | Green |
.bubble-left-3 |
Left | Purple |
.bubble-right is the “self” sender. Use .bubble-left variants for other participants — useful for group conversations with multiple speakers.
Group chats
Use all four classes together for multi-person conversations:
::: {.chat}
::: {.bubble-right}
Alright who's bringing what to the potluck?
:::
::: {.fragment .bubble-left}
I can do dessert
:::
::: {.fragment .bubble-left-2}
I'll bring drinks
:::
::: {.fragment .bubble-left-3}
Can I just bring chips
:::
:::Typing indicator
Add .typing to any .fragment bubble for a two-step reveal: the first keypress shows an animated three-dot typing indicator, and the next keypress expands the bubble and reveals the message text.
::: {.chat}
::: {.bubble-right}
Are you still there?
:::
::: {.fragment .bubble-left .typing}
Sorry, was typing a really long reply.
:::
:::Images and plots
Bubbles can contain images or R/Python plot output — just place them inside the bubble div as usual:
::: {.chat}
::: {.bubble-right}

:::
::: {.fragment .bubble-left}
Haha love it
:::
:::Code chunk output works the same way:
::: {.chat}
::: {.bubble-left}
Can you show me that plot?
:::
::: {.fragment .bubble-right}
```{r}
plot(mpg ~ disp, data = mtcars)
```
:::
:::Customizing colors
Override the CSS custom properties in your own stylesheet:
:root {
--bubble-blue: #FF3B30; /* sender bubble */
--bubble-gray: #E9E9EB; /* first receiver */
--bubble-green: #34C759; /* second receiver */
--bubble-purple: #AF52DE; /* third receiver */
}