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

求助:单页滚动网站中固定Logo随section滚动的CSS裁剪/遮罩实现

嘿,这个随滚动区块变化颜色的Logo效果真的很有质感!我来给你一步步拆解怎么实现它~

核心思路

你已经用叠加Logo+z-index分层的思路是对的,接下来的关键就是根据滚动位置,动态裁剪上层Logo,让下层Logo的颜色在对应区块位置显示出来,模拟出Logo颜色随下方区块变化的效果。

1. 先搭好基础结构

首先把HTML结构理顺,两个完全重合的Logo(比如一个白色、一个黑色)放在固定容器里,下面是各个全屏区块:

<!-- 固定定位的Logo容器 -->
<div class="logo-wrapper">
  <img src="logo-black.png" alt="品牌Logo" class="logo logo--bottom">
  <img src="logo-white.png" alt="品牌Logo" class="logo logo--top">
</div>

<!-- 各个页面区块 -->
<section class="page-section section-dark">区块1</section>
<section class="page-section section-light">区块2</section>
<section class="page-section section-dark">区块3</section>

2. 基础样式配置

给Logo固定定位、完全叠加,区块设置不同背景色:

.logo-wrapper {
  position: fixed;
  bottom: 20px;
  left: 20px;
  z-index: 999;
  width: 120px; /* 按你的实际Logo尺寸调整 */
  height: 80px;
  overflow: hidden;
}

.logo {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: contain; /* 确保Logo不变形 */
}

/* 下层Logo:比如黑色,对应浅色区块显示 */
.logo--bottom {
  z-index: 1;
}

/* 上层Logo:比如白色,对应深色区块显示 */
.logo--top {
  z-index: 2;
  /* 初始状态完全显示上层白色 */
  clip-path: inset(0 0 0 0);
}

/* 区块样式 */
.page-section {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
}

.section-dark {
  background-color: #222;
  color: #fff;
}

.section-light {
  background-color: #fff;
  color: #222;
}

3. 滚动监听+动态裁剪

通过JavaScript监听滚动事件,计算Logo与各个区块的位置关系,动态修改上层Logo的clip-path值,实现颜色切换:

const topLogo = document.querySelector('.logo--top');
const sections = document.querySelectorAll('.page-section');

// 节流函数,避免滚动时频繁触发影响性能
function throttle(func, delay = 16) {
  let lastRun = 0;
  return (...args) => {
    const now = Date.now();
    if (now - lastRun >= delay) {
      func(...args);
      lastRun = now;
    }
  };
}

function updateLogoClip() {
  const logoRect = topLogo.getBoundingClientRect();
  const logoTop = logoRect.top;
  const logoBottom = logoRect.bottom;
  const logoHeight = logoRect.height;

  sections.forEach(section => {
    const sectionRect = section.getBoundingClientRect();
    const sectionTop = sectionRect.top;
    const sectionBottom = sectionRect.bottom;

    // 情况1:Logo完全在当前区块内
    if (logoTop >= sectionTop && logoBottom <= sectionBottom) {
      if (section.classList.contains('section-dark')) {
        // 深色区块:显示上层白色Logo,完全不裁剪
        topLogo.style.clipPath = 'inset(0 0 0 0)';
      } else {
        // 浅色区块:裁剪掉上层白色,露出下层黑色
        topLogo.style.clipPath = 'inset(0 0 100% 0)';
      }
    }
    // 情况2:Logo跨两个区块(滚动过渡阶段)
    else if (logoTop < sectionBottom && logoBottom > sectionTop) {
      const overlapStart = Math.max(logoTop, sectionTop);
      const overlapEnd = Math.min(logoBottom, sectionBottom);
      const overlapHeight = overlapEnd - overlapStart;
      const overlapRatio = (overlapHeight / logoHeight) * 100;

      if (section.classList.contains('section-dark')) {
        // 深色区块在Logo上方:裁剪掉上层Logo的下半部分
        if (sectionTop < logoTop) {
          topLogo.style.clipPath = `inset(0 0 ${100 - overlapRatio}% 0)`;
        }
        // 深色区块在Logo下方:裁剪掉上层Logo的上半部分
        else {
          topLogo.style.clipPath = `inset(${100 - overlapRatio}% 0 0 0)`;
        }
      }
    }
  });
}

// 绑定滚动事件(加节流)
window.addEventListener('scroll', throttle(updateLogoClip));
// 页面加载时初始化一次
updateLogoClip();

4. 进阶优化(SVG Logo更高效)

如果你的Logo是SVG格式,不需要叠加两张图片,直接修改SVG的fill颜色+clip-path即可,更节省资源:

<div class="logo-wrapper">
  <svg class="logo logo--bottom" viewBox="0 0 120 80">
    <!-- SVG路径内容 -->
  </svg>
  <svg class="logo logo--top" viewBox="0 0 120 80">
    <!-- 相同的SVG路径内容 -->
  </svg>
</div>

CSS里直接设置fill颜色:

.logo--bottom { fill: #000; }
.logo--top { fill: #fff; }

这样就能完美实现你想要的滚动时Logo随下方区块变色的效果啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:09