htmx Tutorial · User Feedback · Lesson 15 of 30

Animations and Transitions

Fade new content in and old content out with the CSS classes htmx adds during swaps, and use View Transitions.

Create a free account to save this page, take notes and track your progress. Sign in

The classes htmx adds

Class When
htmx-request on the requesting element during the request
htmx-swapping on the target before the swap (lasts for the swap: delay)
htmx-added on new content before it settles
htmx-settling on the target during the settle phase

Combined with CSS transitions, they give smooth animations with no JavaScript.

Fade out, then remove

hx-swap="outerHTML swap:500ms" waits 500 ms before swapping. During that time the element has htmx-swapping, so a CSS transition can fade it out:

Fade out before removingTry it yourself
<style>.row { transition: opacity 500ms; } .row.htmx-swapping { opacity: 0; }</style>
<div class="row">Notification 1 <button hx-delete="/n/1" hx-target="closest .row" hx-swap="outerHTML swap:500ms">Dismiss</button></div>
<div class="row">Notification 2 <button hx-delete="/n/2" hx-target="closest .row" hx-swap="outerHTML swap:500ms">Dismiss</button></div>

<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
  server.delete("/n/:id", () => "");
</script>

Smooth changes between versions

htmx keeps the id of elements between the old and new content and copies the old attributes first, then applies the new ones after a short settle delay. So if the new element has the same id and a different class or style, a CSS transition runs between them:

A CSS transition between old and newTry it yourself
<style>#bar { height: 18px; background: #0ea5e9; transition: width 600ms ease; }</style>
<div style="border:1px solid #ccc;width:300px"><div id="bar" style="width:10%"></div></div>
<button hx-get="/progress" hx-target="#bar" hx-swap="outerHTML">Make progress</button>

<!-- The pretend server: on a real site this part is your backend (Python, PHP, Node, Go...) -->
<script>
  let pct = 10;
  server.get("/progress", () => {
    pct = pct >= 100 ? 10 : pct + 30;
    return `<div id="bar" style="width:${Math.min(pct, 100)}%"></div>`;
  });
</script>

View Transitions

hx-swap="innerHTML transition:true" uses the browser's View Transitions API, which cross-fades the old and new content (in supporting browsers, with a normal swap elsewhere).

Test yourself

What does hx-swap="outerHTML swap:500ms" give you time to do?

  1. Run a CSS fade-out while the element has the htmx-swapping class
  2. Cancel the request
  3. Load a second response
  4. Retry a failed request
Show answer

Answer: Run a CSS fade-out while the element has the htmx-swapping class

The swap delay keeps the old element in place with htmx-swapping, so a transition can play.

Was this page helpful?