alt alt

Skeleton: Make Your CSS Walk

Hey there, CSS fans! This is the third part of a 3D series. The first one is here, the second is here, start from there if you missed any of them.

Before your character takes a single step, there’s one thing it absolutely needs: a skeleton.

In CSS animation, the skeleton isn’t bones and cartilage — it’s HTML structure and transform-origin. It’s the thing that makes your character move like a character and not like a stack of divs having an existential crisis.

Watch video

Why Your Character Needs a Skeleton

Imagine animating a chicken. You want it to jump. You’ve already built it, colored it, and now… it’s time to move.

Without a skeleton, that means animating each part of the chicken individually. The head, the wings, the legs — all getting their own keyframes. It’s like micromanaging limbs in five timelines at once.

See animation madness to make this chicken just jump
@keyframes head {
  0%, 85%, 100% { translate: 0em 0em 0em; }
  20%, 80% { translate: 0em 0em -1em; }
  50%, 60% { translate: 0em 0em 5em; }
}
@keyframes beak {
  0%, 85%, 100% { translate: 2em 7em 4em; }
  20%, 80% { translate: 2em 7em 3em; }
  50%, 60% { translate: 2em 7em 8em; }
}
@keyframes wattle {
  0%, 85%, 100% { translate: 2em 7em 2em; }
  20%, 80% { translate: 2em 7em 1em; }
  50%, 60% { translate: 2em 7em 6em; }
}
@keyframes comb {
  0%, 85%, 100% { translate: 2em 2em 8em; }
  20%, 80% { translate: 2em 2em 7em; }
  50%, 60% { translate: 2em 2em 13em; }
}
@keyframes body {
  0%, 85%, 100% { translate: 0em -3em -5em; }
  20%, 80% { translate: 0em -3em -6em; }
  50%, 60% { translate: 0em -3em 0em; }
}
@keyframes tail {
  0%, 85%, 100% { translate: 1em -5em -5em; }
  20%, 80% { translate: 1em -5em -6em; }
  50%, 60% { translate: 1em -5em 0em; }
}
@keyframes wing-left {
  0%, 85%, 100% { translate: -2em 0em -4em; }
  20%, 80% { translate: -2em 0em -5em; }
  50%, 60% { translate: -2em 0em 1em; }
}
@keyframes wing-right {
  0%, 85%, 100% { translate: 6em 0em -4em; }
  20%, 80% { translate: 6em 0em -5em; }
  50%, 60% { translate: 6em 0em 1em; }
}
@keyframes knee-right {
  0%, 20%, 80%, 100% { translate: 5em 2em -8em; }
  50%, 60% { translate: 5em 2em -3em; }
}
@keyframes knee-left {
  0%, 20%, 80%, 100% { translate: 0em 2em -8em; }
  50%, 60% { translate: 0em 2em -3em; }
}
@keyframes foot-right {
  0%, 20%, 80%, 100% { translate: 4em 1em -9em; }
  50%, 60% { translate: 4em 1em -4em; }
}
@keyframes foot-left {
  0%, 20%, 80%, 100% { translate: -1em 1em -9em; }
  50%, 60% { translate: -1em 1em -4em; }
}
@keyframes finger-one {
  0%, 20%, 80%, 100% { translate: -1em 4em -9em; }
  50%, 60% { translate: -1em 4em -4em; }
}
@keyframes finger-two {
  0%, 20%, 80%, 100% { translate: 1em 4em -9em; }
  50%, 60% { translate: 1em 4em -4em; }
}
@keyframes finger-three {
  0%, 20%, 80%, 100% { translate: 4em 4em -9em; }
  50%, 60% { translate: 4em 4em -4em; }
}
@keyframes finger-four {
  0%, 20%, 80%, 100% { translate: 6em 4em -9em; }
  50%, 60% { translate: 6em 4em -4em; }
}

Now imagine that chicken needs to dance. No thanks.

A proper HTML skeleton saves you from this nightmare. It turns chaos into structure, and lets you focus on how your character moves — not how to keep it from falling apart.

The Chicken’s Skeleton

Let’s break down our chicken’s structure. Start from the body, then nest all the connected parts — like joints in real anatomy.

Each moving part is nested inside the one it’s attached to. Shoulder inside the body, arm inside the shoulder, hand inside the arm, finger inside the hand, and so on.

Want to add a hat? Drop it in the head element. A sword? Goes in the hand element. The HTML is the skeleton.

Let’s talk joints

Every animated element transforms (rotates) from one pont. In CSS, that point is transform-origin.

By default, it’s in the center of the element. But for a character, that’s usually wrong. Your chicken’s wing doesn’t flap from the middle. You’ll need to manually set the anchor point — usually at the joint.

Position transform-origin based on how the character would move in real life. It sounds like overkill — it’s not. It’s what makes movement feel natural.

Animation Magic

Here’s the cool part: when you nest joints correctly, you only have to animate one thing. If you don’t nest? You’re stuck micromanaging every angle on every frame. Nightmare.

Compare these two examples: the one you already saw before and the one with a proper nesting.

16 animation declarations to make this chicken just jump
4 animation declarations to make this chicken jump and flap wings

CSS animation doesn’t have to be hard — just smart.

Want That Wiggly, Spaghetti-Limb Vibe?

Want spagetti movement? Here’s a trick: create more joints for each body parts. I did it for a mosquito nose. It consists of a few joints connecting small nose parts. Nest them and place their transform-origin like with a normal character, and suddenly… you’ve got a sausage-shaped nose that bends like it’s made of rubber.

The more elements you add, the more rubbery it will look.

Demo Time

Let’s look at the simple cube characters dancing — powered by proper skeletons and smart nesting.

Takeaways

That’s the skeleton in a nutshell!

Share your demos on your favorite social media and tag me @julia_miocene.

Don’t forget to keep the web weird.