如何让导航文本随背景图片自动变色以提升可见度?
问题与解决方案
问题
我有一个包含链接的菜单,还有一张跟随光标移动的图片(位于链接后方)。当图片移至链接下方时,链接因颜色对比不足可见度极低。我希望实现类似backdrop-filter: invert(100%);但仅作用于文本的效果,此前尝试使用mix-blend-mode: difference;未生效。
解决方案
原问题出在链接的混合模式仅与父容器nav的白色背景混合,而非下方图片。通过调整层级和背景设置,让混合模式直接作用于图片即可解决:
- 移除
nav的白色背景,避免遮挡链接与图片的混合效果; - 给链接容器
.links-container设置层级,确保它在图片上方; - 给图片容器
.link-image-container设置负层级,固定在链接下方; - 保留链接的
mix-blend-mode: difference;,让文本颜色随下方图片自动反转。
修改后的完整代码
HTML
<nav> <img src="./assets/svg/x.svg" alt="x icon" class="x"> <div class="links-container"> <a index="0" class="navigation-links" href="">Link</a> <a index="1" class="navigation-links" href="">Link</a> <a index="2" class="navigation-links" href="">Link</a> <a index="3" class="navigation-links" href="">Link</a> <a index="4" class="navigation-links" href="">Link</a> <a index="5" class="navigation-links" href="">Link</a> <a index="6" class="navigation-links" href="">Link</a> </div> <div class="link-image-container"> <img src="./assets/pictures/nature/photo_1.jpg" alt="link image example" class="link-image"> <img src="./assets/pictures/night/photo_1.jpg" alt="link image example" class="transition-image"> </div> </nav>
CSS
.burger, .x { position: fixed; cursor: pointer; z-index: 10; top: 1%; right: 1%; opacity: 0; transform: scaleX(1.25); animation: fadeIn .25s 2.5s ease forwards; } @keyframes fadeIn { to { opacity: 1; } } .x { position: absolute; opacity: 1; top: calc(50% - 24px); right: 1%; transform: none; animation: none; } nav { position: fixed; display: flex; flex-flow: row nowrap; justify-content: center; align-items: flex-start; transform-origin: center right; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; /* 移除白色背景,避免影响混合模式 */ transform: scaleX(1); transition: transform ease-in-out 1.25s; } .links-container { display: flex; flex-flow: column nowrap; justify-content: center; align-items: flex-start; height: 100%; width: 100%; position: relative; z-index: 1; /* 确保链接在图片上方 */ } .navigation-links { cursor: pointer; text-decoration: none; font-family: playfair; text-align: center; mix-blend-mode: difference; /* 文本与下方图片自动反转对比 */ z-index: 10; font-size: 39px; width: 100%; padding: 1% 0; opacity: 1; transition: 1s ease; color: #fff; /* 改为白色,配合difference模式效果更稳定 */ transform-origin: left; transform: skewY(0deg); } .navigation-links:hover { font-family: playfair-italic; } .link-image-container { position: absolute; overflow: hidden; display: flex; flex-flow: row nowrap; justify-content: center; align-items: center; pointer-events: none; width: 20vw; height: 55vh; transition: 0.15s; z-index: -1; /* 固定在链接下方 */ } .link-image-container img { pointer-events: none; height: 100%; width: 100%; } .transition-image { position: absolute; top: 0; left: 100%; }
JavaScript
let links = document.getElementsByClassName('navigation-links'); // 菜单展开逻辑 document.getElementsByClassName('burger')[0].addEventListener('click', () => { document.getElementsByTagName('nav')[0].style.cssText = "transform: scaleX(1);"; let delay = 0; setTimeout(() => { for (let i = 0; i < links.length; i++) { links[i].style.cssText = `transition-delay: ${delay}s; transform: skewY(0deg); opacity: 1;`; delay += 0.15; } }, 1250); }); // 菜单收起逻辑 document.getElementsByClassName('x')[0].addEventListener('click', () => { let delay = 0; for (let i = 0; i < links.length; i++) { links[i].style.cssText = `transition-delay: ${delay}s; transform: skewY(10deg); opacity: 0;`; delay += 0.15; } setTimeout(function() { document.getElementsByTagName('nav')[0].style.cssText = "transform: scaleX(0);"; }, (150 * links.length) + 150); }); // 图片切换逻辑(预留) for (let i = 0; i < links.length; i++) { links[i].addEventListener('mouseover', function() { let categoryIndex = this.index; // 这里可以添加图片切换的逻辑 }); } // 图片跟随光标移动 const image = document.getElementsByClassName("link-image-container")[0]; let mouseX = 0; let mouseY = 0; let imageX = 0; let imageY = 0; let speed = 0.25; function movePicture() { let distX = mouseX - imageX; let distY = mouseY - imageY; imageX = imageX + (distX * speed); imageY = imageY + (distY * speed); let centerX = Math.max(Math.min(imageX - (image.offsetWidth / 2), window.innerWidth - image.offsetWidth), 0); let centerY = Math.max(Math.min(imageY - (image.offsetHeight / 2), window.innerHeight - image.offsetHeight), 0); image.style.left = `${centerX}px`; image.style.top = `${centerY}px`; requestAnimationFrame(movePicture); } movePicture(); document.addEventListener("mousemove", function(event) { mouseX = event.pageX; mouseY = event.pageY; });
内容的提问来源于stack exchange,提问作者Eli-ott
相关产品推荐
相关产品推荐

