如何在元素滚动到6.3vh顶部位置时取消.title类的border-radius
需求说明
我希望当class为.title的div元素滚动至顶部6.3vh的位置时,将其border-radius设置为0(取消圆角)。尝试过媒体查询、伪类等方法均未奏效,寻求仅使用CSS或Sass的解决方案。
现有代码
CSS代码
html, body { margin: 0; padding: 0; } .wrapper { height: auto; margin: 0 10vh; font-size: 3rem; background: red; } header { width: 100%; height: 6.3vh; background: orange; display: flex; justify-content: center; align-items: top; position: sticky; top: 0; z-index: 4; } .header_title { background: blue; } main { width: 100%; background: green; display: flex; flex-direction: column; align-items: center; position: sticky; top: 6.3vh; z-index: 3; } .image { width: 100%; height: 53.7vh; background: burlywood; position: sticky; top: 6.3vh; z-index: 1; } .title { background: purple; border-radius: 20px 20px 0 0; position: sticky; top: 6.3vh; z-index: 3; } .cards { background: pink; width: 100%; position: sticky; z-index: 2; top: 60vh; margin-bottom: 40vh; } footer { width: 100%; height: 40vh; background: grey; display: flex; justify-content: center; align-items: top; position: sticky; z-index: 3; }
(注:修正了原footer代码中width: 1的语法错误,改为width: 100%)
HTML代码
<div class="wrapper"> <header> <div class="header_title">HEADER</div> </header> <main> <div class="image">IMAGE</div> <div class="title">MAIN</div> <div class="cards"> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> <div class="card">CARD</div> </div> </main> <footer> FOOTER </footer> </div>
解决方案
利用CSS的**滚动驱动动画(Scroll-Driven Animations)**可以实现该需求,无需JavaScript。核心是通过滚动进度触发样式变化:
修改后的CSS代码如下:
html, body { margin: 0; padding: 0; /* 定义滚动时间线,绑定页面滚动行为 */ scroll-timeline: --scrollTracking inline; } .wrapper { height: auto; margin: 0 10vh; font-size: 3rem; background: red; } header { width: 100%; height: 6.3vh; background: orange; display: flex; justify-content: center; align-items: top; position: sticky; top: 0; z-index: 4; } .header_title { background: blue; } main { width: 100%; background: green; display: flex; flex-direction: column; align-items: center; position: sticky; top: 6.3vh; z-index: 3; } .image { width: 100%; height: 53.7vh; background: burlywood; position: sticky; top: 6.3vh; z-index: 1; } .title { background: purple; border-radius: 20px 20px 0 0; position: sticky; top: 6.3vh; z-index: 3; /* 绑定滚动驱动动画 */ animation: unsetBorderRadius linear; animation-timeline: --scrollTracking; /* 指定动画触发范围:元素进入视口到顶部距离视口6.3vh时完成动画 */ animation-range: entry 0 cover 6.3vh; } @keyframes unsetBorderRadius { to { border-radius: 0; } } .cards { background: pink; width: 100%; position: sticky; z-index: 2; top: 60vh; margin-bottom: 40vh; } footer { width: 100%; height: 40vh; background: grey; display: flex; justify-content: center; align-items: top; position: sticky; z-index: 3; }
原理说明
scroll-timeline: --scrollTracking inline:在body上创建滚动时间线,关联页面滚动状态;animation-timeline: --scrollTracking:将.title的动画绑定到该滚动时间线;animation-range: entry 0 cover 6.3vh:设置动画触发区间——从.title开始进入视口,到其顶部距离视口顶部6.3vh时,动画执行完成;- 动画
unsetBorderRadius在结束时将border-radius设为0,实现滚动到目标位置后取消圆角的效果。
注意:滚动驱动动画已被现代主流浏览器支持(Chrome、Edge、Firefox 117+、Safari 16.4+),若需兼容旧浏览器则需降级方案,但纯CSS场景下这是唯一可行的实现方式。
内容的提问来源于stack exchange,提问作者Brom
相关产品推荐
相关产品推荐

