动画效果

htmx设计允许你使用CSS过渡 仅用CSS和HTML就能为网页添加平滑的动画和过渡效果。下面是一些不同动画技术的示例。

htmx还允许你使用新的视图过渡API 来创建动画。

🔗基础CSS动画

🔗颜色脉动

htmx中最简单的动画技术是在内容交换时保持元素的id稳定。如果元素的id保持稳定,htmx将以允许CSS过渡的方式交换它, 可以在元素的旧版本和新版本之间编写过渡效果。

考虑这个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">
  颜色交换演示
</div>

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

<div id="color-demo" class="smooth" style="color:blue"
      hx-get="/colors" hx-swap="outerHTML" hx-trigger="every 1s">
  颜色交换演示
</div>

由于div有一个稳定的idcolor-demo,htmx将以CSS过渡(定义在.smooth类上)应用于从redblue的样式更新, 并在它们之间平滑过渡。

🔗演示

颜色交换演示

🔗平滑进度条

进度条示例也使用了这种基础CSS动画技术,通过更新进度条元素的length属性, 实现平滑动画效果。

🔗交换过渡

🔗交换时淡出

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

<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">
        淡出我
</button>

🔗演示

🔗沉降过渡

🔗添加时淡入

基于上一个示例,我们可以通过在沉降阶段使用htmx-added类来淡入新内容。你也可以通过使用htmx-settling类, 针对目标而非新内容编写CSS过渡。

<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">
        淡入我
</button>

🔗演示

🔗请求中动画

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

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

🔗演示


🔗使用htmx class-tools扩展

通过使用class-tools扩展,可以创建许多有趣的动画效果。

这里有一个切换div透明度的示例。注意我们将切换时间设置为比过渡时间稍长。这样可以避免在过渡被类变化中断时可能发生的闪烁。

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

🔗演示

切换演示

🔗使用视图过渡API

htmx通过hx-swap属性的transition选项提供了对新的视图过渡API的访问。

下面是一个使用视图过渡的交换示例。过渡通过CSS中的view-transition-name属性与外部div绑定, 并使用::view-transition-old::view-transition-new定义过渡,使用@keyframes定义动画。 (关于视图过渡API的完整细节可以在Chrome开发者页面上找到。)

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

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

<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>初始内容</h1>
   <button class="btn primary" hx-get="/new-content" hx-swap="innerHTML transition:true" hx-target="closest div">
     交换它!
   </button>
</div>

🔗演示

初始内容

🔗结论

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