应弃用Bootstrap carousel改用原生栅格+lightgallery.js组合:用row/col-*布局图片,img-fluid适配响应式,手动配置allowScrollInside:true防iOS误触关闭,配合srcset/sizes按设备分发图片并启用lazyload。

别用 Bootstrap carousel 做相册
Bootstrap 的 carousel 是为轮播广告、Banner 图设计的,不是相册。硬塞 20 张图进去,会卡顿、缩略图错位、iOS 上点选无响应——它没做图片懒加载、没处理 touchmove 冲突、也不支持多图并排布局。
真正该做的,是放弃 carousel,改用原生栅格 + 轻量第三方库组合:
-
row+col-*控制每行几张图(如col-sm-4 col-md-3 col-lg-2) - 每张图外层加
position-relative,方便后续叠加放大按钮或 caption - 图片必须用
img-fluid,禁用固定height,否则在小屏上会被拉伸或裁剪 - 如果图来自 API 动态渲染,得等 DOM 插入完成再调
lg.init(),否则 lightgallery 绑定失败
lightgallery.js 是当前最稳的选择
它比 fancybox 轻、比 photoswipe 兼容性好,关键是默认开启 allowScrollInside: false —— 这个参数能防止 iOS Safari 手指刚滑出图片就关闭弹窗,但也会导致页面无法上下滚动。真实场景中要手动开:
lightGallery(document.getElementById('gallery'), {
allowScrollInside: true,
download: false,
counter: false,
plugins: [lgZoom, lgThumbnail]
});
注意两点:
-
srcset和sizes必须手写进<img>标签里,lightgallery 不会自动帮你生成;否则高清屏下模糊、流量浪费 - 别用
<picture> + <source>包裹图,Bootstrap 栅格不触发 media query 切换,反而让缓存失效、解析变慢 - 移动端双击放大默认关闭,需显式传
zoomFromOrigin: true才生效
图片资源优化不能只靠 layout
一张 1920×1080 的 JPG 原图直接丢进相册,不管分辨率高低都加载,是典型带宽浪费。实际应按设备像素比和视口宽度分发:
- 小屏(
max-width: 576px)用400w版本 - 中屏(
576px–992px)用800w版本 - 大屏(≥
992px)才加载1200w或webp格式 - 所有
<img>必须带loading="lazy",否则首屏渲染阻塞严重
用 ImageOptim 或 Squoosh 压缩后,实测单图体积可降 40%~60%,且肉眼无损。
容易被忽略的兼容细节
iOS Safari 在 lightgallery 弹出后,偶尔出现「手指一移出图片区域,整个画廊就关闭」的问题——这不是 bug,是它的防误触机制主动阻止了 touchmove 事件,但它没区分是图内拖拽还是页面滚动。
解决办法只有两个:
- 设
allowScrollInside: true,同时确保父容器有明确高度(避免 body 滚动冲突) - 禁用
closeOnTap: true,改用右上角 × 按钮退出,更可控 - 若项目仍需支持 IE11,lightgallery v2.7+ 已不兼容,得回退到 v2.4 并手动 polyfill
CustomEvent
最麻烦的其实是 srcset 的 fallback:Safari 13.1 之前不支持 webp 的 type 判断,得靠 JS 检测后动态替换 src,这个逻辑很容易漏。


















