My daughter is learning about the solar system and other bits of astronomy in school, so I thought it would be fun to create a little CSS animation that shows how the orbits work. I found this image on Dribbble that I really liked the look of, and decided to recreate it in CSS. This served well enough to explain to her how much smaller than the sun we are, and the Earth’s place in the solar system. Right now of course, these orbits and sizes are not at all to scale, but maybe someday!
Everything is enclosed in a universe div, to give a central point for the absolutely positioned elements. Next we create the sun and planets markup. Why am I using
<span> for the planets but
<div> for the sun? When I was doing it, I thought that having the orbiting planets being line level elements would be helpful. It turns out the animation was much easier than I thought so it didn’t impact things, and I didn’t notice it until I was writing up this blog post. Considering they are different types of space elements, I’m going to say it’s a semantic decision. Stellar semantics, if I do say so myself.
Sorry about that, I hope you didn’t choke from laughing at my dazzling pun.
Alrighty now the fun part: CSS. We want to set styles for all the children of the universe (sounds like a new age band). Absolute positioning is our friend here, since we want everything to be centered on the sun. We’ll also set a border-radius to make them all circles.
To mimic the orbital path seen in the concept, we set all the planets to have a transparent background with a 1px border. Next, it’s time to create the Sass loop to write the actual planet CSS. Create the arglists for planet sizes and colors to give some variation (if you want everything uniform, change the variables to single values instead or replace the list args with a single arg). We want to set this loop on a planet’s pseudo element.
At first, I was trying to use the
<span> element for the planet itself and a pseudo element for the orbital path, then animate that around a circle. While that’s totally possible, it turned out to also be totally unnecessary. Instead, I’m using the
<span> for the orbital path and a pseudo element for the planet itself. By default, pseudo elements appear on the “edge” of their parent elements (after a reset of course); doing it the other way means you’re writing a ton of CSS just to make the element animate around a central point.
Speaking of the animation, it’s simply rotating the entire element from 0-360deg; since the element is currently round it results in the pseudo element “orbiting” in a circle. If the element were square you’d see what would look like a square rolling across the screen instead. We create another Sass loop to give different values to animation-delay and animation-duration on the orbital path element. A negative value in the delay attribute make the animation start in the middle of the animation; this keeps us from having a “line” of planets before the animation starts. We could achieve similar results by staggering the rotate start and end points in the animation, but that many different animations would be a performance hit.
It’s not as responsive as some of my other work and as I said before it’s absolutely not to scale, but then again, it’s just a little animation to explain orbital paths to my grade school daughter. And to fuck around on CodePen.