quarto-shapes

CSS shape classes for Quarto documents and presentations

Style divs as shapes that can contain text and other elements. Supports fill, stroke, rotation, and sizing — all composable as classes.

Installation

quarto add emilhvitfeldt/quarto-shapes

Quick Start

Add to your YAML front matter:

---
title: My Document
format: html
filters:
  - shapes
---

Then wrap any content in a shape div:

::: {.shape-circle fill="blue"}
Hello
:::

Shape classes

Every shape is a class of the form .shape-<name>. The full catalog, grouped by category:

Category Shape classes
Basic geometric .shape-circle, .shape-square, .shape-rectangle, .shape-rounded-square, .shape-oval, .shape-semicircle, .shape-pie, .shape-wedge, .shape-arc, .shape-block-arc, .shape-donut, .shape-frame
Polygons .shape-triangle, .shape-diamond, .shape-pentagon, .shape-hexagon, .shape-heptagon, .shape-octagon, .shape-decagon, .shape-dodecagon, .shape-parallelogram, .shape-trapezoid
Stars .shape-star-4, .shape-star, .shape-star-6, .shape-star-8, .shape-star-10, .shape-star-12, .shape-star-16, .shape-star-24, .shape-star-32, .shape-sun, .shape-starburst
Nature & symbols .shape-heart, .shape-moon, .shape-cloud, .shape-lightning, .shape-teardrop, .shape-wave, .shape-double-wave, .shape-no-symbol, .shape-smiley
Arrows .shape-arrow, .shape-arrow-double, .shape-notched-arrow, .shape-pentagon-arrow, .shape-arrow-striped, .shape-arrow-bent, .shape-chevron
Callouts & bubbles .shape-speech-bubble, .shape-callout-round, .shape-callout-rounded, .shape-callout-oval, .shape-callout-thought, .shape-callout-cloud, .shape-callout-explosion
Flowchart .shape-terminator, .shape-cylinder, .shape-document, .shape-manual-input, .shape-delay, .shape-display, .shape-stored-data, .shape-summing-junction, .shape-off-page
Block & functional .shape-cross, .shape-shield, .shape-folded-corner, .shape-diagonal-stripe, .shape-scroll, .shape-wavy-flag, .shape-ribbon
3D / perspective .shape-cube, .shape-cylinder-3d, .shape-cone, .shape-pyramid
Math symbols .shape-minus, .shape-multiply, .shape-divide, .shape-equals, .shape-not-equal
Brackets & braces .shape-bracket-left, .shape-bracket-right, .shape-brace-left, .shape-brace-right, .shape-paren-left, .shape-paren-right

The HTML example renders every one of these with its class name labeled underneath.

Colors, sizes, and modifiers

Colors are set with the fill= and stroke= attributes; size, stroke width, and rotation are classes. Everything is composable — mix attributes and classes on a single div, in any order:

::: {.shape-hexagon fill="none" stroke="red" .shape-stroke-lg .shape-rotate-90 .shape-md}
:::

Fill — fill="…"

Sets the interior color. Accepts any CSS color — a named color (tomato), hex (#42526C), or function (rgb(52 152 219)). Use fill="none" for an outline-only shape (pair it with a stroke).

::: {.shape-circle fill="#42526C"}
:::

Stroke — stroke="…" + .shape-stroke-*

Two independent axes: the outline color comes from the stroke= attribute (any CSS color), and the outline width from a class.

Color Width Default width
stroke="<any CSS color>", or stroke="none" .shape-stroke-sm (1) · .shape-stroke-md (3) · .shape-stroke-lg (6) · .shape-stroke-xl (10) 3 when a stroke color is set without a width class

Size — .shape-{sm,md,lg,full} or size="…"

Sets the shape’s bounding box. Defaults to 8rem (same as .shape-md) when no size class is given.

Class HTML size Typst (print)
.shape-sm 4rem 3cm
.shape-md 8rem 5cm
.shape-lg 14rem 8cm
.shape-full 100% of container

For a custom size, use the size= attribute with any length. It overrides the size classes and works in both HTML and Typst.

::: {.shape-circle fill="#42526C" size="3cm"}
:::

The value is passed through to both outputs as-is, so for documents you render to both HTML and Typst use a unit valid in each (cm, mm, in, pt). Typst does not accept px.

Rotation — .shape-rotate-*

Rotates the shape clockwise in 45° steps: .shape-rotate-45, .shape-rotate-90, .shape-rotate-135, .shape-rotate-180, .shape-rotate-225, .shape-rotate-270, .shape-rotate-315.

See the HTML example for these modifiers applied across the full shape catalog.

Callout direction — direction="…"

The callout and speech-bubble shapes (.shape-callout-round, .shape-callout-oval, .shape-callout-rounded, .shape-speech-bubble) point their tail down by default. Use the direction= attribute to point the tail any direction. The body stays upright and only the pointer moves: the filter recomputes the shape as a single outline (body + spike) for the requested angle, so there is no seam even on outlined callouts.

direction= takes a compass angle in degrees, or one of the four keyword aliases:

Value Pointer faces
0 / up up
90 / right right
180 / down (default) down
270 / left left

Any number works, so direction="225" points the tail down-left and direction="30" points up-and-to-the-right.

::: {.shape-speech-bubble fill="lightyellow" direction="up"}
Heads up!
:::

::: {.shape-callout-round fill="#4DADAD" direction="225"}
Down-left
:::

Works in HTML, RevealJS, and Typst. (.shape-callout-cloud, .shape-callout-thought, and .shape-callout-explosion keep their fixed designs.)

Typst / PDF output

Shapes also render in Quarto’s typst format (PDF). The existing SVG definitions are embedded as Typst images, so every shape is available. Note these print-specific behaviors.

  • Size classes map to print lengths: .shape-sm 3cm, .shape-md 5cm, .shape-lg 8cm.
  • Content is centered within the shape’s bounding box, not its visual outline.

Examples

Basic Usage