跳到主内容

示例 / 动画

动画

transition / animation / View Transitions —— 4 个可调试 demo

按钮 Hover 过渡

beginner查看章节 →
按钮 Hover 过渡transition 基础:状态变化时自动插值
查看源码html
<button class="btn">Hover 我看过渡</button>

<style>
.btn {
  padding: 0.625rem 1.25rem;
  background: #3b82f6;
  color: white;
  border-radius: 8px;
  /* 关键:transition 写在默认状态,hover 进入和离开都有过渡 */
  transition: background 0.2s ease, transform 0.2s ease;
}

.btn:hover {
  background: #1d4ed8;         /* 颜色变深 */
  transform: translateY(-2px); /* 略微上浮 */
}

/* 试着改:
   - duration: 0.2s → 1s    (感受过渡变慢)
   - ease → linear           (感受机械感)
   - translateY(-2px) → -10px(感受过度强调)
*/
</style>

卡片进入动画

beginner查看章节 →
卡片进入动画@keyframes + animation:多关键帧时间轴

卡片标题

进入动画演示:从下往上滑入 + 淡入

查看源码html
<div class="card">
  <h3>卡片标题</h3>
  <p>进入动画演示:从下往上滑入 + 淡入</p>
</div>

<style>
.card {
  animation: slide-in-up 0.4s ease-out both;
  /*         ↑名称  ↑时长 ↑缓动  ↑填充模式 */
}

@keyframes slide-in-up {
  0% {
    opacity: 0;
    transform: translateY(20px);
  }
  50% {
    opacity: 0.5; /* 中间关键帧:半透明 */
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* animation-fill-mode: both = 
   动画开始前停在 0%,结束后停在 100% */
/* 试着改:
   - 0% translateY(20px) → 50px(感受起点更远)
   - ease-out → linear(感受机械感)
   - 删掉 50% 关键帧(感受三帧 vs 两帧)
*/
</style>

View Transition 基础

intermediate查看章节 →
View Transition 基础浏览器原生跨状态过渡(含降级)
项目 1
项目 2
项目 3
项目 4
查看源码html
<button onclick="toggleView('list')">列表视图</button>
<button onclick="toggleView('grid')">网格视图</button>

<div id="container" class="list-view">
  <div class="item">项目 1</div>
  <div class="item">项目 2</div>
  <div class="item">项目 3</div>
  <div class="item">项目 4</div>
</div>

<script>
function toggleView(view) {
  const container = document.getElementById('container');
  
  // 关键:View Transition API
  if (!document.startViewTransition) {
    // 降级:不支持的浏览器直接改 DOM
    container.className = view + '-view';
    return;
  }
  
  // 支持的浏览器:自动捕获前后状态、生成过渡
  document.startViewTransition(() => {
    container.className = view + '-view';
  });
}
</script>

<style>
.list-view {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.grid-view {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
}

/* 浏览器自动生成交叉淡入淡出,零额外 CSS */
</style>

暗色切换圆形扩散

advanced查看章节 →
暗色切换圆形扩散View Transition + clip-path 实现的杀手级效果

当前主题:亮色

从点击位置圆形扩散(仅切换 demo 容器内主题)
Chrome / Edge / Safari 18+ 支持;不支持的浏览器降级直接切换

查看源码html
<button id="theme-toggle">切换主题</button>

<script>
document.getElementById('theme-toggle')
  .addEventListener('click', (event) => {
  const x = event.clientX;
  const y = event.clientY;
  
  // 计算从点击位置到屏幕四角的最远距离
  const endRadius = Math.hypot(
    Math.max(x, innerWidth - x),
    Math.max(y, innerHeight - y)
  );
  
  // 降级判断
  if (!document.startViewTransition) {
    toggleTheme();
    return;
  }
  
  // 触发 View Transition
  const transition = document.startViewTransition(() => {
    toggleTheme();
  });
  
  // 自定义动画:从点击位置圆形扩散
  transition.ready.then(() => {
    document.documentElement.animate(
      {
        clipPath: [
          `circle(0px at ${x}px ${y}px)`,
          `circle(${endRadius}px at ${x}px ${y}px)`,
        ],
      },
      {
        duration: 500,
        easing: 'ease-in-out',
        pseudoElement: '::view-transition-new(root)',
      }
    );
  });
});

function toggleTheme() {
  const root = document.documentElement;
  root.dataset.theme = 
    root.dataset.theme === 'dark' ? 'light' : 'dark';
}
</script>

<style>
[data-theme='light'] {
  background: #ffffff;
  color: #1a1a1a;
}
[data-theme='dark'] {
  background: #1a1a1a;
  color: #e5e5e5;
}
</style>