嵌套子元素实现与父级滚动容器一致的position:sticky吸边效果
问题根源
position: sticky 只会相对于最近的设置了overflow属性不为visible的祖先元素生效。你当前代码里id为three1的元素父级是普通inline-flex容器,overflow为默认的visible,所以它的吸附参照是父容器本身,而父容器是和最外层滚动容器一起滚动的,设置left:0只会在父容器范围内吸边,父容器整体向左滚出视口时three1也会跟着移动,自然达不到和#four一致的效果。
另外你的代码存在多处重复id的问题(比如多个three1、four1),id是唯一标识,重复会导致元素选择异常,需要先修正重复id。
解决方案
方案1:纯CSS(可调整DOM结构优先选择)
直接将需要吸边的#three1从嵌套的inline-flex容器中移出,和#four平级,二者的sticky都会参照最外层滚动容器,效果完全一致。
修改后的核心HTML结构示例:
<div style="width: 100%;box-sizing: border-box;white-space: nowrap;overflow-x: scroll;"> <div class="box" id="one">1</div> <div class="box" id="two">2</div> <div class="box" id="three">3</div> <div class="box" id="four" style="position: sticky; left: 0px">4</div> <div class="box" id="five">5</div> <!-- 把three1移到inline-flex容器外,修正为唯一id --> <div class="box1" id="threeSticky" style="position: sticky; left: 0px;display: inline-flex;">one</div> <div style="display: inline-flex"> <div class="box1" id="four1">two</div> <div class="box1" id="two1">9</div> <div class="box1" id="three2">10</div> <div class="box1" id="four2">11</div> </div> <!-- 后续其他元素省略 --> </div>
方案2:JS实现(不能修改DOM结构时使用)
监听最外层滚动容器的滚动事件,动态调整#three1的偏移量,模拟sticky效果:
// 需提前把需要吸边的three1的id修正为唯一值threeSticky const outerScroll = document.querySelector('[style*="overflow-x: scroll"]') const stickyEle = document.querySelector('#threeSticky') const parentEle = stickyEle.parentElement // 缓存父元素相对于最外层滚动容器的初始左偏移 const parentOffsetLeft = parentEle.offsetLeft outerScroll.addEventListener('scroll', () => { const scrollLeft = outerScroll.scrollLeft if (scrollLeft > parentOffsetLeft) { // 滚动超过父元素左边界时,让three1偏移对应距离固定在左侧 stickyEle.style.transform = `translateX(${scrollLeft - parentOffsetLeft}px)` } else { stickyEle.style.transform = 'translateX(0)' } })
如果出现吸边元素被其他内容遮挡的情况,可给#threeSticky添加z-index: 1样式调整层级。
内容的提问来源于stack exchange,提问作者Zada 1
相关产品推荐
相关产品推荐

