decktalk schema page prints the whole attribute table with each value, default, range and the
finding it raises. Read it beside this page rather than guessing an attribute name.
The canvas is the frame’s shape
The runtime builds a canvas element,#dt-canvas, scales it to fit the window and centres it. The
canvas has the shape of the project’s frame, [video] size, and a short side of 1080 CSS pixels:
1920 by 1080 for wide, the default, 1080 by 1080 for square and 1080 by 1920 for vertical. A
size written in your stylesheet is therefore a size on the video frame. A page may supply its own <div id="dt-canvas"> and the runtime will use that one, which is
how a deck puts one figure under all of its slides.
Place every element absolutely, so one reveal never moves another. Both packaged decks do this.
deck/index.html
:root as --dt-width and --dt-height, and its shape as
data-dt-shape, which is wide, square or vertical. The starter lays every box out across
--dt-width, and stacks its slides for a square or vertical frame under a :root:not([data-dt-shape="wide"])
rule, so a square copy of a project is the project copied with size = "square" and nothing else
changed.
Keep every cued element out of the bottom 192 px of the canvas, where two lines of caption sit above a
margin. A player draws captions there, so an element that arrives in that band can be covered at the moment it
arrives. The starter’s lowest band sits at
top: 720px and ends about 840 px down, clear of it.
Keep a slide to about four reveals. A derivation that needs more starts a second slide.
[video] size also takes a width and a height in pixels, such as "1280x720". The page is laid
out on the canvas of that shape, so a smaller or larger frame of one shape draws the same slides at
another resolution, and a frame of another shape lays the page out again by its own rules.Describe every cued element
The transcript, the audio description and every reader who cannot see the picture are written fromdata-describe. It is a noun phrase naming the subject of the reveal, and the runtime supplies the
verb for each moment: an arrival “appears”, a step back “steps back”, a return “comes to the front”
and a departure “leaves”.
deck/index.html
data-describe and draws no text of its own earns
PAGE_NO_DESCRIPTION, which is an error. A shape with no
words in it is the usual cause, because a filled block is the one kind of reveal that is easy to see
and impossible to read.
Three attributes go with it.
data-describe=""is a decorative element, said out loud in the markup. An empty description clears the finding and writes no transcript line.data-describe-outreplaces the departure sentence when leaving means something of its own, such as the lesson’sdata-describe-out="the hand-written rules drop away".data-describe-classgives a description to each class change, ascue:descriptionpairs separated by a vertical bar. Adata-classchange with no description beside it earnsPAGE_CLASS_UNDESCRIBED, because the transcript would otherwise lose the change entirely.
Make the change large enough to measure
DeckTalk compares two frames on brightness alone. A pixel counts as changed when its luma differs by more thanverify.probe_diff_luma, which is 40 out of 255 by default, and what is judged is the
share of the frame those pixels cover.
On a 1920 by 1080 frame, 0.3 percent is about 6,220 pixels and 0.1 percent about 2,073, which is
roughly an eighty by eighty solid block and a forty-six by forty-six one. Design against the larger
number, because a reveal that only just clears the floor on a frozen frame can fall under it once the
encoder has been over it.
Three consequences follow from comparing luma and nothing else.
- A colour swap of the same lightness changes nothing. It is also invisible to a viewer with low vision. Change the lightness as well as the hue.
- A line of text is too thin. A line of 44 px type is a few hundred pixels of ink. Give a small reveal a filled container that arrives with it, which is why both packaged decks reveal filled cards, pills and bands rather than text on white.
- An outline is too thin. Fill the shape.
verify.probe_diff_luma does not help, and its published hazard says why: a high value counts
only a change that crosses most of the range, so a reveal that fades in, or a light element on a light
slide, reads as no change at all.
Keep every motion under half a second
MEASURABLE_SPAN_SECONDS is 0.5, and it is the one ceiling the page contract is built around. A cue
still moving half a second after it fires cannot be measured, because that is the frame the next cue
is read from. No value any attribute admits can reach it on its own.
The entrance
data-in-style is the closed word that says how an element arrives, and each word declares its own
length.
data-in-seconds overrides that length. It runs from 0.12 to 0.44 in steps of 0.04, which is three
to eleven frames at 25 fps, the slowest rate a film is recorded at, and a value off that grid earns
PAGE_BAD_VALUE. It governs the entrance alone and never when
the entrance starts.
An element whose measured motion still runs past 0.5 seconds earns
PAGE_MOTION_OVERRUN, which is an error. Since the longest
entrance a page may write is 0.44 seconds, the two ways to reach it are motion.scale above one and
a staggered container.
The stagger
data-stagger spreads one cue across a container’s children, from 0.04 to 0.2 seconds apart in steps
of 0.04. The total is exact arithmetic: the last child starts one step per earlier child after the
cue, then plays its own entrance.
fade entrance, so its total is
0.04 × 3 + 0.24, which is 0.36 seconds and clears the ceiling.
deck/lesson.html
draw entrance would total 0.2 × 3 + 0.44, which is 1.04 seconds,
and DeckTalk measures that exactly and reports
PAGE_STAGGER_OVERRUN as an error. Fix it by
shortening the step, choosing a shorter entrance, or splitting the container across two cues.
A container that carries data-stagger and has no children spreads one entrance over nothing, which
is PAGE_STAGGER_EMPTY.
The other spans
data-words="appear" shows a line one word at a time from nothing, and a line of more than eight
words takes longer than one cue can carry, which earns
PAGE_APPEAR_TOO_LONG. Shorten the line, or use
highlight, which starts every word dim and brightens each one as it is said.
Honour reduced motion
motion.reduce renders the whole film as the variant a viewer who asks for less motion should be
given. The recorder asks Chromium for a page that prefers reduced motion, the runtime puts the class
dt-reduced on the root element, and every entrance the runtime owns becomes a plain fade with no
travel, no scale and no overshoot. The film keeps its length, its captions and its cue times, so the
reduced build and the ordinary build are the same film with the motion taken out.
motion.scale is the companion
setting, a multiplier from 0.25 to 4 on every declared span. A scale that carries a span past half a
second earns PAGE_MOTION_OVERRUN, so slowing a deck down is judged like any other overrun.
The runtime can only reduce the motion it owns. A data-class hands the change to the page’s own
stylesheet, and that stylesheet owes the reduced form. The lesson example writes both halves.
deck/lesson.html
data-class, and reads the longest
animation or transition the stylesheet gives that element. Under a reduced render, a class that still
animates earns PAGE_CLASS_NOT_REDUCED, which is
an error and names the class. It can only be raised under a reduced render, so judge the page that way
at least once:
Look at the slide before you record it
decktalk check judges the written files and the pages together, opens no recording, spends nothing
and prices what a voiced build would cost. It freezes each slide either side of each cue and reports
the changed share. Every finding on this page except PAGE_APPEAR_TOO_LONG, which needs the voice’s
clock and comes from record, comes out of that one command. --no-frames keeps
the browser and drops the freeze comparison, and --no-pages judges the written files with no
browser at all and then says which judgements it could not reach.
decktalk storyboard freezes every slide at every cue onto one page, build/storyboard.html, and
narrows to --section, --slide, --after, --before and --at. It is the human checkpoint
before anything is bought, and it is where unrendered maths, overlapping elements and text
running off the frame become obvious.
Next
- Copy a pattern that already ships: Slide recipes
- Write the page from nothing: Write a page by hand
- Choose the words the reveal lands on: Writing for the ear