纯css+html可实现轮播图,但可靠、可交互、可访问的轮播必须依赖js;原生carousel标签不存在,所有html轮播均为div+img+js模拟。

纯 CSS + HTML 能做轮播图,但真要可靠、可交互、可访问,必须加 JS 控制逻辑;原生 carousel 标签不存在,所有“HTML轮播图”本质都是用 div + img + JS 模拟出来的。
为什么直接写 <img> 切换会卡顿或跳变
常见做法是用 display: none 或 visibility: hidden 切换图片,但这样浏览器仍会加载全部图片(即使不可见),且 DOM 重排频繁,动画不连贯。
- 用
opacity: 0+pointer-events: none替代display: none,保留布局流,减少重排 - 图片懒加载必须配合
loading="lazy"和 JS 动态设置src,否则首屏加载压力大 - 切换时加
transition: opacity 0.3s ease-in-out,但需确保父容器有will-change: opacity或transform: translateZ(0)触发 GPU 加速
setInterval 自动轮播的三大陷阱
自动播放看似简单,但一不留神就导致用户操作失灵、内存泄漏、焦点丢失。
- 用户手动切换后,
setInterval不清除 → 多个定时器叠加,图片疯狂翻页 → 必须在每次切换前调用clearInterval(this.timer) - 轮播区域获得焦点(比如键盘 Tab 进入)时,应暂停自动播放 → 监听
focusin和blur事件,而非只靠鼠标移入/移出 - 页面切到后台标签页时,
setInterval可能被节流甚至暂停,恢复后时间错乱 → 改用requestAnimationFrame+ 时间戳比对更稳,或监听visibilitychange事件控制启停
如何让轮播图真正支持键盘和屏幕阅读器
多数轮播图默认只响应鼠标点击,对键盘用户(Tab / Enter / ArrowLeft / ArrowRight)和读屏软件完全不友好。
- 每个轮播项
<div role="group"> 包裹,整体容器加 <code>role="region"和aria-live="polite" - 左右按钮必须有
aria-label(如aria-label="上一张"),且tabindex="0"可聚焦 - 当前显示项加
aria-current="true",其他项设为aria-hidden="true";切换时同步更新aria-live区域文本(例如“第 2 张,标题:夏日海滩”) - 按
ArrowLeft/ArrowRight时,焦点应保留在按钮上,而非跳到图片 —— 否则键盘用户会迷失上下文
最易被忽略的是:轮播图一旦嵌套在 position: fixed 或 transform 容器里,focus 状态可能视觉丢失,且 aria-live 的播报顺序容易错乱。这类边界情况得靠真实键盘+NVDA/JAWS 测试,不能只看代码写没写。











