CSS如何设计一个具有故障风(Glitch)的标题_通过伪元素位移动效css

1次阅读

glitch效果必须用伪元素而非直接动画文字,因真文字位移会破坏可访问性与seo;::before/::after为纯装饰层,主文字正常显示,伪元素复制content: attr(data-text)并分染红青色,通过steps(1,end)阶梯动画、错时偏移及像素级适配实现真实故障感。

CSS如何设计一个具有故障风(Glitch)的标题_通过伪元素位移动效css

glitch效果为什么必须用伪元素而不是直接动画文字

因为真文字加位移会破坏可访问性(屏幕阅读器读不到错位内容),也影响SEO;而::before::after是纯装饰层,不干扰语义。直接对h1本身加transform再叠text-shadow,视觉上像glitch,但实际没“撕裂感”——真正的故障风需要两层错位文本轻微偏移+颜色分离+时间差闪动。

怎么用::before::after复刻经典红蓝错位glitch

核心思路:主文字正常显示,伪元素复制内容、分别染成#ff0055(红)和#00ffff(青),再用animation让它们在x轴随机偏移+短暂闪现。

  • 必须给伪元素设content: attr(data-text),配合HTML里写data-text="Error",避免内容重复写两次
  • position: absolutez-index要低于主文字,否则盖住原字
  • 动画关键帧里用translateX(calc(var(--tx, 0) * 1px))比固定px值更易调控偏移幅度
  • 红层动画延迟0.05s,青层延迟0.1s,制造“不同步故障”感
h1 {   position: relative;   font-family: monospace; } h1::before, h1::after {   content: attr(data-text);   position: absolute;   top: 0; left: 0; } h1::before { color: #ff0055; animation: glitch-red 3s infinite; } h1::after { color: #00ffff; animation: glitch-cyan 3s infinite; } <p>@keyframes glitch-red { 0% { transform: translateX(0); } 20% { transform: translateX(-5px); } 40% { transform: translateX(3px); } 60% { transform: translateX(-2px); } 80% { transform: translateX(4px); } 100% { transform: translateX(0); } }

为什么animation-timing-function不能用easelinear

glitch不是平滑过渡,是突然跳变+卡顿。用cubic-bezier(0.2, 0.8, 0.4, 1)这类缓动会让偏移“软着陆”,失去故障的生硬感。真正有效的做法是:

  • steps(1, end)强制帧间无过渡,比如animation: glitch-red 0.5s steps(1, end) infinite
  • 或者在关键帧里用0%, 19% { transform: ... }20%, 39% { transform: ... }这种“阶梯式”写法,逼出跳变
  • 避免animation-fill-mode: forwards——glitch必须归零,否则最后停在偏移态,就变成“歪标题”而不是“故障瞬间”

移动端适配和性能隐患在哪

伪元素glitch在ios safari上容易触发重绘卡顿,尤其字体大、动画快时。不是所有设备都扛得住每秒10次transform变化。

立即学习前端免费学习笔记(深入)”;

  • will-change: transform到伪元素上,提前通知浏览器要动的是位置
  • @media (prefers-reduced-motion: reduce)关掉动画,否则可能引发眩晕
  • 别用font-weight: 900配glitch——粗字+错位=糊成一团,选font-weight: 600或等宽字体更清晰
  • 如果用在导航栏里,确保h1有足够line-height,否则伪元素偏移后可能被父容器overflow: hidden裁掉

真正难调的不是动效本身,是让红/青两层在各种DPR下都对得上像素——有时translateX(2px)在2x屏上其实是4物理像素,偏移就过猛了。这时候得用transform: translateX(calc(2px * 0.5))反向缩放,或者干脆用vw单位保相对精度。

text=ZqhQzanResources