Build
Animations
Fade elements in as they're seen, and menus and panels in and out, without writing CSS or a script.
Marketing pages lean on a little motion: a headline that fades up as the page opens, features that appear one after another as you scroll to them, a menu that drops in instead of popping. In Mockly these are attributes. You don't write CSS keyframes or a script, and the content is never left hidden.
Reveal as it's seen#
Add reveal to any element. It plays the first time the element comes into view, as the page opens or as you scroll to it, and then stays put:
<h1 reveal="fade-up">Invoicing for small studios</h1>reveal | What it does |
|---|---|
"fade" | Fades in. |
"fade-up" | Fades in, rising 1.5rem into place. |
"fade-down" | Fades in, coming down 1.5rem into place. |
"fade-left" | Fades in, moving 1.5rem left into place. |
"fade-right" | Fades in, moving 1.5rem right into place. |
"zoom" | Fades in, growing from 95% of its size. |
Each takes 0.6 seconds and slows as it ends.
One after another#
Add stagger beside reveal to animate the element's children instead, one after another. It's the time between each one, in milliseconds:
<ul class="grid grid-cols-3 gap-6" reveal="fade-up" stagger={80}> <li>Quotes</li> <li>Invoices</li> <li>Reminders</li></ul>The first child starts as the list comes into view, the second 80 ms later, and so on, up to a second after the first. Children a changing list adds later animate as they arrive.
Never hidden#
The elements wait, hidden, only where they'll play. Everywhere else they show as they are, from the start:
- for visitors who ask for reduced motion in their system settings
- without JavaScript, and in browsers too old to tell
- in print
- if the page's script hasn't started within 3 seconds, say on a slow connection
Search engines read the text as they always do. Only pages with reveal load the code that plays it, a few hundred bytes.
In the studio, the page shows everything while you edit it, and plays the animations in Preview.
Menus and panels#
An island's <Show> shows and hides its markup at once. Give it a transition and it comes and goes smoothly instead:
import { Show, state } from "mockly"; export function Menu() { const open = state(false); return ( <nav class="relative"> <button type="button" aria-expanded={open.value} onClick={() => { open.value = !open.value; }}> Menu </button> <Show when={open.value} transition="fade-down"> <ul class="absolute right-0 mt-2 rounded-lg bg-white p-2 shadow-lg"> <li><a href="/pricing">Pricing</a></li> <li><a href="/docs">Docs</a></li> </ul> </Show> </nav> );}transition | For |
|---|---|
"fade" | Anything: fades in and out. |
"fade-down" | A dropdown or menu: drops in from just above. |
"fade-up" | A tooltip or a toast: rises from just below. |
"zoom" | A popover or a dialog: grows from 95%. |
"slide-left" | A panel from the right edge. |
"slide-right" | A panel from the left edge. |
"slide-up" | A sheet from the bottom. |
"slide-down" | A banner from the top. |
It comes in over 0.2 seconds (0.3 for the slides) and goes a little quicker. While it leaves, it stays on the page; it's hidden once it's gone. With a fallback, the two take turns: the fallback enters once the markup has left, so they never show at once. Clicked again while it's leaving, it comes straight back.
With reduced motion, it comes and goes at once, as without transition.
The slides move the panel by its own size, so position it at the edge it comes from, for example fixed inset-y-0 right-0 w-80 for slide-left.
Rules#
| Rule | Code |
|---|---|
reveal is one of the names above, as a string. | MK2017 |
stagger is a whole number of milliseconds from 1 to 1000, written out, on an element with reveal. | MK2017 |
transition is one of the names above, as a string, on a <Show> whose when reads state. | MK2018 |