You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

滚动时如何实现依次滑入并固定在页面顶部的双粘性导航栏?

纯CSS实现方案(推荐)

利用position: sticky和CSS滚动驱动动画实现,无需额外JS逻辑,代码如下:

完整CSS代码

body {
  margin: 0;
  height: 300vh;
}

nav {
  height: 50px;
  display: flex;
  position: sticky;
  top: 0;
  /* 初始定位到视口底部 */
  margin-top: calc(100vh - 50px);
  background: #fff;
}

nav div {
  width: 100px;
  height: 100%;
}

/* 红色导航项 */
nav div:first-child {
  background-color: red;
  transform: translateY(-100%);
  opacity: 0;
  transition: all 0.3s ease;
  /* 滚动驱动动画:nav固定到顶部后触发红色项滑入 */
  animation: showRedNav 0.3s ease forwards;
  animation-timeline: scroll(root);
  animation-range: 100vh 100vh;
}

/* 蓝色导航项 */
nav div:last-child {
  background-color: blue;
}

@keyframes showRedNav {
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

如果需要兼容不支持CSS滚动驱动动画的浏览器,可以使用下面的React JS实现方案。


React JS实现方案

通过监听滚动事件判断蓝色导航是否固定到顶部,控制红色导航的展示状态:

完整JS代码

const Navbar = () => {
  const [showRedNav, setShowRedNav] = React.useState(false);
  const navRef = React.useRef(null);

  React.useEffect(() => {
    const handleScroll = () => {
      const scrollTop = window.scrollY;
      const navOffsetTop = navRef.current.offsetTop;
      // 滚动距离大于等于nav的初始偏移量时,说明nav已经固定到顶部
      setShowRedNav(scrollTop >= navOffsetTop);
    };
    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);

  return (
    <nav ref={navRef}>
      <div className={showRedNav ? 'active' : ''}></div>
      <div></div>
    </nav>
  )
}

// Render it
ReactDOM.render(
  <Navbar/>,
  document.getElementById("react")
);

对应CSS补充代码

/* 红色导航项样式调整 */
nav div:first-child {
  background-color: red;
  transform: translateY(-100%);
  opacity: 0;
  transition: all 0.3s ease;
}
nav div:first-child.active {
  transform: translateY(0);
  opacity: 1;
}

内容的提问来源于stack exchange,提问作者Luke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:15:04