THE REFERENCE ROOM

Type in motion.

Use movement to direct attention. These short sequences run once; rerun a preview to replay. Respect reduced-motion preferences and keep the words available.

Hover transitions

Hover transitions

Duration controls length; delay offsets the start; timing shapes acceleration. An iteration count of 1 keeps the sequence finite.

<h1><span>Down</span> <span>the</span> <span>Rabbit-Hole</span></h1>
Edit HTML
h1 {
  transition: color .3s ease, transform .3s ease;
}
h1:hover {
  color: #FF1493;
  transform: rotate(-3deg) scale(1.05);
}
p {
  animation: enter 1s ease-out .2s both;
}
@keyframes enter {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  h1 { transition: none; }
  p { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
Edit CSS

Try this → Hover the title. Try .8s instead of .3s.

Rotate, scale, move and fade

Rotate, scale, move and fade

Duration controls length; delay offsets the start; timing shapes acceleration. An iteration count of 1 keeps the sequence finite.

<h1><span>Down</span> <span>the</span> <span>Rabbit-Hole</span></h1>
Edit HTML
h1 { animation: tumble 2s ease-in-out 1 both; transform-origin: left center; }
@keyframes tumble {
  from { transform: translateX(-20px) rotate(-8deg) scale(.8); opacity: .2; }
  to { transform: translateX(0) rotate(0) scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
Edit CSS

Try this → Change transform-origin to center. Compare ease-in-out and linear.

Staggered words

Staggered words

Duration controls length; delay offsets the start; timing shapes acceleration. An iteration count of 1 keeps the sequence finite.

<h1><span>Down</span> <span>the</span> <span>Rabbit-Hole</span></h1>
Edit HTML
span { display: inline-block; animation: rise 1s ease-out both; }
span:nth-child(2) { animation-delay: .2s; }
span:nth-child(3) { animation-delay: .4s; }
@keyframes rise { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
Edit CSS

Try this → Increase each delay to .5s.

Perspective

Perspective

Duration controls length; delay offsets the start; timing shapes acceleration. An iteration count of 1 keeps the sequence finite.

<h1><span>Down</span> <span>the</span> <span>Rabbit-Hole</span></h1>
Edit HTML
body { perspective: 600px; }
h1 { animation: depth 2s ease-in 1 both; transform-origin: center; }
@keyframes depth { from { transform: rotateY(-25deg) translateZ(-200px); } to { transform: rotateY(0) translateZ(0); } }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
Edit CSS

Try this → Try 300px perspective and compare the depth.

Click to animate

A deliberate trigger

A button controls when the CSS animation runs.

<button type="button" id="trigger">Try it</button>
<p id="message">Down the Rabbit-Hole</p>
Edit HTML
.highlight { background: #7FFF00; padding: 20px; }
.enter { animation: enter .8s ease-out; }
@keyframes enter {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .enter { animation: none; }
}
Edit CSS
const message = document.querySelector("#message");
document.querySelector("#trigger").addEventListener("click", () => {
  message.classList.remove("enter");
  requestAnimationFrame(() => {
    requestAnimationFrame(() => message.classList.add("enter"));
  });
});
Edit JAVASCRIPT

Try this → Change the keyframe duration and replay.