SCSS 不支持系统高对比度模式,必须用原生 @media (prefers-contrast: high) 实现;禁用 Sass 变量模拟、lightness() 计算及嵌套媒体查询,优先加固 border/outline 等可继承属性,并确保关键信息不依赖 background-image。

SCSS 本身不感知系统高对比度模式,@media (prefers-contrast: high) 必须由 CSS 原生支持,SCSS 只能生成它——关键在于别把颜色写死,也别用 lightness() 替代 WCAG 对比度校验。
必须用 @media (prefers-contrast: high) 而非变量模拟
系统级高对比度(Windows 高对比主题、macOS 的“增加对比度”)只响应原生媒体查询,SCSS 变量或 $high-contrast-mode: true 这类开关毫无作用。浏览器不会解析 Sass 变量,也不会在编译时读取系统设置。
- ✅ 正确写法:
@media (prefers-contrast: high) { .btn { border: 3px solid #000; } } - ❌ 错误写法:
@if $high-contrast-mode { ... }—— 编译时就确定了,无法随系统切换 - ⚠️ 注意:该媒体查询目前仅 Chromium 和 Safari 支持,Firefox 尚未实现(2026 年 9 月)
颜色不能依赖 lightness() 或手动调亮/调暗
lightness(#333) 返回的是 HSL 模型下的明度值,和 WCAG 所需的相对亮度(luminance)完全不是一回事。高对比度模式下,系统会强制重绘文本与背景为极值色(如黑底白字),此时你用 darken($color, 20%) 算出的颜色可能反而低于 4.5:1 阈值,甚至变成灰蒙蒙一片。
- 高对比度启用后,用户代理样式表会覆盖大部分 color/background-color,但 border、outline、box-shadow 等仍由你控制——这些才是重点加固对象
- 别试图在 SCSS 里“预测”高对比色:传入
#6366f1,返回#000是错的;应统一设为currentColor或硬编码 WCAG 合规的极值色(如#000、#fff、#0000ff) - 若需保留品牌色语义,可用
color: var(--primary-high-contrast, #000);,再通过 JS 检测window.matchMedia('(prefers-contrast: high)').matches动态注入 CSS 变量
SCSS 能做的真正有用的事:生成 fallback 类 + 隔离可访问性规则
与其在 SCSS 里硬算对比度,不如把它当“模板引擎”,专注生成结构清晰、可被 JS 或 CSS 覆盖的类名和占位规则。
- 用
@use把高对比样式抽成独立模块:@use "accessibility/high-contrast" as hc;,避免污染主样式流 - 输出带明确语义的类名,例如
.text-high-contrast、.border-high-contrast,而非.text-hc-1这类无意义缩写 - 所有高对比相关声明必须包裹在
@media (prefers-contrast: high)内部,且禁止嵌套到其他媒体查询中(如不要写@media (min-width: 768px) { @media (prefers-contrast: high) { ... } },部分浏览器不识别嵌套媒体查询) - 慎用
!important:高对比模式下,用户代理样式已带!important,你的同级声明会被直接忽略;唯一可靠方式是提高选择器权重(如加一层.app前缀)或使用更具体的属性(outline比border更易被尊重)
最常被忽略的一点:高对比度模式下,background-image 几乎总会被禁用,所有依赖渐变、纹理、SVG 背景的视觉提示都会消失。SCSS 无法绕过这点,只能提前约定——所有关键信息必须通过 color、border、content 或 outline 传递,而不是藏在背景图里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











