真正可靠的是 grid + grid-template-columns 配合 grid-auto-flow: dense 的组合:设 display: grid、grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))、grid-column: span 1、aspect-ratio: 9/16、gap: 8px。

用 CSS Grid 实现真正响应式的短视频瀑布流
纯 CSS 实现的“瀑布流”在短视频卡片场景下,flex 或 float 都会因高度不均导致错位或留白;column-count 虽能模拟但无法控制单卡宽度、且视频尺寸易被截断。真正可靠的是 grid + grid-template-columns 配合 grid-auto-flow: dense 的组合——它不依赖 JS,支持任意高度卡片,且能随容器宽度自动调整列数。
关键不是“堆满”,而是让每张卡片按内容自然撑开、不强制等高:
-
display: grid容器设grid-template-columns: repeat(auto-fill, minmax(280px, 1fr))—— 最小 280px(适配移动端竖屏视频),最大均分剩余空间 - 每张卡片设
grid-column: span 1,确保不跨列(避免视频被拉伸) - 禁用
grid-auto-rows,让行高由视频aspect-ratio: 9/16自动决定 - 务必加
gap: 8px,否则卡片紧贴时加载闪烁明显
视频卡片内联播放必须绕开的三个 autoplay 限制
现代浏览器(Chrome、Safari、Edge)对自动播放有严格策略:autoplay 必须配合 muted、playsinline,且用户需有过交互(如滚动)才可能触发。直接写 <video autoplay></video> 在多数设备上静音也不播。
实操中更稳妥的做法是监听 IntersectionObserver,只对视口内卡片调用 play():
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const video = entry.target.querySelector('video');
if (video && !video.playing) {
video.play().catch(e => console.log('autoplay blocked:', e));
}
}
});
}, { threshold: 0.1 });
document.querySelectorAll('.video-card').forEach(el => observer.observe(el));
注意:iOS Safari 要求 playsinline 属性存在,且不能移除 muted;Android Chrome 对静音视频的自动播放宽容度更高,但首次进入仍可能失败。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
加载性能差?问题大概率出在 poster 和 lazyload 搭配上
瀑布流里上百个 <video></video> 标签同时请求 src,会导致大量 404(视频未上传完)、带宽打满、首屏卡顿。常见错误是只给 loading="lazy" 却忽略 poster 占位。
正确顺序是:
- 所有
<video></video>必须带poster属性,指向轻量缩略图(建议 ≤15KB,WebP 格式) -
src不直接写死,改用自定义属性如data-src,由 JS 在卡片进入视口后赋值再load() - 避免用
background-image模拟 poster——视频加载后不会自动替换,视觉跳变明显 - 服务端返回的视频地址若含签名或过期时间,需在 JS 加载时动态拼接,不能靠 HTML 静态写死
移动端触摸滑动卡顿?检查 overflow-anchor 和 will-change
长列表瀑布流在 iOS Safari 或部分 Android 浏览器中,快速滚动时会出现掉帧、回弹异常,根源常是浏览器对 grid 容器的渲染优化失效。
两个低成本修复点:
- 给容器加
overflow-anchor: none,禁用浏览器默认的锚点滚动定位(它会反复计算 grid 行位置) - 对卡片元素加
will-change: transform,提前告知浏览器该元素将频繁变化位置(仅对进入视口的卡片动态添加,避免全量开启) - 禁用
-webkit-overflow-scrolling: touch(已废弃,且与 grid 冲突) - 如果使用了
transform: translateY()做懒加载动画,确保用requestAnimationFrame控制节奏,别直接改 top/left
真正难调的不是布局,是视频资源加载时机和滚动行为的耦合——卡片刚进视口就触发 play(),但 src 还没 load 完,这时候 catch 到的错误不是“拒绝播放”,而是“network error”,容易误判为权限问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










