如何为CSS旋转实现的横向滚动网站制作滚动进度条
CSS翻转实现的横向滚动适配进度条方案
你当前通过CSS旋转偏移实现的横向滚动,原有进度条失效的核心原因是找错了真实的滚动数据源,按照下面的步骤调整即可正常运行:
核心逻辑拆解
你用来承载滚动的.wrapper-wrapper本身就是垂直方向的原生滚动容器——CSS旋转只是把这个垂直滚动的视觉方向转成了横向,容器本身的scrollTop、scrollHeight等原生滚动属性完全没有改变。之前的进度条之所以失效,是因为你之前读取的是window全局的垂直滚动值,但当前实现下window本身根本不会产生任何滚动,所有滚动行为都被封闭在这个内部容器里。
具体实现步骤
1. 绑定正确的滚动数据源
进度值的计算逻辑和普通垂直滚动完全一致,只是把读取对象换成真实的滚动容器即可:
- 容器当前滚动距离:取
.wrapper-wrapper的原生scrollTop属性 - 容器总可滚动距离:取
.wrapper-wrapper自身的scrollHeight - clientHeight值 - 实时进度百分比 = (当前滚动距离 / 总可滚动距离)* 100%
对应的进度更新函数示例:
// 获取真实滚动容器和进度条DOM const scrollContainer = document.querySelector('.wrapper-wrapper') const progressBar = document.querySelector('#scroll-progress-bar') function refreshProgress() { const currentScroll = scrollContainer.scrollTop const maxScroll = scrollContainer.scrollHeight - scrollContainer.clientHeight // 处理无内容可滚动的边界情况,避免除以0报错 const progressRate = maxScroll > 0 ? (currentScroll / maxScroll) * 100 : 0 progressBar.style.width = `${progressRate}%` }
2. 给真实滚动容器绑定滚动事件
不要再把滚动监听绑在window上,直接把scroll事件绑定到.wrapper-wrapper节点上即可:
// 页面加载完成先初始化一次初始进度 window.addEventListener('load', refreshProgress) // 滚动触发时用requestAnimationFrame节流,减少DOM更新频率提升性能 scrollContainer.addEventListener('scroll', () => { requestAnimationFrame(refreshProgress) })
3. 调整进度条DOM的层级避免视觉扭曲
因为你的滚动容器是被CSS旋转过的,千万别把进度条的DOM结构放在.wrapper-wrapper内部——不然进度条会跟着一起旋转,视觉上变成垂直的歪斜条。
正确的DOM结构应该把进度条放在所有旋转容器的最外层,比如直接放在body根节点下:
<!-- 进度条在最外层,不参与内部旋转 --> <div class="fixed top-0 left-0 w-full h-1 bg-gray-100 z-50 overflow-hidden"> <div id="scroll-progress-bar" class="h-full bg-blue-500" style="width: 0%"></div> </div>
常见踩坑点提醒
- 不要手动换算CSS旋转带来的尺寸偏移:浏览器会自动计算旋转后的容器实际可滚动尺寸,直接读
scrollHeight等原生属性即可,不需要手动根据100vh、400vw这些写死的尺寸做换算 - 不要读window的
scrollY作为滚动值:当前实现里window本身没有任何滚动行为,读出来永远是0 - 记得处理边界值:如果页面加载时图片、字体还没加载完成,
scrollHeight的计算值会不准,需要在资源加载完成后再触发一次进度更新
内容的提问来源于stack exchange,提问作者Kiet-del
相关产品推荐
相关产品推荐

