mod()函数返回非负余数,值恒在[0, |b|)区间,适合循环偏移;但负除数会导致safari与chrome结果不一致,应避免;单位须统一,不可用于@keyframes关键帧计算。

mod() 函数在 CSS 中确实能用于循环动画或交替着色,但它不是“万能取模”,用错参数或忽略负值行为,动画会跳变、颜色错位,甚至在 Safari 中结果不一致。
mod() 的行为和负值陷阱
mod(A, B) 返回的是标准数学模运算结果:值始终落在 [0, |B|) 区间内(含 0,不含 |B|)。这正是它适合循环偏移的关键——结果永远非负、可预测。
-
mod(140px, 90px)→50px(140 ÷ 90 = 1 余 50) -
mod(-140px, 90px)→40px(因为 -140 + 2×90 = 40;注意:Safari 17.4 返回40px,Chrome/Firefox 也一致) -
mod(-140px, -90px)在 Safari 17.4 返回40px,但 Chrome 返回-50px——务必避免用负除数,兼容性不可靠
如果你看到颜色条突然反向、动画重置到起点,大概率是传入了负的第二个参数,或没意识到被除数为负时结果仍非负(导致 offset 意外归零)。
用 mod() 实现等距循环动画偏移
典型场景:让一组卡片水平排列,每张卡片的 transform: translateX() 基于其索引 counter() 或自定义属性 --i 循环偏移,形成波浪入场效果。
- 必须配合 CSS 自定义属性传递索引,例如:
style="--i: 0;"、style="--i: 1;" - 写法示例:
transform: translateX(mod(calc(var(--i) * 20px), 100px));→ 索引 0→5 → 偏移 0/20/40/60/80px;索引 6 →mod(120px, 100px) = 20px,重新开始循环 - 单位必须统一:
mod(calc(var(--i) * 1rem), 2rem)合法;mod(10px, 2rem)报错 - 不能直接在
@keyframes里用mod()驱动关键帧位置(浏览器不支持动态计算关键帧),只能用于属性值计算(如transform、background-position)
用 mod() 做交替着色(如斑马纹、隔行变色)
比 :nth-child(odd) 更灵活:支持任意步长、非整数步长(如每 3.5 项循环)、与滚动位置联动。
- 基础斑马纹:
background-color: hsl(mod(calc(var(--i) * 60), 120), 70%, 60%);→ 每 2 项循环一次色相(120° 一周期) - 滚动驱动着色:
background-color: oklch(mod(calc(100vh - scroll(y)), 200px) / 200px * 100%, 0.35, 280);(需启用实验性 color 功能) - 注意:CSS 不支持条件分支,所以不能用
mod()直接写「奇数红、偶数蓝」;得配合hsl()或color-mix()映射为视觉差异 - 若需严格二值切换(0/1),可用
round(mod(...), 1)截断,但更稳妥的是用calc((mod(...) + 0.5) / 1)再转为clamp(0, ..., 1)
真正容易被忽略的点:mod() 的结果是**连续可插值的长度值**,不是布尔开关。想用它做“切换”,得主动把它映射成视觉变量(色相、透明度、位移量),而不是期待它自动产生离散状态。另外,所有依赖它的布局/动画,在 Safari 和 Chrome 中表现基本一致,但别碰负除数——那块坑还没填平。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











