# Exercise: An Animated Game Start Screen

Bring Star Hopper's start screen to life with twinkling stars, a title that slides in, buttons that lift on hover and focus and a looping loading bar, then calm it all for reduced motion, while the tests check every rule.

Journeyman · CSS · Updated October 30, 2026

*Star Hopper* is a made-up space game, and its start screen is ready except for one thing: nothing moves. The stars are frozen dots, the title sits still, the buttons don't answer when you point at them, and the loading bar is a full stripe that never loads. A game's first screen sets the mood, and motion is how this one should say "the galaxy is alive, press Start". Your job is the motion, all of it in CSS, and then a calmer version of it for players who asked their device for less. Tests check each part as you go.

## Get the exercise code

In the **Exercise** box beside the lesson, choose **Get the starter on GitHub** to open its GitHub repository. Click **Code**, then **Download ZIP**, and unzip it into your `css-in-depth` folder. Then open the folder in VS Code.

The folder holds:

- `index.html`: the start screen: twelve stars, the title, a tagline, the Start, How to play and High scores buttons, and the loading bar. Ready to use: don't change it.
- `styles.css`: Part 1 is the look of the screen, ready to use. Part 2 is where your motion goes. For you to finish.
- `page.test.js` and `package.json`: the tests that check your rules. You don't need to change these.
- `README.md`: the same steps as this lesson, and the checklist of what to watch for.

Everything you need is in the folder: the page and its look are handed over, so you can spend your time on the motion.

## What to do

Open `index.html` with Live Server first. Here's the part of the page you'll animate, as it is in the HTML you were given:

```html
<h1 class="title">Star Hopper</h1>

<nav class="menu" aria-label="Game menu">
  <button class="menu-button start-button" type="button">Start</button>
  <button class="menu-button" type="button">How to play</button>
  <button class="menu-button" type="button">High scores</button>
</nav>

<div class="loading" role="status">
  <p class="loading-label">Loading the galaxy…</p>
  <div class="loading-bar">
    <div class="loading-fill"></div>
  </div>
</div>
```

The stars are twelve `<span class="star">` elements in a `<div class="sky">` behind everything. Part 1 already gives each star its place and its own `animation-delay`, so they'll twinkle at different times once they have an animation.

Write each part in Part 2 of `styles.css`, saving and watching the page after each one:

1. **Twinkling stars.** A `@keyframes` rule takes a star from dim to bright (with `opacity`, and `scale` if you like). Play it on `.star`: about 1.5 seconds, forever, going back and forth.
2. **A title that slides in.** A `@keyframes` rule starts the title 3rem above its place and see-through. Play it on `.title` once: about 0.7 seconds, `ease-out`, starting 0.3 seconds after the page opens. During those 0.3 seconds the title waits, hidden, at its starting point, so it never jumps.
3. **Buttons that lift.** When a menu button is hovered or has keyboard focus, it moves 4px up with `translate` and its shadow grows. A transition on `.menu-button` makes the lift take about 150ms, up and back down.
4. **A loading bar.** A `@keyframes` rule grows `.loading-fill` from nothing to its full width with `scale` (not `width`), from its left edge, about every 2 seconds, forever.
5. **Motion that respects the reader.** After your other rules, a `@media (prefers-reduced-motion: reduce)` rule stops the stars and the loading bar, swaps the title's slide for a short fade (or no animation), and keeps the buttons still on hover and focus.

Every `@keyframes` rule animates only `transform` (`translate`, `rotate`, `scale`) and `opacity`.

## Check your work

Open a terminal in VS Code (**Terminal > New Terminal**) and run `npm install` once, to download what the tests need. After that, run the tests whenever you like:

```bash
npm test
```

At first, the first test passes (the page is already there) and the other nine fail. Each part you finish turns its tests green. A failing test's message says what it found, for example *.title has animation-fill-mode none, so during the 0.3s delay it sits in its normal place, then jumps up to start sliding.*

The tests read your rules; they can't watch anything move. So reload the page and watch it too, and then turn on reduced motion in the developer tools' Rendering panel (from *Motion That Respects the Reader: prefers-reduced-motion*) and watch it again. The README's checklist says what to look for.

## Hints

- **An animation that doesn't play** is nearly always a name in `animation` that doesn't match its `@keyframes` name exactly, or a missing duration. *Keyframe Animations* lists both.
- **Two times in one line.** In `animation` and in `transition`, the first time is the duration and the second is the delay.
- **A title that jumps before it slides** needs a fill mode. Which one shows the first frame during the delay?
- **A lift that snaps back down** has its transition on the hover rule. *Transitions: Smooth Changes* shows where it belongs.
- **A bar that grows from the middle** is growing around its center. *Transforms: Move, Turn and Grow* shows how to move the point it grows from.
- **Reduced motion that changes nothing?** A media query adds no specificity, so check where yours sits in the file.

## When you're done

Every test is green, and `npm test` prints:

```text
> exercise-css-game-start-screen@1.0.0 test
> node --test

✔ 1) index.html links styles.css, and has the start screen (1.7841ms)
✔ 2) the stars twinkle: a @keyframes animation on .star that plays forever (5.4028ms)
✔ 3) the title slides in once, after 0.3 seconds, with no jump (0.7118ms)
✔ 4) the loading bar fills again and again, with scale, not width (0.5371ms)
✔ 5) every @keyframes rule animates only transform and opacity (0.1688ms)
✔ 6) every menu button lifts on hover and on keyboard focus (3.2172ms)
✔ 7) the lift is a transition on .menu-button, so it runs up and back down (1.7919ms)
✔ 8) styles.css has a prefers-reduced-motion media query (0.1118ms)
✔ 9) with reduced motion, the stars and the loading bar stop looping (1.0445ms)
✔ 10) with reduced motion, the title and the buttons don't move (2.1469ms)
ℹ tests 10
ℹ suites 0
ℹ pass 10
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 707.946
```

Your times will differ. Now look at your screen with reduced motion on. Is there still something that tells a player the galaxy is loading? If the bar is still, what could the label or a gentle fade do instead?

## So what

A spinner that says "wait", a button that says "you're on me", a title that says "welcome": you've written the motion games and apps use everywhere, kept it smooth with `transform` and `opacity`, and made sure it never makes a player feel sick.

## What Module 6 unlocks

You can now design a page from a blank file: lay it out, make it fit any screen, give it a look, a theme and motion. Module 6 is about CSS on a real team. You'll learn to name and organize styles so other people can work with them (and so you can, six months later), how to decide whether a framework such as Bootstrap or Tailwind is worth it for a project, and how to find and fix a broken layout fast with the developer tools. It's the module that turns "I can write CSS" into "I can work on anyone's CSS".

## Key terms

- [Keyframe animation](https://www.ask-codey.com/glossary/keyframe-animation)
- [Transition](https://www.ask-codey.com/glossary/transition)
- [Translate](https://www.ask-codey.com/glossary/translate-css)
- [Animation fill mode](https://www.ask-codey.com/glossary/animation-fill-mode)
- [prefers-reduced-motion](https://www.ask-codey.com/glossary/prefers-reduced-motion)

## Related

- [Transitions: Smooth Changes](https://www.ask-codey.com/lessons/css-transitions)
- [Transforms: Move, Turn and Grow](https://www.ask-codey.com/lessons/css-transforms)
- [Keyframe Animations](https://www.ask-codey.com/lessons/css-keyframe-animations)
- [Motion That Respects the Reader: prefers-reduced-motion](https://www.ask-codey.com/lessons/css-reduced-motion)

Source: https://www.ask-codey.com/lessons/exercise-css-game-start-screen
