quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.6k stars 294 forks source link

How to center text in Quarto presentations? #1231

Open asmaier opened 2 years ago

asmaier commented 2 years ago

I'm creating a presentation with Quarto ( to revealjs) and wanted to have one slide with a line of text centered horizontally and vertically. I could not find a way to do this. I figured that I can use the .r-stack to center text horizontally like

## 
:::{.r-stack}
centered text ^[with a footnote for extra fun]
:::

But how can one center the line of text also vertically?

cscheid commented 2 years ago

Hi! This turns out to be much trickier to do than might appear at first glance because of the way revealjs sets up its slide sizes. Unfortunately, there's no simple current solution. Here are two possible workarounds for now.

Don't use footnotes

If you don't use footnotes, then switching to a title slide (using # instead of ##) solves the problem:

#

:::{.r-stack}
centered text horizontally and vertically
:::

Use footer class instead of footnotes

If you must use notes, then putting them manually in the footer is another workaround:

#

:::{.r-stack}
centered text horizontally and vertically
:::

::: footer
Here's a horizontally-centered note on the footer. (Note that it's not a footnote.)
:::

The main complication we can't easily solve is that revealjs does a fair amount of transformation of the "main" coordinate system through scaling and translating transforms. This makes it hard to set up any of the usual CSS tricks like setting a parent div with full height and a child div with margin: auto, or setting up a child div with position: absolute and top: 50%; transform: translateY(-50%).

@jjallaire I do think we need a better solution for the future, but I don't see how we do that outside of throwing away revealjs's CSS and replacing it with a more robust system of our own. I think the best present solution is to document this quirk on the revealjs format page.

asmaier commented 2 years ago

Thank you for the hint with the title page. It works. However the problem with "misusing" .r-stack is that this trick only works for a single line of text. But on the title page for a presentation several lines of text (title, subtitle, author, date) are centered . How is this done? Can't the same layout be activated for an arbitrary slide in the middle of the presentation?

jjallaire commented 2 years ago

Any slide that uses an H1 header (#) is considered a title slide and is vertically centered.

asmaier commented 2 years ago

But text on the title slide of a presentation (see https://quarto.org/docs/gallery/#presentations) is also horizontally centered, isn't it? How is this done?

(Also the footer text seems to be centered horizontally)

jjallaire commented 2 years ago

You can add the .center class to the heading:

## Heading {.center}
asmaier commented 2 years ago

Unfortunately that does only seem to center the content vertically but not horizontally.

jjallaire commented 2 years ago

Oh sorry I was still on vertical. No, it doesn't appear as if there is a way to do horizontal centering of slides right now.

asmaier commented 2 years ago

I was about to give up, but now I found actually two solutions for multiline text which is horizontally and vertically centered. Actually it seems every line of centered text needs it's own div. So the following works:

#
:::{.r-stack}
First centered line
:::
:::{.r-stack}
Second centered line
:::

But this one is even nicer

#
:::{#title-slide .center}
First centered line

Second centered line
:::

The latter solution has slightly bigger vertical spacing between the lines, but needs less markup. Both solutions will not handle footnote nicely, but they are good enough for my purposes.

asmaier commented 1 year ago

Unfortunately there is an issue with the solution suggested above. When trying to convert a presentation with that trick to beamer it won't work. It seems the converter to beamer cannot handle more than one title page. So it gets confused if the structure of your presentation has more than one title page like

## section 

#
:::{#title-slide .center}
First centered line

Second centered line
:::

## another section
asmaier commented 1 year ago

I found an even better way to center text horizontally and vertically:

## {.center}

:::{#title-slide .center}
First centered line

Second centered line
:::

## {.center} will center the text vertically on the slide. This will also work when converting to beamer and won't break the presentation like inserting a title-slide with #.

:::{#title-slide .center} will center the text horizontally. However this will not work when converting the presentation in beamer. The text will stay left-aligned in the beamer pdf.

asmaier commented 1 year ago

Further remarks about horizontal centering in quarto. Basically there are three different ways to do that

  1. {#title-slide .center} for text (or {.r-stack })
  2. {fig-align="center"} for images (not necessary, because it is the default)
  3. #| fig-align: center inside a code block for figures produced by the code The latter is not so elegant, because changing the figure alignment will lead to reexecution of the code block (caching won't help, because the content of the code block has changed).

Why do I note this here? Paraphrasing the Python Zen here: "There should be one-- and preferably only one --obvious way to center content (horizontally and/or vertically) in Quarto."

cscheid commented 1 year ago

I'm adding a suggestion of a different workaround for horizontal centering here. It is HTML-specific, but works for simple cases:

---
title: playground
format: revealjs
---

## centering

:::: {.columns}

::: {.column width="80%"}
<center>
short

things

are

centered
</center>
:::

::: {.column width="20%"}
only

on

the

left
:::

::::

(ht to @aronatkins for this one!)

asmaier commented 1 year ago

Note: The suggestion of @cscheid will only center the content horizontally within the first column. It will not center the content vertically in that column. It should also be noted that using <center> is deprecated for HTML: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/center

mcanouil commented 11 months ago

FYI: