动画

htmx 旨在允许你使用 CSS 转换 仅使用 CSS 和 HTML 向你的网页添加流畅的动画和过渡。以下是各种动画技术的几个示例。

¥htmx is designed to allow you to use CSS transitions to add smooth animations and transitions to your web page using only CSS and HTML. Below are a few examples of various animation techniques.

htmx 还允许你使用新的 查看转换 API 创建动画。

¥htmx also allows you to use the new View Transitions API for creating animations.

基本 CSS 动画

¥Basic CSS Animations

Color Throb

htmx 中最简单的动画技术是使元素的 id 在内容交换过程中保持稳定。如果元素的 id 保持稳定,htmx 将以某种方式交换它,以便在元素的旧版本和新版本之间编写 CSS 转换。

¥The simplest animation technique in htmx is to keep the id of an element stable across a content swap. If the id of an element is kept stable, htmx will swap it in such a way that CSS transitions can be written between the old version of the element and the new one.

考虑此 div:

¥Consider this div:

<style>
.smooth {
  transition: all 1s ease-in;
}
</style>
<div id="color-demo" class="smooth" style="color:red"
      hx-get="/colors" hx-swap="outerHTML" hx-trigger="every 1s">
  Color Swap Demo
</div>

此 div 将每秒轮询一次,并将被新内容替换,从而将 color 样式更改为新值(例如 blue):

¥This div will poll every second and will get replaced with new content which changes the color style to a new value (e.g. blue):

<div id="color-demo" class="smooth" style="color:blue"
      hx-get="/colors" hx-swap="outerHTML" hx-trigger="every 1s">
  Color Swap Demo
</div>

由于 div 具有稳定的 id,即 color-demo,因此 htmx 将构造交换,以便在 .smooth 类上定义的 CSS 转换适用于从 redblue 的样式更新,并在它们之间平滑过渡。

¥Because the div has a stable id, color-demo, htmx will structure the swap such that a CSS transition, defined on the .smooth class, applies to the style update from red to blue, and smoothly transitions between them.

演示

¥Demo

颜色交换演示

¥Color Swap Demo

平滑的进度条

¥Smooth Progress Bar

进度条 演示也使用这种基本的 CSS 动画技术,通过更新进度条元素的 length 属性,实现流畅的动画。

¥The Progress Bar demo uses this basic CSS animation technique as well, by updating the length property of a progress bar element, allowing for a smooth animation.

交换过渡

¥Swap Transitions

交换时淡出

¥Fade Out On Swap

如果你希望淡出将在请求结束时被删除的元素,你需要利用 htmx-swapping 类和一些 CSS 并将交换阶段延长到足够长的时间以使动画完成。可以这样做:

¥If you want to fade out an element that is going to be removed when the request ends, you want to take advantage of the htmx-swapping class with some CSS and extend the swap phase to be long enough for your animation to complete. This can be done like so:

<style>
.fade-me-out.htmx-swapping {
  opacity: 0;
  transition: opacity 1s ease-out;
}
</style>
<button class="fade-me-out"
        hx-delete="/fade_out_demo"
        hx-swap="outerHTML swap:1s">
        Fade Me Out
</button>

演示

¥Demo

¥

解决过渡问题

¥Settling Transitions

添加时淡入

¥Fade In On Addition

基于上一个示例,我们可以在解决阶段使用 htmx-added 类淡入新内容。你还可以使用 htmx-settling 类针对目标(而不是新内容)编写 CSS 转换。

¥Building on the last example, we can fade in the new content by using the htmx-added class during the settle phase. You can also write CSS transitions against the target, rather than the new content, by using the htmx-settling class.

<style>
#fade-me-in.htmx-added {
  opacity: 0;
}
#fade-me-in {
  opacity: 1;
  transition: opacity 1s ease-out;
}
</style>
<button id="fade-me-in"
        class="btn primary"
        hx-post="/fade_in_demo"
        hx-swap="outerHTML settle:1s">
        Fade Me In
</button>

演示

¥Demo

¥

请求飞行动画

¥Request In Flight Animation

你还可以利用 htmx-request 类,该类应用于触发请求的元素。下面是一个表单,提交时会改变其外观以指示正在处理请求:

¥You can also take advantage of the htmx-request class, which is applied to the element that triggers a request. Below is a form that on submit will change its look to indicate that a request is being processed:

<style>
  form.htmx-request {
    opacity: .5;
    transition: opacity 300ms linear;
  }
</style>
<form hx-post="/name" hx-swap="outerHTML">
<label>Name:</label><input name="name"><br/>
<button class="btn primary">Submit</button>
</form>

演示

¥Demo


使用 htmx class-tools 扩展

¥Using the htmx class-tools Extension

可以使用 class-tools 扩展创建许多有趣的动画。

¥Many interesting animations can be created by using the class-tools extension.

以下是切换 div 不透明度的示例。请注意,我们将切换时间设置为比过渡时间稍长。这可以避免因类更改而中断转换时可能发生的闪烁。

¥Here is an example that toggles the opacity of a div. Note that we set the toggle time to be a bit longer than the transition time. This avoids flickering that can happen if the transition is interrupted by a class change.

<style>
.demo.faded {
  opacity:.3;
}
.demo {
  opacity:1;
  transition: opacity ease-in 900ms;
}
</style>
<div class="demo" classes="toggle faded:1s">Toggle Demo</div>

演示

¥Demo

切换演示

¥Toggle Demo

使用视图转换 API

¥Using the View Transition API

htmx 通过 hx-swap 属性的 transition 选项提供对新 查看转换 API 的访问。

¥htmx provides access to the new View Transitions API via the transition option of the hx-swap attribute.

下面是使用视图转换的交换示例。过渡通过 CSS 中的 view-transition-name 属性与外部 div 绑定,并且该过渡根据 ::view-transition-old::view-transition-new 定义,使用 @keyframes 定义动画。(有关 View Transition API 的详细信息,请参阅 Chrome 开发者页面。)

¥Below is an example of a swap that uses a view transition. The transition is tied to the outer div via a view-transition-name property in CSS, and that transition is defined in terms of ::view-transition-old and ::view-transition-new, using @keyframes to define the animation. (Fuller details on the View Transition API can be found on the Chrome Developer Page on them.)

此过渡的旧内容应向左滑出,新内容应从右侧滑入。

¥The old content of this transition should slide out to the left and the new content should slide in from the right.

请注意,截至撰写本文时,视觉转换仅发生在 Chrome 111+ 上,但预计在不久的将来会有更多浏览器实现此功能。

¥Note that, as of this writing, the visual transition will only occur on Chrome 111+, but more browsers are expected to implement this feature in the near future.

<style>
   @keyframes fade-in {
     from { opacity: 0; }
   }

   @keyframes fade-out {
     to { opacity: 0; }
   }

   @keyframes slide-from-right {
     from { transform: translateX(90px); }
   }

   @keyframes slide-to-left {
     to { transform: translateX(-90px); }
   }

   .slide-it {
     view-transition-name: slide-it;
   }

   ::view-transition-old(slide-it) {
     animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out,
     600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left;
   }
   ::view-transition-new(slide-it) {
     animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in,
     600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right;
   }
</style>


<div class="slide-it">
   <h1>Initial Content</h1>
   <button class="btn primary" hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
     Swap It!
   </button>
</div>

演示

¥Demo

初始内容

结论

¥Conclusion

你可以使用上述技术在使用 htmx 时使用普通旧 HTML 创建相当多有趣且令人愉悦的效果。

¥You can use the techniques above to create quite a few interesting and pleasing effects with plain old HTML while using htmx.