Animation

Change of visual properties over time.

Animated chip

Property animated: position · 900ms

html

<div class="mot-anim-stage" data-property="position">
  <span class="mot-anim-chip mot-anim-chip--loop" style="background:#A8E6C1;">Animated chip</span>
</div>
<p class="mot-anim-caption">Property animated: <strong>position</strong> &middot; 900ms</p>
<style>
.mot-anim-stage { position: relative; width: 100%; max-width: 320px; height: 110px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; overflow: hidden; font: 14px/1.4 system-ui, sans-serif; color: #241430; }
.mot-anim-chip { position: absolute; top: 50%; left: 16px; transform: translateY(-50%); display: inline-block; padding: 8px 14px; border-radius: 999px; font-weight: 600; color: #241430; }
.mot-anim-caption { margin: 8px 0 0; font: 13px system-ui, sans-serif; color: #241430aa; }
@media (prefers-reduced-motion: no-preference) {
  [data-property="position"] .mot-anim-chip { animation: mot-anim-pos 900ms ease-in-out infinite; }
  [data-property="opacity"] .mot-anim-chip { animation: mot-anim-op 900ms ease-in-out infinite; }
  [data-property="colour"] .mot-anim-chip { animation: mot-anim-col 900ms ease-in-out infinite; }
  [data-property="scale"] .mot-anim-chip { animation: mot-anim-scale 900ms ease-in-out infinite; }
  .mot-anim-chip:not(.mot-anim-chip--loop) { animation-iteration-count: 1; animation-fill-mode: forwards; }
  @keyframes mot-anim-pos { 0%,100% { left: 16px; } 50% { left: 220px; } }
  @keyframes mot-anim-op { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
  @keyframes mot-anim-col { 0%,100% { background: #A8E6C1; color: #241430; } 50% { background: #241430; color: #FAF7F2; } }
  @keyframes mot-anim-scale { 0%,100% { transform: translateY(-50%) scale(1); } 50% { transform: translateY(-50%) scale(1.4); } }
}
</style>

tailwind

<div class="mot-anim-tw relative w-full max-w-[320px] h-[110px] bg-[#FAF7F2] border border-[#24143022] rounded-xl overflow-hidden font-sans text-[#241430]" data-property="position">
  <span class="mot-anim-tw-chip mot-anim-tw-chip--loop absolute top-1/2 left-4 -translate-y-1/2 inline-block px-3.5 py-2 rounded-full font-semibold" style="background:#A8E6C1;">Animated chip</span>
</div>
<p class="mt-2 text-sm text-[#241430]/70">Property animated: <strong>position</strong> &middot; 900ms</p>
<style>
@media (prefers-reduced-motion: no-preference) {
  [data-property="position"] .mot-anim-tw-chip { animation: mot-anim-tw-pos 900ms ease-in-out infinite; }
  [data-property="opacity"] .mot-anim-tw-chip { animation: mot-anim-tw-op 900ms ease-in-out infinite; }
  [data-property="colour"] .mot-anim-tw-chip { animation: mot-anim-tw-col 900ms ease-in-out infinite; }
  [data-property="scale"] .mot-anim-tw-chip { animation: mot-anim-tw-scale 900ms ease-in-out infinite; }
  .mot-anim-tw-chip:not(.mot-anim-tw-chip--loop) { animation-iteration-count: 1; animation-fill-mode: forwards; }
  @keyframes mot-anim-tw-pos { 0%,100% { left: 16px; } 50% { left: 220px; } }
  @keyframes mot-anim-tw-op { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
  @keyframes mot-anim-tw-col { 0%,100% { background: #A8E6C1; color: #241430; } 50% { background: #241430; color: #FAF7F2; } }
  @keyframes mot-anim-tw-scale { 0%,100% { transform: translateY(-50%) scale(1); } 50% { transform: translateY(-50%) scale(1.4); } }
}
</style>

react

export function Animation({
  property = "position",
  duration = 900,
  loop = true,
  accent = "#A8E6C1",
  label = "Animated chip",
}) {
  return (
    <div>
      <div data-property={property} style={{ position: "relative", width: "100%", maxWidth: 320, height: 110, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, overflow: "hidden", fontFamily: "system-ui, sans-serif", color: "#241430" }}>
        <span className={loop ? "chip chip--loop" : "chip"} style={{ position: "absolute", top: "50%", left: 16, transform: "translateY(-50%)", display: "inline-block", padding: "8px 14px", borderRadius: 999, fontWeight: 600, background: accent, color: "#241430" }}>
          {label}
        </span>
      </div>
      <p style={{ margin: "8px 0 0", fontSize: 13, color: "#241430aa" }}>Property animated: <strong>{property}</strong> &middot; {duration}ms</p>
      <style>{`
        @media (prefers-reduced-motion: no-preference) {
          [data-property="position"] .chip { animation: mot-anim-pos ${duration}ms ease-in-out infinite; }
          [data-property="opacity"] .chip { animation: mot-anim-op ${duration}ms ease-in-out infinite; }
          [data-property="colour"] .chip { animation: mot-anim-col ${duration}ms ease-in-out infinite; }
          [data-property="scale"] .chip { animation: mot-anim-scale ${duration}ms ease-in-out infinite; }
          .chip:not(.chip--loop) { animation-iteration-count: 1; animation-fill-mode: forwards; }
          @keyframes mot-anim-pos { 0%,100% { left: 16px; } 50% { left: 220px; } }
          @keyframes mot-anim-op { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
          @keyframes mot-anim-col { 0%,100% { background: #A8E6C1; color: #241430; } 50% { background: #241430; color: #FAF7F2; } }
          @keyframes mot-anim-scale { 0%,100% { transform: translateY(-50%) scale(1); } 50% { transform: translateY(-50%) scale(1.4); } }
        }
      `}</style>
    </div>
  );
}