整个网站与网站模板的区别,免费个人博客注册,邢台头条新闻最新,如何建立公司网站建议和规则端小白也能搞定#xff1a;CSS文字横向无缝滚动悬停暂停#xff08;附实测代码#xff09; 为啥老板总想要那种新闻跑马灯效果#xff1f;先搞清楚我们要做啥CSS实现滚动的几种野路子marquee标签#xff1f;祖传玩意儿了transform animation#xff1a;主流…端小白也能搞定CSS文字横向无缝滚动悬停暂停附实测代码为啥老板总想要那种新闻跑马灯效果先搞清楚我们要做啥CSS实现滚动的几种野路子marquee标签祖传玩意儿了transform animation主流打法flex infinite translate更丝滑的现代方案手把手撸一个能上线的版本HTML结构怎么搭才不翻车关键CSS属性逐行拆解无缝衔接的秘密再深挖让鼠标悬停真的能暂停hover触发animation-play-state: paused移动端怎么办这方案到底靠不靠谱优缺点唠明白先说说优点心里美滋滋再说说缺点别盲目乐观实战中踩过的那些坑滚动速度太快像弹幕中文和英文混排对不齐容器宽度变了滚动断档文字模糊或者锯齿调试技巧浏览器里怎么快速试效果临时改 animation-play-state用 outline 标边界慢动作看细节手机模拟器测 touch让代码更健壮的小聪明用 CSS 变量控制滚动速度防溢出露馅will-change 优化无障碍访问A11y加载时的 FOUC 处理最后悄悄说句前端小白也能搞定CSS文字横向无缝滚动悬停暂停附实测代码为啥老板总想要那种新闻跑马灯效果说实话我刚入行那会儿看到产品需求文档里写着需要横向滚动公告栏的时候内心是崩溃的。那时候满脑子都是什么marquee标签还是拉一个 huge 的 JS 轮播库进来结果老大飘过来一句“能用 CSS 解决的就别碰 JS。”这话说得太对了。你想想就为了个文字从左往右跑的效果你引入一个 Swiper.js 或者自己写一堆setInterval bundle 体积咔咔涨运行时还多占内存关键是 SEO 直接原地爆炸——搜索引擎蜘蛛一看好家伙你的公告文字全是 JS 动态塞进去的抓个寂寞啊所以今天咱们就来唠唠怎么用纯 CSS 搞出一个丝滑的无缝滚动还要带悬停暂停功能。别以为这很简单里面水深得呢特别是那个无缝和暂停坑了我好几次夜宵。先搞清楚我们要做啥做技术方案之前得先明白业务到底要什么。我见过太多人一上来就撸代码结果做出来了才发现产品经理说的是另一种东西。这种横向滚动业务里一般叫跑马灯或者新闻 ticker。常见场景我给你数数股市行情——那些红红绿绿的股票代码永远在屏幕顶端滚动眼睛一瞥就能扫到自选股有没有炸雷。电商公告——“全场满199减50”、“新款iPhone到货了”这种促销信息得循环播放生怕你错过。新闻网站——Breaking News那种 urgency 感就是靠不停滚动营造出来的。后台管理系统——告警信息、系统通知得让用户一进页面就注意到。核心需求其实就三条记好了第一横向滚。别给我搞成纵向的那是另一个物种。第二无缝衔接。这个最关键。文字滚到最左边没了右边得马上续上中间不能有空档期。人眼对 discontinuity 特别敏感一旦断了那个违和感能让你难受一天。第三悬停就得停。用户体验的基本礼貌。用户鼠标放上去了明显是想看清楚内容你还继续滚那不是找骂吗CSS实现滚动的几种野路子别急着写代码先看看有哪些方案能打。这就像买菜你得知道菜市场有几条路哪条路最近哪条路坑最多。marquee标签祖传玩意儿了有些老程序员可能还记得marquee这个标签。HTML 原生支持一行代码搞定marqueebehaviorscrolldirectionleft这是要滚动的内容/marquee确实能用但兄弟这玩意儿已经被废弃了。W3C 官方不推荐现代浏览器虽然还兼容毕竟存量网站太多但保不齐哪天就被砍了。而且可控性差样式难调悬停暂停都得靠 JS 监听事件咱们还是别跟过时的东西较劲了。transform animation主流打法现在最稳的方案是用 CSS Animation 配合transform: translateX()。为什么不用margin-left或者left因为 transform 走合成层不会触发重排重绘性能高一个数量级。特别是在移动端掉帧和丝滑的区别往往就在这一个属性上。核心思路是让内容从右侧进入平移到左侧出去。flex infinite translate更丝滑的现代方案但是这里有个问题。如果内容长度不固定或者你要做无缝效果单纯一个 translate 是不够的。为啥因为当最后一个字滚出左边框的时候右边是空的你得等它完全出去再瞬间重置回右边这中间有个 flash肉眼可见的卡顿。解决方法是内容复制。把要滚动的内容复制一份拼在原内容的后面。这样当第一份内容快要滚完的时候第二份内容正好接上视觉上就是个无限循环。这个 trick 很巧妙后面代码里详细讲。手把手撸一个能上线的版本好了理论讲完上硬货。这个方案我在生产环境跑过兼容到 IE11 没问题虽然 IE 用户越来越少但公司后台系统你懂的总有几台古董机。HTML结构怎么搭才不翻车结构要简单但得为 CSS 服务。我的建议是这样divclassmarquee-containerdivclassmarquee-contentspanclasstext-wrapper 热烈庆祝公司上市10周年全场商品低至5折起新用户注册领888元大礼包限时特惠手慢无/spanspanclasstext-wrapper 热烈庆祝公司上市10周年全场商品低至5折起新用户注册领888元大礼包限时特惠手慢无/span/div/div看到没关键点在于.text-wrapper有两个内容一模一样。这就是前面说的复制一份骗过人眼的 trick。.marquee-container是外层容器负责遮罩和溢出隐藏。.marquee-content是动画层负责整体平移。关键CSS属性逐行拆解.marquee-container{/* 固定高度防止内容撑开 */height:40px;/* 背景色随意根据你的设计来 */background:linear-gradient(90deg,#ff6b6b,#ee5a6f);/* 最关键的一行溢出隐藏只显示容器内的内容 */overflow:hidden;/* 相对定位作为子元素的定位上下文 */position:relative;/* 圆角、阴影这些装饰性属性根据喜好加 */border-radius:4px;box-shadow:0 2px 8pxrgba(238,90,111,0.3);}.marquee-content{/* 让两个 span 横向排列 */display:flex;/* 垂直居中 */align-items:center;/* 高度填满容器 */height:100%;/* 动画名称后面定义 */animation-name:marquee-scroll;/* 一次完整的滚动需要20秒根据内容长度调整 */animation-duration:20s;/* 线性速度匀速滚动不会忽快忽慢 */animation-timing-function:linear;/* 无限循环 */animation-iteration-count:infinite;/* 动画开始时在第一帧停留避免初始位置的跳动 */animation-fill-mode:both;}.text-wrapper{/* 文字不换行这是横向滚动的前提 */white-space:nowrap;/* 文字颜色 */color:#fff;/* 字号 */font-size:14px;/* 字间距稍微拉开一点阅读更舒适 */letter-spacing:0.5px;/* 左右内边距让两段文字之间有点呼吸感 */padding:0 50px;/* 行高继承垂直居中 */line-height:40px;}/* 定义关键帧动画 */keyframesmarquee-scroll{0%{/* 初始位置从右侧进入 */transform:translateX(0);}100%{/* 结束位置向左平移50% *//* 为什么是50%因为内容复制了一份两份总长度是单份的2倍 *//* 平移50%正好让第一份完全出去第二份完全进来形成无缝 */transform:translateX(-50%);}}这里有几个点特别值得细说white-space: nowrap是命脉。如果不加这个文字遇到容器边界会自动换行你的横向滚动直接变成纵向排版当场翻车。animation-timing-function: linear也很重要。默认的 ease 会有加速减速过程看起来一顿一顿的不够机械感或者说不够丝滑。线性匀速更符合人们对滚动公告的认知。translateX(-50%)的 trick 前面提过。因为有两份一模一样的内容总宽度是单份的两倍所以平移自身宽度的50%正好完成一个周期的滚动。无缝衔接的秘密再深挖可能有同学会问为什么是两份一份不行吗假设你只有一份内容宽度是 W。从translateX(100%)完全在右侧外面滚动到translateX(-100%)完全在左侧外面确实能看完所有内容。但当它到达-100%的时候瞬间重置回100%这个重置过程如果动画没处理好会有跳变。而且translateX(100%)意味着初始状态容器里是完全空的用户第一眼看到的是一个空白区域体验不好。两份内容的方案初始状态是第一份内容填满容器第二份紧挨着在右侧。滚动过程中第一份慢慢出去第二份慢慢进来当第一份完全出去的时候第二份正好完全占据容器此时动画也正好到了50%瞬间回到起点因为两份内容一样人眼完全察觉不到跳变完美。这个原理其实跟传统的雪碧图动画或者无缝轮播是一个路数都是利用视觉暂留和内容的周期性。让鼠标悬停真的能暂停无缝滚动搞定了现在来解决悬停暂停。看起来简单实际有坑。hover触发animation-play-state: paused最直接的思路.marquee-container:hover .marquee-content{animation-play-state:paused;}没错这就是核心代码。animation-play-state是专门控制动画运行状态的属性paused就是暂停running就是运行默认。但是这里有个事件冒泡的坑。如果你的.text-wrapper里还有其他可交互元素比如链接、按钮鼠标移上去的时候hover 状态可能会混乱。还有如果你用了cursor: pointer之类的要确保层级正确。更健壮的写法是确保 hover 在容器上且状态能正确传递到动画层.marquee-container{/* ... 其他样式 ... */cursor:pointer;}.marquee-container:hover .marquee-content{animation-play-state:paused;}/* 加个过渡让暂停更柔和不会急刹车 */.marquee-content{/* ... 其他样式 ... *//* 虽然 animation 本身不能 transition但可以加个 will-change 优化 */will-change:transform;}移动端怎么办这是最头疼的。移动端没有 hover 这个概念用户是 touch 的。你手指按上去:hover伪类可能会触发取决于浏览器实现但抬起手指后状态可能不会自动恢复或者表现得很诡异。稳妥起见移动端需要 JS 兜底。但别担心就两行不违背纯 CSS的初心毕竟 PC 端还是纯 CSS移动端只是增强constmarqueedocument.querySelector(.marquee-content);// touch 开始时暂停marquee.addEventListener(touchstart,(){marquee.style.animationPlayStatepaused;});// touch 结束时恢复marquee.addEventListener(touchend,(){marquee.style.animationPlayStaterunning;});当然如果你追求极致的纯 CSS也可以考虑用media (hover: hover)媒体查询只在支持 hover 的设备上启用暂停功能media(hover:hover){.marquee-container:hover .marquee-content{animation-play-state:paused;}}这样移动端默认就是一直滚不暂停也算一种策略。具体怎么选看产品需求。这方案到底靠不靠谱优缺点唠明白技术选型最怕的就是只看优点不看坑。我把我实战中的感受摊开来给你看。先说说优点心里美滋滋纯 CSS零依赖。这意味着什么页面加载快啊你不用等那个 JS 文件下载、解析、执行CSS 是渲染阻塞的但同时也是最先处理的用户第一眼就能看到效果。而且少了一个请求HTTP/2 虽然多路复用但能少开条流总是好的。性能开销小。transform和opacity是浏览器优化最好的两个属性走合成层不触发重排GPU 直接参与。我测过在 mid-range 安卓机上这个滚动能稳 60fps跟原生一样丝滑。SEO 友好。这是最关键的业务价值。你的公告文字实打实写在 HTML 里搜索引擎蜘蛛爬过来一目了然。你要是换成 JS 动态生成或者用 Canvas 画SEO 直接归零。对于电商、新闻类站点这往往是决定性因素。可维护性高。就几行 CSS后面接手的人一眼就能看懂。不像某些 JS 库升级个版本 API 全变或者文档稀烂想改个速度都得翻源码。再说说缺点别盲目乐观内容长度固定时不好适配。我们的方案里动画时长是固定的比如20秒。如果内容很短20秒滚完太拖沓如果内容超长20秒滚完像飞一样。虽然可以用 CSS 变量动态调整但终归不如 JS 那样能根据内容长度自动计算速度。超长文本可能卡顿。如果你要滚动的文本是几千字的长文复制一份就是双倍 DOM 节点虽然现代浏览器处理几千个节点没问题但万一你还加了复杂的样式、伪元素、阴影什么的渲染压力会上去。这时候可能需要考虑虚拟滚动或者分段加载。IE别提了。虽然前面说兼容到 IE11但animation属性在 IE10 以下是不支持的。如果你的用户群体还有大量 IE9比如某些政府机构、银行内部系统这个方案直接毙掉。不过都2024年了IE9 应该进博物馆了吧动态内容更新麻烦。如果公告是实时推送的你需要用 JS 去更新 DOM这时候要确保更新时动画状态正确否则可能出现跳帧。好在这个问题用少量 JS 就能解决不是硬伤。实战中踩过的那些坑理论讲完来点血泪史。这些都是我深夜加班 debug 出来的经验你现在看到相当于白嫖了我的夜宵。滚动速度太快像弹幕产品经理第一天说快点让用户注意到第二天说慢点看都看不清。调animation-duration就行但注意时长越长速度越慢这个反直觉的关系别搞混了。更高级的做法是用 CSS 变量方便全局调整:root{--marquee-duration:20s;}.marquee-content{animation-duration:var(--marquee-duration);}/* 不同场景用不同速度 */.marquee-container.urgent{--marquee-duration:10s;}.marquee-container.relax{--marquee-duration:30s;}中文和英文混排对不齐这是个排版玄学问题。中文字符通常是等宽monospace 感英文是比例宽度混在一起的时候如果用了某些字体视觉上有断层感。解决方法是微调letter-spacing和word-spacing.text-wrapper{/* 中文间距 */letter-spacing:0.05em;/* 英文单词间距 */word-spacing:0.1em;/* 用支持中文的等宽或准等宽字体 */font-family:PingFang SC,Microsoft YaHei,sans-serif;}还有一种 trick 是给中英文之间加零宽空格#8203;或者用span分别包起来微调但那样 HTML 结构太脏不建议。容器宽度变了滚动断档响应式布局的痛。用户缩放浏览器或者从竖屏转到横屏容器宽度变了但动画还是按照原来的translateX(-50%)跑可能出现两份内容之间出现空隙或者重叠。严格来说我们的方案里因为translateX是相对于自身宽度的百分比而自身宽度是由内容撑开的display: flexwhite-space: nowrap所以内容没变的情况下百分比是自适应的。但如果内容本身变了比如字体大小随屏幕宽度变化就可能出问题。保险起见可以用 JS 监听 resize或者更简单用 CSS 锁死一些关键尺寸.marquee-container{/* 最小宽度保证再小就不优雅降级 */min-width:320px;/* 或者直接用媒体查询断点 */}media(max-width:768px){.text-wrapper{font-size:12px;padding:0 20px;}}文字模糊或者锯齿滚动过程中文字发虚特别是 Windows 下的 Chrome。这是因为transform开启了硬件加速但某些显卡驱动渲染文字不够锐利。可以加个 hack.marquee-content{/* 强制 GPU 渲染有时能缓解 */transform:translateZ(0);/* 或者调整抗锯齿 */-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}但要注意translateZ(0)会创建新的层叠上下文可能影响 z-index 的表现用的时候留意一下。调试技巧浏览器里怎么快速试效果写 CSS 动画DevTools 是你的好朋友。几个我常用的技巧临时改 animation-play-state在 Elements 面板选中.marquee-content在 Styles 里直接勾选或取消animation-play-state: paused看暂停效果是否符合预期。这比刷新页面快多了特别是调那个刚好停在我想要的位置的时候。用 outline 标边界布局乱了不知道哪里超了加个 outline.marquee-container{outline:2px solid red;}.marquee-content{outline:2px solid blue;}.text-wrapper{outline:1px dashed green;}肉眼可见的层级关系比border好因为不占布局空间。慢动作看细节Chrome DevTools 有个神器Animations 面板如果没显示按Esc打开 Drawer点菜单找 Animations。在这里你可以把动画速度降到 10%看清楚每一帧的衔接手动拖拽时间轴看任意时刻的状态查看动画的 keyframes 详情对于调试无缝效果特别有用。你能肉眼确认当第一份内容完全出去的时候第二份是不是完美接上有没有缝隙或者重叠。手机模拟器测 touchDevice Toolbar 切到手机模式但注意这里的 touch 是模拟的:hover行为可能跟真机不一样。最稳妥还是真机调试或者用 Safari 的 Remote DebuggingiOS和 Chrome 的 Remote DebuggingAndroid。真机上如果发现触摸不暂停检查两点元素是否正确响应了 touch 事件有时候被其他层挡住了JS 的事件监听是否加上了如果用了 JS 兜底方案让代码更健壮的小聪明写到这你已经能跑通基础版本了。但production code 和 demo 的区别就在于那些万一的处理。用 CSS 变量控制滚动速度前面提过再给个完整示例divclassmarquee-containerstyle--marquee-speed:15s;divclassmarquee-contentspanclasstext-wrapper.../spanspanclasstext-wrapper.../span/div/div.marquee-content{/* 默认值如果行内没定义就用这个 */animation-duration:var(--marquee-speed,20s);}这样同一套 CSS不同实例可以有不同的速度不用写多个 class。防溢出露馅overflow: hidden是必须的但有时候内容太长或者用户设置了很大的字体可能从其他方向溢出。保险起见.marquee-container{overflow:hidden;position:relative;/* 有时候还需要 */max-width:100%;box-sizing:border-box;}will-change 优化告诉浏览器这个元素要动画了你提前准备一下.marquee-content{will-change:transform;}注意will-change是双刃剑用多了反而占用 GPU 内存。建议只在确定要动画的元素上加动画结束后可以移除如果需要的话滚动公告一般是无限循环所以一直留着也行。无障碍访问A11y别忘了视力不好的用户。滚动内容对使用屏幕阅读器的人不太友好因为只读一遍就过去了。可以加上aria-live属性让屏幕阅读器能读到divclassmarquee-containeraria-livepolitearia-atomictruedivclassmarquee-contentspanclasstext-wrapperroletext这里是公告内容.../span!-- 第二份内容可以加上 aria-hidden避免重复朗读 --spanclasstext-wrapperaria-hiddentrue这里是公告内容.../span/div/divaria-livepolite表示内容变化时礼貌地通知读屏软件不会打断当前朗读。aria-hiddentrue让第二份内容对屏幕阅读器不可见因为内容一样读两遍反而烦人。还有prefers-reduced-motion媒体查询要尊重media(prefers-reduced-motion:reduce){.marquee-content{animation:none;/* 静止状态下展示全部内容或者换种方式 */flex-wrap:wrap;height:auto;}}有些用户设置了减少动画可能是晕车或者注意力障碍这时候咱就别滚了静态展示完事。加载时的 FOUC 处理Flash of Unstyled Content内容加载瞬间的样式闪烁。如果 CSS 加载慢了用户可能先看到静止的两行文字然后 CSS 到了突然开始滚动有点突兀。可以加个初始状态隐藏或者用内敛样式先定住divclassmarquee-containerstyleopacity:0;.../divscript// CSS 加载完再显示window.addEventListener(load,(){document.querySelector(.marquee-container).style.opacity1;});/script或者用animation-delay错开启动时间给浏览器一点准备时间。最后悄悄说句好了全套功夫都交给你了。从基本原理到踩坑实录从 PC 到移动端从性能优化到无障碍访问该说的不该说的都说了。下次产品再说就加个简单的跑马灯你可以笑着甩出这段代码然后——去摸鱼吧。是真的这活儿现在对你就是五分钟的事剩下的时间喝杯咖啡看看技术博客或者跟后端兄弟吹吹水不香吗而且你注意到了吗咱们这个方案没有引用任何第三方库没有复杂的构建配置复制粘贴就能跑。这种简单但 robust的解决方案往往比那些重型的、依赖众多的方案更有生命力。五年后可能你用的框架都换了三茬但这几行 CSS 大概率还能稳稳地跑在公司的公告栏上。技术嘛有时候追求的就是这种优雅且持久的感觉。就像一个好的老员工不多话不折腾但关键时刻永远不掉链子。代码拿去不谢。有问题死党群聊里吼一声懂的兄弟会捞你的。欢迎来到我的博客很高兴能够在这里和您见面希望您在这里可以感受到一份轻松愉快的氛围不仅可以获得有趣的内容和知识也可以畅所欲言、分享您的想法和见解。推荐DTcode7的博客首页。一个做过前端开发的产品经理经历过睿智产品的折磨导致脱发之后励志要翻身农奴把歌唱一边打入敌人内部一边持续提升自己为我们广大开发同胞谋福祉坚决抵制睿智产品折磨我们码农兄弟专栏系列点击解锁学习路线(点击解锁知识定位《微信小程序相关博客》持续更新中~结合微信官方原生框架、uniapp等小程序框架记录请求、封装、tabbar、UI组件的学习记录和使用技巧等《AIGC相关博客》持续更新中~AIGC、AI生产力工具的介绍例如stable diffusion这种的AI绘画工具安装、使用、技巧等总结《HTML网站开发相关》《前端基础入门三大核心之html相关博客》前端基础入门三大核心之html板块的内容入坑前端或者辅助学习的必看知识《前端基础入门三大核心之JS相关博客》前端JS是JavaScript语言在网页开发中的应用负责实现交互效果和动态内容。它与HTML和CSS并称前端三剑客共同构建用户界面。通过操作DOM元素、响应事件、发起网络请求等JS使页面能够响应用户行为实现数据动态展示和页面流畅跳转是现代Web开发的核心《前端基础入门三大核心之CSS相关博客》介绍前端开发中遇到的CSS疑问和各种奇妙的CSS语法同时收集精美的CSS效果代码用来丰富你的web网页《canvas绘图相关博客》Canvas是HTML5中用于绘制图形的元素通过JavaScript及其提供的绘图API开发者可以在网页上绘制出各种复杂的图形、动画和图像效果。Canvas提供了高度的灵活性和控制力使得前端绘图技术更加丰富和多样化《Vue实战相关博客》持续更新中~详细总结了常用UI库elementUI的使用技巧以及Vue的学习之旅《python相关博客》持续更新中~Python简洁易学的编程语言强大到足以应对各种应用场景是编程新手的理想选择也是专业人士的得力工具《sql数据库相关博客》持续更新中~SQL数据库高效管理数据的利器学会SQL轻松驾驭结构化数据解锁数据分析与挖掘的无限可能《算法系列相关博客》持续更新中~算法与数据结构学习总结通过JS来编写处理复杂有趣的算法问题提升你的技术思维《IT信息技术相关博客》持续更新中~作为信息化人员所需要掌握的底层技术涉及软件开发、网络建设、系统维护等领域的知识《信息化人员基础技能知识相关博客》无论你是开发、产品、实施、经理只要是从事信息化相关行业的人员都应该掌握这些信息化的基础知识可以不精通但是一定要了解避免日常工作中贻笑大方《信息化技能面试宝典相关博客》涉及信息化相关工作基础知识和面试技巧提升自我能力与面试通过率扩展知识面《前端开发习惯与小技巧相关博客》持续更新中~罗列常用的开发工具使用技巧,如 Vscode快捷键操作、Git、CMD、游览器控制台等《photoshop相关博客》持续更新中~基础的PS学习记录含括PPI与DPI、物理像素dp、逻辑像素dip、矢量图和位图以及帧动画等的学习总结日常开发办公生产【实用工具】分享相关博客》持续更新中~分享介绍各种开发中、工作中、个人生产以及学习上的工具丰富阅历给大家提供处理事情的更多角度学习了解更多的便利工具如Fiddler抓包、办公快捷键、虚拟机VMware等工具吾辈才疏学浅摹写之作恐有瑕疵。望诸君海涵赐教。望轻喷嘤嘤嘤非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。愿斯文对汝有所裨益纵其简陋未及渊博亦足以略尽绵薄之力。倘若尚存阙漏敬请不吝斧正俾便精进