求助:单页滚动网站中固定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
相关产品推荐
相关产品推荐

