导航栏滚动收缩 CSS代码 JS 代码 迭代记录

🎨CSS代码:

1. ✅️导航栏滚动收缩样式 - 2026年1月6日

:root {
  /* 导航栏滚动缩放 */
  --header-height-expanded: 135px;
  --header-height-shrunk: 80px;
  --transition-duration: 0.2s;
  --transition-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
/* ==========================================
   导航栏滚动收缩样式
   ========================================== */
.header-container {
  position: sticky;
  top: 12px;
  height: var(--header-height-expanded);
  min-height: unset;
  transition: height var(--transition-duration) var(--transition-easing);
  z-index: 1000;
}

.header-container.shrunk {
  height: var(--header-height-shrunk);
}

/* 收缩态遮罩 */
.header-container.shrunk::before {
  content: '';
  position: absolute;
  inset: -15px 0;
  pointer-events: auto;
  z-index: -1;
}

header {
  padding: 1em 1.6em;
}

/* ===== 行结构 ===== */
.header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.header-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;

  transform: translateY(0) translateZ(0);
  transition: transform var(--transition-duration) var(--transition-easing);
  will-change: transform;
  pointer-events: auto;
}

.header-container.shrunk .header-bottom {
  transform: translateY(-55px) translateZ(0);
  pointer-events: none;
}

/* ===== 占位元素 ===== */
.placeholder-top,
.placeholder-bottom {
  opacity: 1;
  transform: translateY(0) translateZ(0);
  transition:
    opacity calc(var(--transition-duration) * 0.75) var(--transition-easing),
    transform var(--transition-duration) var(--transition-easing);
  will-change: transform, opacity;
}

.header-container.shrunk .placeholder-top {
  opacity: 0;
  transform: translateY(-12px) translateZ(0);
  pointer-events: none;
}

.header-container.shrunk .placeholder-bottom {
  opacity: 0;
  transform: translateY(-20px) translateZ(0);
}

/* 导航按钮不动画 */
.header-bottom nav {
  transition: none;
}

/* ===== 交互修正 ===== */
.header-container.shrunk {
  pointer-events: none;
}

.header-container.shrunk nav,
.header-container.shrunk .user-menu-container,
.header-container.shrunk .user-menu-trigger {
  pointer-events: auto;
}

2. ✅️导航栏滚动收缩样式 - 保留 will-change / 去除 translateZ(0) 优化版 - 2026年1月9日

:root {
  /* 导航栏滚动缩放 */
  --header-height-expanded: 135px;
  --header-height-shrunk: 80px;
  --transition-duration: 0.2s;
  --transition-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
/* ==========================================
   导航栏滚动收缩样式 - 优化版
   ========================================== */
.header-container {
  position: sticky;
  top: 12px;
  height: var(--header-height-expanded);
  min-height: unset;
  transition: height var(--transition-duration) var(--transition-easing);
  z-index: 1000;
}

.header-container.shrunk {
  height: var(--header-height-shrunk);
}

/* 收缩态遮罩 */
.header-container.shrunk::before {
  content: '';
  position: absolute;
  inset: -15px 0;
  pointer-events: auto;
  z-index: -1;
}

header {
  padding: 1em 1.6em;
}

/* ===== 行结构 ===== */
.header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.header-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  transform: translateY(0);
  transition: transform var(--transition-duration) var(--transition-easing);
  will-change: transform;
  pointer-events: auto;
}

.header-container.shrunk .header-bottom {
  transform: translateY(-55px);
  pointer-events: none;
}

/* ===== 占位元素 ===== */
.placeholder-top,
.placeholder-bottom {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity calc(var(--transition-duration) * 0.75) var(--transition-easing),
    transform var(--transition-duration) var(--transition-easing);
  will-change: transform, opacity;
}

.header-container.shrunk .placeholder-top {
  opacity: 0;
  transform: translateY(-12px);
  pointer-events: none;
}

.header-container.shrunk .placeholder-bottom {
  opacity: 0;
  transform: translateY(-20px);
}

/* 导航按钮不动画 */
.header-bottom nav {
  transition: none;
}

/* ===== 交互修正 ===== */
.header-container.shrunk {
  pointer-events: none;
}

