typodojo.js docs
words that move, on any page.
One script tag, then attributes on the words you want to move. No build step, no framework. Every moving word on this page uses the attributes shown beside it.
Start.
Add the script once, anywhere on the page. Then mark any element with data-typo and the name of a motion.
hello
The text stays in the page, so screen readers and search engines read it as usual. Strokes take the element's text color and size, so your CSS still decides how it looks.
Motions.
Seven are built in. Each plays once when the word scrolls into view; tap a word or press Replay to see it again.
write
ink
weight
wave
bounce
rise
type
| Motion | What happens |
|---|---|
| write | Each letter is written stroke by stroke, in the order a hand would write it. |
| ink | The ink spreads from nothing, swells past full weight, then settles. |
| weight | The strokes swell and settle. Loops well. |
| wave | A wave runs through the letters. Loops well. |
| bounce | Letters drop in and bounce once. |
| rise | Letters rise into place from just below. |
| type | Letters appear one at a time, like a typewriter. |
Fonts.
Words are drawn from real pen strokes. Three house fonts are built in; your own fonts from the studio work the same way, and self moves the font your page already uses.
display
nib
textura
your own font
| data-typo-font | Letters |
|---|---|
| display | Typo Display, one round pen. The default. |
| nib | Typo Nib, a broad nib held at one angle. |
| textura | Typo Textura, blackletter, minim by minim. |
| self | The element's own font, as live text. Works with wave, bounce, rise and type, which move whole letters. |
| a link | Your font from the studio: open Make it move, press Strokes for typodojo.js, host the file beside your page and link to it. |
Settings.
Every setting is an attribute on the same element. Leave any of them out and the motion's own default is used.
slow and steady
| Attribute | Values | What it does |
|---|---|---|
| data-typo | a motion or a recipe | What the word does. |
| data-typo-font | display, nib, textura, self, a link | Which letters move. |
| data-typo-duration | milliseconds | How long the whole word takes. |
| data-typo-stagger | milliseconds | The delay between one letter and the next. |
| data-typo-ease | smooth, snappy, springy, linear | How each letter arrives. |
| data-typo-loop | present or absent | Repeat, for wave and weight. |
| data-typo-play | view, load, hover | When it plays. The default, view, waits until the word scrolls in. |
| data-typo-motion | JSON | A motion saved in the studio, every setting at once. |
| data-typo-recipe | JSON | Your own recipe, checked with the market's rules before it plays. |
| data-typo-shadow | a font, then where | The same word behind, in another font. |
| data-typo-on | rules, or one kind | What the word answers. |
Interactions.
With data-typo-on a word answers what someone does to it. Each one has a keyboard way in, and the word can be reached with Tab.
hover
click
tap
hold
drag
focus
| data-typo-on | What it does | Keyboard |
|---|---|---|
| hover | The letters near the pointer rise and grow heavier. | Left and Right arrows |
| click | The word answers with a bounce, one letter after another. | Enter or Space |
| dblclick | It writes itself again, stroke by stroke. | Enter |
| context | Right click: the letters scatter and find their places again. | Enter or the menu key |
| press | A drop of ink where you touch, and the letters near it dip. | Enter or Space |
| hold | The longer you press, the heavier the ink. | Hold Space or Enter |
| drag | The letters follow the pointer in a line, each a little behind. | Arrow keys |
| scroll | The word gathers as it comes into view and loosens as it leaves. | Scrolling |
| focus | A brush stroke underlines it; type a letter it holds and that letter jumps. | Tab, then a letter |
| type | Sets what someone types into a field, each new letter landing. Name the field with data-typo-input="#id". | Typing |
Answers.
A word can answer several things, each in one rule: when this happens, play that. Write when:play, then which letters and how often if you like. Point at these, press them, or Tab to them and press Enter.
answer
deeper
| When it's | Write | Keyboard |
|---|---|---|
| pointed at | hover | Tab to it |
| pressed | press | Enter or Space |
| clicked | click | Enter |
| double clicked | dbl | Enter twice |
| held down | hold | Hold Space |
| dragged | drag | Arrow keys |
| reached with Tab | focus | It is the keyboard way |
| a key is typed | key-a, key-enter, key-space | Anywhere outside a field |
| in view, or the page opens | view, open | On its own |
| every few seconds | every-5s | On its own, 2 to 60 seconds, while in view |
Play is the id of any recipe in typodojo.js. Which letters: all (the default), near the pointer, or one. How often: always (the default) or once. A word answers at most six things, one rule per event. A letter still playing finishes first, so answers never fight. Every answer sends a typo:fire event you can listen for. One kind on its own, like data-typo-on="hover", works as in Interactions.
3D.
Recipes can move letters toward you or into the screen, and tilt them like a page or a door. Each letter becomes its own box, so the depth works in every browser. With reduced motion the word is drawn flat and finished.
swing in
flip up
Three channels do it: z (depth, in em), rx (tilt back) and ry (tilt sideways). A recipe can also give letters a body, their thickness, and a view, how far away the reader sits. Two rules keep it readable: every letter ends flat, facing you, and no letter faces away for long.
Shadows.
The same word behind itself, in another font. It is always lighter than the word, so the word reads first.
echo
two hands
Write the font first, then anything else in any order: where it falls (0.1em 0.08em, up to a quarter of a letter), depth -0.4 to push it back, light, mid or dark, lag 240 to follow a beat later, or still. The font is display, nib, textura, self, a link to your strokes file, or any open font by name: open:DM+Serif+Display. A letter the font lacks is drawn in Typo Display.
Typo.
Our dog is a font. Every letter is something he does: s sits, a stands alert, w wags, d lies down, j jumps, z sleeps, and 1 to 8 walk and run. Write words and he does them in order; the words stay real text for screen readers and search.
sit wag walk sleep
run jump
He plays when he comes into view and rests on the last pose; a click or Enter plays him again. Add data-typo-dog-loop to keep him going, or data-typo-dog-keys to let people walk him with the arrow keys once they click him: Shift runs, up jumps, down lies down. With reduced motion he changes pose without the in-betweens. Words he knows: sit, stand, walk, run, sleep, down, bark, wag, bow, look, shake, tilt, howl, sniff, crouch, jump, hello.
Recipes.
Recipes are motions and interactions people add from the market. Use one by its id, the same way as a built-in motion. These are in the version this page runs:
The format
A recipe is plain data the library plays, never code. Keys say where each letter is at a moment between 0 (start) and 1 (end); anything a key leaves out is at rest.
{
"id": "drift-up",
"name": "Drift up",
"by": "@typodojo",
"kind": "motion",
"on": "view",
"duration": 900,
"stagger": 60,
"ease": "smooth",
"order": "forward",
"keys": [{ "t": 0, "y": 0.4, "o": 0 }, { "t": 1 }]
}
| Field | Values |
|---|
| Channel | Means | Range | At rest |
|---|
The rules
Every recipe passes these before it joins, and the same checks run in your browser before you send one.
JavaScript.
Most pages never need it. For words added after the page loads, or to replay and check, typodojo.js has a small API on window.typodojo.
| Call | What it does |
|---|---|
| typodojo.scan(root) | Finds every data-typo and data-typo-on inside root (the whole page if you leave it out) and sets it up. Safe to call again. |
| typodojo.draw(el) | Draws one element now, without waiting for it to scroll into view. |
| typodojo.replay(el) | Plays an element's motion again from the start. |
| typodojo.recipes() | The recipes in this version, as data. |
| typodojo.check(recipe) | Checks a recipe against the rules and every recipe already in: { ok, problems, nearest }. |
| typodojo.version | The version number of the recipe library. |
| typodojo.recipe(id) | One recipe, or null. |
| typodojo.rules.parse(text) | Reads answers: { rules, problems }. rules.text(rules) writes them back, rules.say(rule) reads one as a sentence. |
| typodojo.shadow(text) | Reads a shadow, with its defaults, or { problems }. |
| typo:fire | An event from a word that answered: { when, play, who, via, letters }. |
Press Run.
Versions.
The library only grows. Each time recipes are added, there is a new version; nothing already published changes.
| Script | Use it when |
|---|---|
| typodojo.com/typodojo.js | You want new recipes as they arrive. Checked for updates within the hour. |
| typodojo.com/typodojo@1.js | You want a page that never changes. Pinned versions are cached for a year. |
Both can be loaded from any site. The whole library, house fonts included, is one file with no other requests unless you link a font of your own.
For everyone.
- Reduced motion. When someone has asked their device for less motion, every word appears finished and nothing moves.
- Readable. The word stays in the page as text, labeled for screen readers. Only the drawing moves, and every motion ends at rest.
- Keyboard. Every interaction can be reached with Tab and started without a pointer.
- Calm. No recipe flashes more than three times a second or hides the letters for long.
Try it.
Change the HTML and press Run. Only text elements and data-typo attributes are kept, so it is safe to paste anything.