Examples

Modals you can open.

Working Bootstrap modals built by the extension, one per option, with the source alongside each.

Every button below opens a modal built by the extension as this page was rendered.

This site sets two defaults for all of them, in _quarto.yml:

extensions:
  modal:
    fade: true
    centred: true

Individual modals below override those.

The default button type

type is the first argument of the shortcode, and it is positional. Leave it out and you get a toggle button.

{{< modal target=modal-default-type label="Open without a type" >}}

Write the type as a bare word, and never as type=toggle. A named type is read as an attribute instead. The extension then reports a key it does not recognise, and you still get a toggle button. The button table lists the two values the argument accepts.

Dismiss buttons

A dismiss button closes a modal, and it takes more than one shape.

{{< modal dismiss target=modal-dismiss label="Close by name" >}}
{{< modal dismiss inside=true label="Cancel" classes="btn btn-secondary" >}}
{{< modal dismiss inside=true >}}

target names the modal to close, so the button works from anywhere in the page. inside=true drops the target, and the button then closes the modal that holds it. A dismiss button with no label becomes Bootstrap’s bare cross, which is the button the header carries. classes replaces the default classes on any button.

Sizes

size takes the Bootstrap tokens or the friendly aliases.

::: {#modal-small size=small}
::: {#modal-large size=lg}
::: {#modal-xl size=extra-large}

The default width

size=medium and size=default add no size class at all, so the dialog keeps the width Bootstrap gives it. Either spelling gives one modal its default width back when a project sets size for every modal.

::: {#modal-default-width size=medium}

Scrolling, fullscreen, and a static backdrop

::: {#modal-scrollable scrollable=true}
::: {#modal-fullscreen fullscreen=lg}
::: {#modal-static backdrop-static=true keyboard=false}

Fullscreen at every width

fullscreen=true fills the screen at every width, and not only below a breakpoint.

::: {#modal-fullscreen-always fullscreen=true}

Dialog options lists every value fullscreen accepts.

Overriding a project default

This site turns fade and centred on for every modal. One container turns either of them off again.

::: {#modal-plain fade=false centred=false}

An attribute on the container always wins over the project or document setting.

The header close button

The header carries a close button unless close-button=false removes it. A container with no horizontal rule gets no footer, so the header button is then the only button.

::: {#modal-no-close close-button=false}
::: {#modal-no-footer}

Give each modal a header close button or a footer that closes it. close-button=false with no footer leaves a dialog that only the backdrop and Esc can close. Container-only attributes covers close-button and its label.

Headings inside the body

The first heading becomes the title. Every later heading stays in the body, and the extension puts the modal identifier in front of its own identifier. A heading inside a modal can therefore repeat a heading on the page without a clash.

::: {#modal-headings}

## A body with its own headings

### Details

:::

A code block inside a modal

A code block keeps its copy button inside a modal. The extension adds a small script whenever it builds a modal. The script gives each modal its own clipboard handler, with the modal as the container, so the copy works while the dialog holds the focus.

Accessibility

description points at the identifier of an element elsewhere on the page, and becomes the modal’s aria-describedby.

This paragraph carries the identifier the modal points at.

::: {#modal-described description="described-note" close-button-label="Dismiss this dialog"}

The identifier has to exist in the document; the extension warns when it does not, since a dangling aria-describedby is worse than none.

Source

The repository ships a short, standalone starting point you can copy: example.qmd.

Back to top