.header-container.shrunk nav,
.header-container.shrunk .user-menu-container,
.header-container.shrunk .user-menu-trigger {
  pointer-events: auto;
}

3. ✅️导航栏滚动收缩样式 - 统一动画视觉开关版 - 2026年1月10日

:root {
  /* 导航栏滚动缩放配置 */
  --header-anim-switch: 1; 
  --header-height-expanded: 135px;
  --header-height-shrunk: 80px;
  --transition-duration: 0.2s;
  --transition-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
/* ==========================================
   导航栏滚动收缩样式 - 统一动画视觉开关版
   ========================================== */
.header-container {
  position: sticky;
  top: 12px;
  height: var(--header-height-expanded);
  min-height: unset;
  transition: height calc(var(--transition-duration) * var(--header-anim-switch)) var(--transition-easing);
  z-index: 1000;
}

.header-container.shrunk {
  height: var(--header-height-shrunk);
}

/* 收缩态遮罩 */
.header-container.shrunk::before {
  content: '';
  position: absolute;
  inset: -15px 0;
  pointer-events: auto;
  z-index: -1;
}

header {
  padding: 1em 1.6em;
}

/* ===== 行结构 ===== */
.header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.header-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  transform: translateY(0);
  /* 所有内部元素使用同一个变量 */
  transition: transform calc(var(--transition-duration) * var(--header-anim-switch)) var(--transition-easing);
  will-change: transform;
  pointer-events: auto;
}

.header-container.shrunk .header-bottom {
  transform: translateY(-55px);
  pointer-events: none;
}

/* ===== 占位元素 ===== */
.placeholder-top,
.placeholder-bottom {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity calc(var(--transition-duration) * 0.75 * var(--header-anim-switch)) var(--transition-easing),
    transform calc(var(--transition-duration) * var(--header-anim-switch)) var(--transition-easing);
  will-change: transform, opacity;
}

.header-container.shrunk .placeholder-top {
  opacity: 0;
  transform: translateY(-12px);
  pointer-events: none;
}

.header-container.shrunk .placeholder-bottom {
  opacity: 0;
  transform: translateY(-20px);
}

/* 导航按钮不动画 */
.header-bottom nav {
  transition: none;
}

/* ===== 交互修正 ===== */
.header-container.shrunk {
  pointer-events: none;
}

.header-container.shrunk nav,
.header-container.shrunk .user-menu-container,
.header-container.shrunk .user-menu-trigger {
  pointer-events: auto;
}

⚡️JS 代码:

1. 🔙导航栏滚动收缩功能 - Safari 浏览器兼容 - 2026年1月6日

// =============================
// 14. 导航栏滚动收缩功能 - Safari 浏览器兼容
// =============================
function initHeaderShrink() {
  const runInit = () => {
    const header = document.querySelector(".header-container");
    if (!header) return;

    // 差值需大于 展开高度135-收缩高度80=55
    const SHRINK_AT = 65;
    const EXPAND_AT = 5;

    let isShrunk = false;
    let lastScrollY = window.scrollY;
    let ticking = false;

    const updateHeaderState = () => {
      const scrollY = window.scrollY;
      const isScrollingDown = scrollY > lastScrollY;
      lastScrollY = scrollY;

      if (isScrollingDown && !isShrunk && scrollY > SHRINK_AT) {
        header.classList.add("shrunk");
        isShrunk = true;
      } else if (!isScrollingDown && isShrunk && scrollY < EXPAND_AT) {
        header.classList.remove("shrunk");
        isShrunk = false;
      }
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(updateHeaderState);
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });

    console.log("✅ 导航栏收缩功能已就绪");
  };

  // 延迟执行初始化函数 避免强制的重排
  if ("requestIdleCallback" in window) {
    requestIdleCallback(runInit, { timeout: 100 });
  } else {
    setTimeout(runInit, 100);
  }
}

2. 🔄导航栏滚动收缩功能 - 智能变速版 1 - 2026年1月8日

// =============================
// 14. 导航栏滚动收缩功能 - 智能变速版 1
// =============================
function initHeaderShrink() {
  const runInit = () => {
    const header = document.querySelector(".header-container");
    if (!header) return;

    // 差值需大于 展开高度135-收缩高度80=55
    const SHRINK_AT = 65; 
    const EXPAND_AT = 5;

    let isShrunk = false;
    let lastScrollY = window.scrollY;
    let ticking = false;

    // 核心速度阈值 强制缩放/展开无动画
    const SPEED_THRESHOLD = 3; 

    const updateHeaderState = () => {
      const scrollY = window.scrollY;
      const isScrollingDown = scrollY > lastScrollY;
      
      // 计算滚动速度 绝对值
      const scrollSpeed = Math.abs(scrollY - lastScrollY);
      
      // 智能切换动画
      if (scrollSpeed > SPEED_THRESHOLD) {
        // 快速滚动 无动画
        header.style.transition = 'none';
      } else {
        // 慢速滚动 恢复动画
        header.style.transition = '';
      }
      
      // 正常的收缩/展开逻辑
      if (isScrollingDown && !isShrunk && scrollY > SHRINK_AT) {
        header.classList.add("shrunk");
        isShrunk = true;
      } else if (!isScrollingDown && isShrunk && scrollY < EXPAND_AT) {
        header.classList.remove("shrunk");
        isShrunk = false;
      }
      
      lastScrollY = scrollY;
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(updateHeaderState);
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    console.log("✅ 导航栏收缩功能已就绪");
  };

  // 延迟执行初始化函数 避免强制的重排
  if ("requestIdleCallback" in window) {
    requestIdleCallback(runInit, { timeout: 100 });
  } else {
    setTimeout(runInit, 100);
  }
}

3. ✅️导航栏滚动收缩功能 - 智能变速版 2 - 2026年1月8日

// =============================
// 14. 导航栏滚动收缩功能 - 智能变速版 2
// =============================
function initHeaderShrink() {
  const runInit = () => {
    const header = document.querySelector(".header-container");
    if (!header) return;

    // 差值需大于 展开高度135-收缩高度80=55
    const SHRINK_AT = 80; //65 闲置后收缩动画异常
    const EXPAND_AT = 5;

    let isShrunk = false;
    let lastScrollY = window.scrollY;
    let ticking = false;

    // 核心速度阈值 强制缩放/展开无动画
    const SPEED_THRESHOLD = 16; 

    // 状态标记 防止在临界值附近频繁闪烁
    let isScrollingFast = false; 

    const updateHeaderState = () => {
      const scrollY = window.scrollY;
      const isScrollingDown = scrollY > lastScrollY;

      // 计算滚动速度
      const scrollSpeed = Math.abs(scrollY - lastScrollY);

      // 状态变更才操作 DOM
      // 跨越阈值时修改 transition 属性
      if (scrollSpeed > SPEED_THRESHOLD && !isScrollingFast) {
        // 快速滚动 无动画
        header.style.transition = 'none';
        isScrollingFast = true;
      } else if (scrollSpeed <= SPEED_THRESHOLD && isScrollingFast) {
        // 慢速滚动 恢复动画
        header.style.transition = '';
        isScrollingFast = false;
      }

      // 正常的收缩/展开逻辑
      if (isScrollingDown && !isShrunk && scrollY > SHRINK_AT) {
        header.classList.add("shrunk");
        isShrunk = true;
      } else if (!isScrollingDown && isShrunk && scrollY < EXPAND_AT) {
        header.classList.remove("shrunk");
        isShrunk = false;
      }

      lastScrollY = scrollY;
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(updateHeaderState);
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });

    // 初始化执行一次 确保刷新页面状态正确
    updateHeaderState();

    console.log("✅ 导航栏收缩功能已就绪");
  };

  // 延迟执行初始化函数 避免强制的重排
  if ("requestIdleCallback" in window) {
    requestIdleCallback(runInit, { timeout: 100 });
  } else {
    setTimeout(runInit, 100);
  }
}

4. ✅️导航栏滚动收缩功能 - 智能变速简化版 3 - 2026年1月9日

// =============================
// 14. 导航栏滚动收缩功能 - 智能变速简化版 3 √
// =============================
function initHeaderShrink() {
  const runInit = () => {
    const header = document.querySelector(".header-container");
    if (!header) return;

    // 差值需大于 展开高度135-收缩高度80=55
    const SHRINK_AT = 80; 
    const EXPAND_AT = 5;

    let isShrunk = false;
    let lastScrollY = window.scrollY;
    let ticking = false;

    // 滚动速度阈值 强制缩放无动画
    const SPEED_THRESHOLD = 16; 

    // 状态标记 防止在临界值附近频繁闪烁
    let isScrollingFast = false; 

    const updateHeaderState = () => {
      const scrollY = window.scrollY;
      const isScrollingDown = scrollY > lastScrollY;

      // 计算滚动速度
      const scrollSpeed = Math.abs(scrollY - lastScrollY);

      // 状态变更才操作 DOM
      // 跨越阈值时修改 transition 属性
      if (scrollSpeed > SPEED_THRESHOLD && !isScrollingFast) {
        // 快速滚动 无动画
        header.style.transition = 'none';
        isScrollingFast = true;
      } else if (scrollSpeed <= SPEED_THRESHOLD && isScrollingFast) {
        // 慢速滚动 恢复动画
        header.style.transition = '';
        isScrollingFast = false;
      }

      // 正常收缩逻辑
      if (isScrollingDown && !isShrunk && scrollY > SHRINK_AT) {
        header.classList.add("shrunk");
        isShrunk = true;
      } else if (!isScrollingDown && isShrunk && scrollY < EXPAND_AT) {
        header.classList.remove("shrunk");
        isShrunk = false;
      }

      lastScrollY = scrollY;
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(updateHeaderState);
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });

    // 初始化执行一次 确保刷新页面状态正确
    updateHeaderState();

    console.log("✅ 导航栏收缩功能已就绪");
  };

  // 延迟执行初始化函数 避免强制的重排
  if ("requestIdleCallback" in window) {
    requestIdleCallback(runInit, { timeout: 100 });
  } else {
    setTimeout(runInit, 100);
  }
}

5. ✅️导航栏滚动收缩功能 - 统一动画视觉开关版 - 2026年1月10日

// =============================
// 14. 导航栏滚动收缩功能 - 统一动画视觉开关版
// =============================
function initHeaderShrink() {
  const runInit = () => {
    const header = document.querySelector(".header-container");
    if (!header) return;

    const SHRINK_AT = 80; 
    const EXPAND_AT = 5;

    let isShrunk = false;
    let lastScrollY = window.scrollY;
    let ticking = false;

    // 滚动速度阈值
    const SPEED_THRESHOLD = 16; 

    // 状态标记 防止在临界值附近频繁闪烁
    let isScrollingFast = false; 

    const updateHeaderState = () => {
      const scrollY = window.scrollY;
      const isScrollingDown = scrollY > lastScrollY;

      // 计算滚动速度
      const scrollSpeed = Math.abs(scrollY - lastScrollY);

      // 通过修改变量值 统一控制所有子元素动画
      if (scrollSpeed > SPEED_THRESHOLD && !isScrollingFast) {
        // 快速滚动:将变量设为 0,所有依赖该变量的 transition 时间都变成 0
        header.style.setProperty('--header-anim-switch', '0');
        isScrollingFast = true;
      } else if (scrollSpeed <= SPEED_THRESHOLD && isScrollingFast) {
        // 慢速滚动:将变量恢复为 1,动画恢复正常
        header.style.setProperty('--header-anim-switch', '1');
        isScrollingFast = false;
      }

      // 正常收缩逻辑
      if (isScrollingDown && !isShrunk && scrollY > SHRINK_AT) {
        header.classList.add("shrunk");
        isShrunk = true;
      } else if (!isScrollingDown && isShrunk && scrollY < EXPAND_AT) {
        header.classList.remove("shrunk");
        isShrunk = false;
      }

      lastScrollY = scrollY;
      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(updateHeaderState);
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });

    // 初始化执行一次 确保刷新页面状态正确
    updateHeaderState();

    console.log("✅ 导航栏收缩功能已就绪");
  };

  // 延迟执行初始化函数 避免强制的重排
  if ("requestIdleCallback" in window) {
    requestIdleCallback(runInit, { timeout: 100 });
  } else {
    setTimeout(runInit, 100);
  }
}