纯css沙漏动画需同时控制旋转、高度变化和裁剪边界;仅用rotate()或height会导致穿帮,必须用.sand-top与.sand-bottom双元素分别控制收窄与撑开,并配合transform-origin、clip-path及分段keyframes实现严丝合缝的视觉效果。

纯 CSS 能做出视觉可信的沙漏动画,但必须同时控制旋转、高度变化和裁剪边界——只靠 rotate() 或只缩 height 都会穿帮。
为什么沙漏动画不能只用 transform: rotate()
单纯旋转整个容器,只是把沙漏“转圈”,沙子不会流动;旋转单个沙斗又容易位移出界。真实沙漏的关键是「上半沙斗顺时针收窄 + 下半沙斗逆时针撑开」,这需要两个独立元素分别控制:.sand-top 和 .sand-bottom。如果只写一个 @keyframes rotate 套在父容器上,你会看到沙子原地打转,或者上下沙斗错位分离。
常见错误现象:
- 沙子区域随旋转整体偏移,脱离玻璃容器边界
- 动画中途出现“撕裂感”,上下沙斗接缝处露白
- 小尺寸下晃动明显,尤其在移动端 Safari 中
height 动画必须配 transform-origin 和 clip-path
仅靠 height: 100% → 0% 会让沙子塌成一条线,失去锥形收腰效果。必须叠加 transform: rotate(45deg) 并指定旋转基点,让收缩过程沿沙斗边缘发生。
实操要点:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
.sand-top要加transform-origin: bottom center,否则收缩时顶部会翘起 -
.sand-bottom要加transform-origin: top center,否则底部会内陷 - 必须用
clip-path: polygon(...)固定沙斗轮廓,防止height改变时内容溢出 - 避免用
scaleY():它会压缩内部伪元素(如模拟沙粒的::before),比例失真
动画时间与翻转节奏怎么对齐
一次完整计时周期 = 沙子从顶流到底 + 沙漏物理翻转 + 沙子从底回顶。CSS 里通常把整个循环设为 --rotateTime: 10s,其中:
- 0%–45%:上半沙斗从满到空(
height: 100% → 0%),下半保持空 - 45%–55%:快速翻转 180°(视觉上沙漏倒置)
- 55%–100%:下半沙斗从空到满(
height: 0% → 100%),上半保持空
关键细节:
- 翻转帧(50%)必须精确落在
transform: rotate(180deg),不能靠 easing 模拟 - 两段
height动画要用ease-in-out,模拟重力加速/减速,linear 看着生硬 - 若嵌入按钮或弹层,务必加
will-change: transform, height,但仅在动画开始前动态添加,结束后立刻移除
嵌入页面时最容易被忽略的渲染陷阱
沙漏动画卡顿,90% 不是代码写错,而是触发方式和层级失控。
- 别在
:hover里直接写animation: ...—— 鼠标反复进出会反复重绘,改用transition+ 类名切换 - 父容器必须有明确
height且overflow: hidden,否则height收缩时内容可能撑破边界 - Chrome 旧版对
transform-origin: 50% 50%解析异常,统一写center更稳 - Safari 对
height + transform同时动画更友好,iOS 15 下scaleY有偶发闪烁
真正难的不是写出动画,而是让每次翻转都严丝合缝地咬合在玻璃容器边缘——差 1px 就穿帮,少一句 transform-origin 就晃动。这些细节不调试到真机上跑一遍,根本看不出问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










