当AA颜色评分高于4.5时如何修改文本颜色?
解决AA颜色评分高于4.5时修改文本样式的方案
核心思路
要实现“当文本与背景的WCAG AA对比度评分(即对比度比值)高于4.5时修改文本颜色”,需要完成两个核心步骤:
- 计算文本色与背景色的对比度比值
- 根据比值动态切换
Typography的color属性
实现方案
1. 计算对比度比值
你可以直接使用Material-UI(假设你用的是MUI的Typography组件)内置的getContrastRatio工具函数,或者自行实现符合WCAG标准的计算逻辑。
方式一:使用MUI内置工具函数
import { getContrastRatio } from '@mui/material/styles';
方式二:自定义对比度计算函数
如果不用MUI,可自行实现标准计算逻辑:
// 将十六进制颜色转为RGB数组 const hexToRgb = (hex) => { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return [r, g, b]; }; // 计算颜色的相对亮度(WCAG公式) const getRelativeLuminance = (r, g, b) => { const sRGB = [r, g, b].map(val => { val /= 255; return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4); }); return 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2]; }; // 计算两个颜色的对比度比值 const getContrastRatio = (color1, color2) => { const [r1, g1, b1] = hexToRgb(color1); const [r2, g2, b2] = hexToRgb(color2); const l1 = getRelativeLuminance(r1, g1, b1); const l2 = getRelativeLuminance(r2, g2, b2); const lighter = Math.max(l1, l2); const darker = Math.min(l1, l2); return (lighter + 0.05) / (darker + 0.05); };
2. 动态切换文本颜色
根据对比度比值是否大于4.5,给Typography设置对应的颜色值。
场景一:背景色固定已知
import { Typography } from '@mui/material'; import { getContrastRatio } from '@mui/material/styles'; // 自定义颜色配置 const textEmphasis = '#666666'; // 原文本色 const backgroundColor = '#ffffff'; // 固定背景色 const highContrastReplacementColor = '#ff0000'; // 对比度高于4.5时的替换色 const MyComponent = () => { const contrastRatio = getContrastRatio(textEmphasis, backgroundColor); const targetTextColor = contrastRatio > 4.5 ? highContrastReplacementColor : textEmphasis; return ( <Typography color={targetTextColor}> Any text... </Typography> ); };
场景二:背景色动态(继承自父元素)
如果背景色是动态变化的,需要通过getComputedStyle获取实际渲染的背景色再计算对比度:
import { useEffect, useState } from 'react'; import { Typography } from '@mui/material'; import { getContrastRatio } from '@mui/material/styles'; const textEmphasis = '#666666'; const highContrastReplacementColor = '#ff0000'; const MyComponent = () => { const [targetTextColor, setTargetTextColor] = useState(textEmphasis); useEffect(() => { const container = document.getElementById('text-container'); if (!container) return; // 将rgb格式背景色转为十六进制 const computedBg = getComputedStyle(container).backgroundColor; const rgbToHex = (rgbStr) => { const values = rgbStr.match(/\d+/g).map(Number); return `#${values.map(val => val.toString(16).padStart(2, '0')).join('')}`; }; const bgHex = rgbToHex(computedBg); // 计算对比度并更新文本色 const contrastRatio = getContrastRatio(textEmphasis, bgHex); setTargetTextColor(contrastRatio > 4.5 ? highContrastReplacementColor : textEmphasis); }, []); return ( <div id="text-container"> <Typography color={targetTextColor}> Any text... </Typography> </div> ); };
内容的提问来源于stack exchange,提问作者triple-D
相关产品推荐
相关产品推荐

