bootstrap 5.3+ 直接用 placeholder-wave 类实现波纹动画,但需父容器设 position: relative;低版本需手写 linear-gradient + background-position 动画;切换时用 opacity 渐变替代 display: none 防闪烁。

Bootstrap 5.3+ 直接用 placeholder-wave 类就行,但得配对父容器样式
Bootstrap 5.3 起才内置 placeholder-wave 和 placeholder-glow 动画类,低版本(5.0–5.2)必须手写 @keyframes 才能动。直接写 <div class="placeholder placeholder-wave"></div> 不会动,常见错误是漏了父容器约束:
- 父元素必须设
position: relative,否则波纹位移错位 - 避免父容器有
overflow: hidden(比如.card默认带圆角和隐藏溢出)→ 动画被截断 - 别在
transform: scale()或rotate()的容器里嵌套 → 坐标系扭曲,波纹卡住 -
col-*类要包在<div class="row"> 里,否则宽度计算异常,波纹跑偏 <h3>手写线性渐变动画:<code>background: linear-gradient()+background-position位移核心是用 CSS 渐变模拟“光扫过”的效果,比依赖框架更可控,也兼容所有 Bootstrap 版本。关键不是渐变本身,而是让它动起来:
- 渐变方向必须是
90deg(从左到右),才能模拟波浪流动感 -
background-size至少设为200% 100%,否则位移没空间 -
animation必须用background-position动,不是transform—— 后者在 flex/grid 容器里容易失效 - 示例片段:
.skeleton { background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%); background-size: 200% 100%; animation: wave 2s ease-in-out infinite; } @keyframes wave { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
骨架屏切换时别用
display: none,改用opacity渐变数据加载完成瞬间切掉骨架屏,如果直接
display: none或removeChild,会闪一下——因为 placeholder 的动画帧和真实文字渲染节奏不同步。- 给骨架容器加
transition: opacity .2s ease-out - 加载开始:确保
opacity: 1,且内容区域已清空 - 数据就绪后:先
element.style.opacity = '0',监听transitionend事件再element.remove() - 绝对不要用
visibility: hidden→ 占位还在,可能引发布局重排或滚动条跳动
React / Vue 项目里用组件封装时,别让骨架结构卷入响应式栅格
用
Placeholder(react-bootstrap)或b-skeleton(BootstrapVue)时,很多人图省事直接塞进Col或b-col,结果动画失灵。根本原因是栅格系统会动态算宽高,干扰background-position的位移基准。- 稳妥做法:骨架结构用纯
<div> + 显式 <code>width/height+placeholder-wave类 - React 中避免
<placeholder as="{Col}" xs="{6}"></placeholder>,改用<placeholder classname="col-6"></placeholder>(靠 class 触发栅格,不靠 as 渲染逻辑) - Vue 中同理,
<b-skeleton width="200px" height="1rem"></b-skeleton>比width="50%"更稳 - 如果必须响应式,用
min-width+max-width配合媒体查询,而不是依赖栅格类实时计算
真正难的不是写动画,是让动画在各种容器嵌套、transform 变形、flex/gird 布局下都保持坐标系干净。每次加骨架屏前,先检查三层:父容器有没有
overflow: hidden、有没有transform、有没有漏position: relative。 - 渐变方向必须是











