CSS Tutorial

CSS Animations

@keyframes plus animation-name run a sequence. Prefer transform and opacity for smoothness.

A sequence, not a one-shot

A transition needs a change — hover, focus, a class added in JavaScript. An animation does not. You name a sequence with @keyframes, attach it with animation-name, and the browser plays that sequence on its own: once, a few times, or forever.

Harbor studio might pulse a “desks free” badge, or fade a banner in when the page loads. Keep that kind of motion small. Animation that never stops fights reading. Prefer a short intro, then stillness.

@keyframes is the storyboard

Inside @keyframes you set stops. from and to are 0% and 100%. You can add extra percentages if the motion has a middle pose. The animation name is yours — a word with no spaces.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  @keyframes rise-in {
    from {
      opacity: 0;
      transform: translateY(12px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
  .card {
    max-width: 18rem;
    padding: 1rem 1.2rem;
    background: #fff;
    border: 1px solid #7dd3fc;
    border-radius: 0.75rem;
    animation-name: rise-in;
    animation-duration: 600ms;
    animation-timing-function: ease-out;
    animation-fill-mode: both;
  }
  h1 { margin: 0 0 0.4rem; font-size: 1.15rem; color: #0d9488; }
  p { margin: 0; color: #475569; }
</style>
<article class="card">
  <h1>Harbor studio</h1>
  <p>The card fades and lifts into place. Reload the preview to play it again.</p>
</article>

animation-fill-mode: both applies the 0% styles before the animation starts and keeps the 100% styles after it ends. Without it, the card can flash at full opacity, then jump back to the keyframe start.

Open this at /css/try and change translateY(12px) to 8px. The motion should stay on transform and opacity — those two paint cheaply. Animatingtop or height looks similar and costs layout every frame.

The animation properties

Name and duration are the minimum. Iteration, direction, delay, and fill-mode finish the control. There is a shorthand, but the longhands are easier to read while you learn.

PropertyJob
animation-nameWhich @keyframes block to play
animation-durationLength of one cycle
animation-timing-functionEasing inside each cycle
animation-iteration-count1, a number, or infinite
animation-directionnormal, reverse, alternate
animation-delayWait before the first cycle
animation-fill-modeKeep start or end keyframes outside the run

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  @keyframes pulse-ring {
    0%, 100% { transform: scale(1); opacity: 1; }
    50% { transform: scale(1.08); opacity: 0.7; }
  }
  .badge {
    display: inline-block;
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    background: #ccfbf1;
    color: #0f766e;
    font-weight: 700;
    font-size: 0.85rem;
    animation: pulse-ring 1.6s ease-in-out infinite;
  }
</style>
<h1>Harbor studio</h1>
<p>Three desks free this hour.</p>
<span class="badge">Open 8–16</span>

The shorthand animation: pulse-ring 1.6s ease-in-out infinite packs name, duration, easing, and iteration. Percentage stops at 0%, 50%, and 100% make a breathe-in, breathe-out loop. Pause it in your head before you ship: does a badge that never rests help, or distract?

Prefer transform and opacity

The compositor can often animate transform and opacity without recalculating text wrapping or neighbors. That is why a fade and a slide feel smoother than growing widthor shifting margin-left. Start every animation with those two properties. Reach for layout properties only when the motion cannot be faked with a transform.

Example

<style>
  body {
    font-family: system-ui, sans-serif;
    color: #0c4a6e;
    background: #f0f9ff;
    margin: 1.25rem;
  }
  @keyframes slide-label {
    from { transform: translateX(-0.75rem); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
  }
  .hours {
    display: inline-block;
    padding: 0.5rem 0.85rem;
    background: #0ea5e9;
    color: #fff;
    border-radius: 0.4rem;
    animation: slide-label 500ms ease-out both;
  }
</style>
<p class="hours">Print shop · Harbor Lane 12</p>

Infinite animation plus a large blur or a changing box-shadow can make a laptop fan spin. Keep loops tiny. And honor prefers-reduced-motion: reduce — set animation: none so the final keyframe is just the resting style.

Transition or animation?

If the motion is a reaction — hover, focus, a class toggle — use a transition. If the motion is a timeline that should play by itself, use @keyframes. You can combine them: a card animates in on load, then transitions on hover. Two tools, two jobs.

Worked examples

The short listings above show one property. These sheets paint documents you would actually ship: a lab dashboard, a clinic form, a marks table, a nav bar.

CSS does not invent meaning. HTML already said what the pieces are. Cascade, specificity, and the box model decide how they look. The numbers are classroom values — current, pH, pulse, 3-4-5 — so the style has something real to sit on.

Preview them in the CSS editor at /css/try. Change one property and watch the page paint. The tags stay the same.

Engineering

A live pulse on the logger

@keyframes names a sequence. animation-name plus duration plus iteration runs it. alternate with infinite is a pulse. Prefer opacity and transform.

Respect prefers-reduced-motion in real work: turn the pulse off when the user asked for less motion. This demo is the grammar only.

Example

<style>
  @keyframes pulse {
    from { opacity: 0.45; }
    to { opacity: 1; }
  }
  .live { animation: pulse 1.2s ease-in-out infinite alternate; color: #0d9488; }
</style>
<p class="live">● logging</p>

Astronomy

A slow fade on a title

A one-shot fade uses iteration-count: 1 and forwards so the last keyframe sticks. Infinite on a heading is a headache.

Example

<style>
  @keyframes in {
    from { opacity: 0; }
    to { opacity: 1; }
  }
  h1 { animation: in 0.8s ease forwards; color: #5b21b6; }
</style>
<h1>Mars</h1>

FAQ: CSS Animations

Common questions about this page.

What is the StudyGrid CSS tutorial?

The StudyGrid CSS tutorial is a full beginner track: selectors, the box model, text, layout, flex, grid, and responsive design. Each chapter has copy-and-preview examples.

Should I run css animation examples locally for better learning?

Yes. Use the browser editor on StudyGrid for a quick check, then Download the example and run it on your computer. Local runs show real errors and the real toolchain, which is one of the fastest ways to learn css animation in this CSS CSS lesson (CSS Animations).

Is the CSS editor the same as Try HTML?

No. Try CSS is a stylesheet preview at /css/try. Try HTML stays at /html/try. CSS lessons never open the HTML-only editor or the Python editor.

Do I need to install anything to learn CSS?

No. Open a chapter, click Try it in CSS, and the page preview updates in the browser.

Where should I start the CSS tutorial?

Start at CSS Intro, then Syntax, Selectors, and How To. After colors and the box model, continue to flex, grid, and media queries. Use Next at the bottom of each chapter.

Is the CSS tutorial free?

Yes. The CSS studio on StudyGrid (studygrid.in) is free: dashboard, chapters, and the live preview editor.