Marquee 跑马灯
循环无缝滚动展示长内容的纯展示组件,内容经 slot 无缝循环;支持悬停暂停、prefers-reduced-motion 静态降级。滚动速度为像素/秒真实速度(组件测量内容宽推导时长),内容不足一屏时自动填充;max-loops 播完派发 oas-finish(detail { loops })。
破坏性变更:speed 语义由「秒」改为「像素/秒」
旧版 speed 表示单次循环时长(秒):speed="8" 即 8 秒滚完一整轮——内容越宽,视觉速度越快,不同容器下同一取值的实际速度飘忽。 现 speed 表示真实滚动速度(像素/秒,默认 48):组件经 ResizeObserver 测量内容宽度后推导动画时长(时长 = 内容宽 ÷ 速度),内容/容器宽度不同,视觉速度依然恒定。
迁移指引:旧代码里的小数值(如 speed="8")在新语义下是 8px/s(极慢),请按目标速度重设(常用 24–120)。时长语义如需保留,可用 CSS 变量 --oas-marquee-duration 直接覆写(测量写入后仍会覆盖,不推荐)。
基础用法
默认循环滚动(48px/s)
速度控制
speed=96 快速 / speed=24 慢速(像素/秒)
同为 speed="48",200px 的短内容与 2000px 的长内容视觉速度完全一致(旧「时长」语义下相差 10 倍)——这就是速度改用语义的原因。
auto-fill 自动填充
内容比容器短时,仅复制一组会在平移过半后露出右侧留白(断 seam)。组件测量容器与内容宽度后,把克隆组自动填充到足够份数,平移一整组内容的过程中视口始终有内容,无缝不断 seam。
auto-fill:短内容在宽容器中无缝循环
- 克隆份数有上限(50 份):极短内容 + 极宽容器时宁可留白也不让 DOM 无限膨胀;图片墙等重内容场景建议内容本身至少一屏宽。
- 填充份数随容器尺寸变化自动重算(ResizeObserver)。
垂直滚动
orientation="vertical" 切换为垂直滚动(公告长文场景)。容器必须固定高(overflow 裁切才有意义),高度由宿主样式给出。
orientation=vertical:垂直滚动(容器固定高 96px)
垂直跑马灯是连续流动语义;需要「逐条滚动停顿」请用 oas-carousel 的垂直轮播。
反向滚动
reverse:反向滚动(双行对开)
多行交错
组件本身保持单行连续滚动语义;多行跑马灯由多个 oas-marquee 以 reverse 交错组合实现(无需额外属性,垂直堆叠即多行):
多行交错:正 / 反 / 正 三行组合
边缘渐隐
fade-edges 开启容器两端渐隐(mask-image 遮罩,默认关——渐隐会软化边缘、改变存量外观,按需开启)。渐隐宽度走 CSS 变量 --oas-marquee-fade-size(默认 24px)。
fade-edges:logo 墙边缘渐隐
悬停暂停
pause-on-hover:鼠标悬停/聚焦时暂停
内容动态更新
宿主向 slot 追加/修改内容时,组件重建克隆组但保持动画相位(记录当前相位、以负 animation-delay 续跑),用户看到的滚动位置不跳变。下方实例每 3 秒追加一条实时公告:
动态追加内容:滚动不跳变
元素内容
slot 支持任意元素组合
图片 / logo 墙
内容不局限于文字——slot 放图片或 logo 即成主流的"品牌墙"无缝滚动。
logo 墙(无缝循环 + 边缘渐隐)
图片滚动(img)
限定循环次数(max-loops)
max-loops 限定循环轮数(正整数):播完 N 轮后动画定格在末帧(animation-fill-mode: forwards),并派发一次 oas-finish(detail: { loops })。未设置或取值非法/非整数时无限循环。轮数 = 位移距离(一份内容宽)被滚过的次数,与内容宽度无关。
prefers-reduced-motion 下动画整体关闭、静态展示——没有「播完」,也就不派发 oas-finish。
max-loops=3:播 3 轮后定格并派发 oas-finish
播放中…
RTL(右到左)
容器处于 RTL 书写方向(宿主或祖先 dir="rtl"、oas-config-provider direction 注入均生效)时,平移方向自动镜像:内容向右流动、新内容从左缘进入(与 LTR 的「向左流、右缘进入」镜像对称),无缝循环与 auto-fill 填充不受影响。reverse 与镜像正交——RTL 下 reverse 即向左流动。纵向滚动与书写方向无关。
dir=rtl:平移方向镜像(内容向右流动)
API
oas-marquee
属性
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
dir | 书写方向(RTL 判定消费):RTL 下水平滚动平移方向镜像 | — | — |
fade-edges | 布尔,存在时容器两端 mask-image 渐隐(默认关);渐隐宽度走 --oas-marquee-fade-size | — | — |
max-loops | 限定循环轮数(正整数):播完定格末帧并派发一次 oas-finish;缺失/非法为无限循环 | string | — |
orientation | 滚动方向:horizontal(默认)/ vertical(垂直滚动,容器需固定高) | — | — |
pause-on-hover | 布尔,存在时悬停/聚焦暂停动画(animation-play-state: paused) | — | — |
reverse | 布尔,存在时反向滚动 | boolean | — |
speed | 滚动速度(像素/秒,默认 48);经测量内容宽推导动画时长(时长=距离/速度),非法/非正数回退默认 | string | — |
事件
| 事件 | 说明 |
|---|---|
oas-finish | max-loops 播完定格时派发一次,detail: { loops } |
插槽
| 名称 | 说明 |
|---|---|
| 默认 | 滚动内容 |
CSS 变量
| CSS 变量 | 默认值 |
|---|---|
--oas-marquee-duration | 20s |
--oas-marquee-fade-size | 24px |
--oas-marquee-shift | 50% |
- 系统开启「减少动态效果」(
prefers-reduced-motion: reduce)时动画关闭、静态展示。 - 复制内容组带
aria-hidden,屏幕阅读器不重复朗读。 - 无其他事件,纯展示;仅
max-loops播完派发一次oas-finish。