滚动放大至全幅

带框的图片滚到屏幕中间时向两侧展开铺满宽度,把一张缩略图变成一整幅场景。

  • CSS
  • 图片
  • 滚动
  • 收录于
向下滚动 ↓
云层之上

AI 提示词

用 CSS 滚动驱动动画制作滚入视野时展开到全宽的图片。给图片外层设置 animation: open linear both,animation-timeline: view(),animation-range: entry 10% cover 50%。keyframes 中从 clip-path: inset(0 22% round 20px) 变为 clip-path: inset(0 0 round 0),同时在同一时间线上把内部图片从 scale 1.2 缩到 1,让画框打开时像镜头往后拉。全部包在 @supports (animation-timeline: view()) 中,不支持的浏览器直接显示完整图片。在 prefers-reduced-motion 下去掉动画。说明文字为“云层之上”。

源代码

Demo.tsx
'use client'

import s from './demo.module.css'

export default function ScrollZoom({ labels }: { labels: Record<string, string> }) {
  return (
    <div className={s.frame} tabIndex={0}>
      <span className={s.hint}>{labels.hint} ↓</span>
      <figure className={s.figure}>
        <div className={s.scene} role="img" aria-label={labels.caption} />
        <figcaption className={s.caption}>{labels.caption}</figcaption>
      </figure>
    </div>
  )
}
demo.module.css
.frame {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}

.frame:focus-visible { outline: 2px solid var(--color-focus); outline-offset: -4px; }

.hint {
  display: block;
  font: 500 var(--text-xs) / 1 var(--font-mono);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-align: center;
  color: var(--stage-muted);
}

.frame { padding-top: 24px; }

.figure {
  --sky-top: oklch(40% 0.08 260);
  --sky-low: oklch(78% 0.1 60);
  --cloud: oklch(92% 0.02 80);
  position: relative;
  height: 200px;
  margin: 160px 0 200px;
  overflow: hidden;
}

.scene {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 30% 14% at 20% 78%, var(--cloud) 96%, transparent),
    radial-gradient(ellipse 40% 16% at 70% 84%, var(--cloud) 96%, transparent),
    radial-gradient(ellipse 50% 20% at 45% 96%, var(--cloud) 96%, transparent),
    radial-gradient(circle at 62% 46%, oklch(95% 0.06 85) 0 8%, transparent 8.5%),
    linear-gradient(var(--sky-top), var(--sky-low));
}

.caption {
  position: absolute;
  left: 50%;
  bottom: 12px;
  translate: -50% 0;
  font: 600 var(--text-base) / 1 var(--font-display);
  color: var(--stage-bg);
  white-space: nowrap;
}

@supports (animation-timeline: view()) {
  .figure {
    animation: open linear both;
    animation-timeline: view();
    animation-range: entry 10% cover 50%;
  }

  .scene {
    animation: settle linear both;
    animation-timeline: view();
    animation-range: entry 10% cover 50%;
  }
}

@keyframes open {
  from { clip-path: inset(0 22% round 20px); }
  to { clip-path: inset(0 0 round 0); }
}

@keyframes settle {
  from { transform: scale(1.2); }
  to { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .figure, .scene { animation: none; }
}

投稿创意

看到想收录的动效或主题?简单描述一下,会打开一个预先填好的 GitHub Issue,确认后即可提交。

你想投稿的是?

需要 GitHub 账号,投稿内容会公开。