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

实现菜单文字随下方背景动态切换黑白颜色的问题排查

问题描述

我要实现菜单文字根据下方背景颜色自动在黑/白之间切换。试过mix-blend-mode,但部分场景下文字辨识度差。

已经完成背景颜色分析并输出对应颜色的功能,但程序判断时会误读自身元素。尝试通过分析远离文字的:before伪元素来规避该问题,并未生效。

核心问题

程序能够识别背景颜色,但无法按照「深色背景显示白色文字、浅色背景显示黑色文字」的逻辑切换文字颜色。尝试过多种方案,要么出现颜色闪烁,要么完全不改变颜色。

相关代码

JavaScript

function getContrastRatio(color1, color2) {
  // Convert hex colors to RGB if necessary
  color1 = (color1.charAt(0) === '#') ? color1.substr(1) : color1;
  color2 = (color2.charAt(0) === '#') ? color2.substr(1) : color2;

  // Extract RGB values
  var r1 = parseInt(color1.substr(0, 2), 16);
  var g1 = parseInt(color1.substr(2, 2), 16);
  var b1 = parseInt(color1.substr(4, 2), 16);
  var r2 = parseInt(color2.substr(0, 2), 16);
  var g2 = parseInt(color2.substr(2, 2), 16);
  var b2 = parseInt(color2.substr(4, 2), 16);

  // Calculate relative luminance
  var lum1 = (Math.max(r1, g1, b1) + Math.min(r1, g1, b1)) / 2;
  var lum2 = (Math.max(r2, g2, b2) + Math.min(r2, g2, b2)) / 2;

  // Calculate contrast ratio
  var contrastRatio = (lum1 + 0.05) / (lum2 + 0.05);

  return contrastRatio;
}

function readBackgroundColor() {
  var menu = document.querySelector('.sticky-menu');
  var contentTop = menu.offsetTop + menu.offsetHeight;
  
  // Use the body as the default content element
  var content = document.body;

  // Iterate over all elements with class "colour" to find the one under the menu
  var colours = document.querySelectorAll('.colour');
  for (var i = 0; i < colours.length; i++) {
    var rect = colours[i].getBoundingClientRect();
    if (rect.top >= contentTop && colours[i] !== menu) { // Exclude the menu from consideration
      break;
    }
    content = colours[i];
  }

  // Check if the content element is a child of the menu
  if (!menu.contains(content)) {
    var computedStyle = window.getComputedStyle(content);
    var backgroundColor = computedStyle.backgroundColor;

    // Calculate contrast ratio for black and white text
    var blackContrast = getContrastRatio(backgroundColor, 'black');
    var whiteContrast = getContrastRatio(backgroundColor, 'white');

    // Choose the color with better contrast
    var textColor = blackContrast > whiteContrast ? 'black' : 'white';

    menu.style.color = textColor;

    console.log("Background:", backgroundColor, "Text:", textColor);
  }
}

// Event listener for scroll
window.addEventListener('scroll', readBackgroundColor);

// Initial call to read background color
readBackgroundColor();

CSS

body, html {padding:0;margin:0;}
.colour {height:250px;width:100vw;}

.black {background:black;}
.blue  {background:blue;}
.red   {background:red;}
  
.sticky-menu {
  position: fixed;
  top: 0;
  padding: 10px;
  line-height:0;
  font-size:50px;
}

HTML

<div class="sticky-menu">home</div>

<div class="colour black"></div>
<div class="colour white"></div>
<div class="colour blue"></div>
<div class="colour red"></div>
<div class="colour white"></div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:21:01