Content & layout

Putting things on the slide

Emil Hvitfeldt

Objectives

  • How we can position elements on the slides
  • Modify standard elements

The default layout

Content flows from the top, left aligned, one thing under the next.

  • That is a fine default, but it is an oppotunity to keep things fresh
  • Everything in this module is a way of stepping out of it
  • Vary the layout across the deck

Columns

Columns, with widths

my-deck.qmd

## Uneven columns

::: {.columns}

::: {.column width="40%"}
Left column
:::

::: {.column width="60%"}
Right column
:::

:::

Not only two

my-deck.qmd

::: {.columns}

::: {.column width="33%"}
1st column
:::

::: {.column width="33%"}
2nd column
:::

::: {.column width="33%"}
3rd column
:::

:::

An empty column is a quick spacer

my-deck.qmd

::: {.columns}

::: {.column width="30%"}
:::

::: {.column width="70%"}
Only right side
:::

:::

The cheapest way to put content somewhere other than the top left.

Filling the slide

r-fit-text

my-deck.qmd

## {.center}

::: r-fit-text
This fits perfectly!
:::

One block, one size

Everything inside a single r-fit-text gets the same size, set by the longest line.

my-deck.qmd

::: r-fit-text
This fits perfectly!

On two lines
:::

One block per line

my-deck.qmd

::: r-fit-text
This fits perfectly!
:::

::: r-fit-text
On two lines
:::

One block per line, and each line fills the slide on its own.

Images

Three ways in

  • A figure, flowing with the rest of the content
  • Absolute, placed exactly where you say
  • A background, filling the whole slide

Pick by how much the image is content and how much it is atmosphere.

A figure

my-deck.qmd

## A basic figure

![](images/holly-mandarich.jpg)

It is content, so it pushes other content around and it respects the margins.

Absolute

my-deck.qmd

## Absolute

![](images/noelle-rebekah.jpg){.absolute top=0 right=0 height="100%"}

The six attributes

Attribute Description
width width of the element
height height of the element
top distance from the top of the slide
left distance from the left of the slide
bottom distance from the bottom of the slide
right distance from the right of the slide

One of top / bottom, one of left / right, and only one of width / height so the image is not distorted.

Absolute works on anything

Not just images. Text takes the class too.

my-deck.qmd

## Absolute text

[python is great]{.absolute bottom="45%" left="20%"}

[and so is R]{.absolute bottom="0%" right="0%"}

Images stop at 95%

Reveal caps every image with max-width: 95% and max-height: 95%, so no height will push it past the edge.

my-deck.qmd

![](images/noelle-rebekah.jpg){.absolute top="-10%" right="-10%"
  height="120%" style="max-height: unset;"}

Unset the cap, then use negative offsets to bleed off the edge.

A background image

my-deck.qmd

## A background image {background-image="images/galen-crout.jpg"}

## {background-image="images/galen-crout.jpg"}

[always explore]{.absolute left="50%" top="20%" style="rotate: -10deg;"}

Text on a photo is hard to read

my-deck.qmd

## {background-image="images/tim-marshall.jpg"}

::: {.absolute left="55%" top="55%" style="font-size:1.8em;"}
Be Brave

Take Risks
:::

Give the text a box

my-deck.qmd

::: {.absolute left="55%" top="55%" style="font-size:1.8em;
  padding: 0.5em 1em;
  background-color: rgba(255, 255, 255, .5);"}
Be Brave

Take Risks
:::

A half-transparent background and some padding, and it is readable.

Or float the content on a card

Shrink the slide itself and give it a shadow, and the background can be as loud as it likes.

styles.scss

/*-- scss:rules --*/
.reveal .slides section.paper {
  width: 92%;
  height: 86% !important;
  max-height: 86% !important;
  left: 4% !important;
  top: 6% !important;
  padding: 40px;
  box-sizing: border-box;
  border-radius: 4px;
  background-color: #fdfcfa;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

The !important is there because reveal positions slides with inline styles.

The paper card

my-deck.qmd

## My slide {.paper background-color="#ffe83e"}

Content goes here, cleanly inside the card.

## My slide {.paper background-image="galen-crout.jpg" background-size="cover"}

Content goes here, cleanly inside the card.

Plots

Plots are figures with extra knobs

  • fig-width / fig-height how big the plot is drawn, which sets how big its text is
  • fig-asp the ratio, so you only tune one of the two
  • fig-dpi raise it when the plot looks soft
  • fig-align left, center, or right

The defaults sit around fig-width: 9, fig-height: 5, which makes axis labels too small from the back row.

Smaller plot, bigger text

my-deck.qmd

```{r}
#| fig-width: 6
#| fig-asp: 0.5
plot(mpg ~ disp, data = mtcars, col = factor(am), pch = 16, bty = "n")
```

Drawing the plot smaller makes its text bigger, because reveal scales it back up to fit.

transparent plots background

my-deck.qmd

knitr:
  opts_chunk:
    dev: png
    dev.args: { bg: "transparent" }
```{python}
fig.patch.set_facecolor("#FFFFFF00")
plt.axes().set_facecolor("#FFFFFF00")
```

Highlighting code

Line by line, for free

code-line-numbers takes the lines you want lit up, and | splits it into steps.

my-deck.qmd

```{.r code-line-numbers="|1|2-3|4"}
library(ggplot2)
mtcars |>
  ggplot(aes(mpg, disp)) +
  geom_point()
```

The same for a computed chunk

my-deck.qmd

```{r}
#| echo: true
#| code-line-numbers: "|1|2-3|4"
library(ggplot2)
mtcars |>
  ggplot(aes(mpg, disp)) +
  geom_point()
```

A leading | means the first step is the whole block with nothing highlighted.

When the highlighter is not enough

Sometimes you want to point at one argument, in your own color, at your own pace.

  • The code is not really code, it is a picture of code
  • A .mono class gets you the look
  • Spans and fragments get you the highlighting

One class

styles.scss

/*-- scss:rules --*/
.mono {
  font-family: monospace;
  font-size: 0.9em;
}

Then put the code in a div with that class. \ gives you a leading space, and two trailing spaces end a line.

Highlight what you want, when you want

my-deck.qmd

::: mono
library([ggplot2]{style="color:purple;"})
mtcars |>
\ \ ggplot(aes(mpg, disp)) +
\ \ geom_point() +
\ \ geom_smooth([method = "lm"]{.fragment .highlight-red},
[formula = "y ~ x"]{.fragment .highlight-blue})
:::

Your turn

Exercise

  1. Take a slide with too much on it and split it into two columns
  2. Add a photo as a background image, with one line of text on top of it
  3. Give that text a box so it is readable
  4. Halve the fig-width on a plot and see what happens to its text

Thank you

Back to the workshop materials.