直接用 data-change 属性和 CSS 属性选择器可实现无 JS 的涨跌色标:td[data-change^="-"] 标红(负数),td[data-change]:not([data-change^="-"]) 标绿(含 0 和正数),需确保 data-change 值为纯数字、颜色用 CSS 变量定义、箭头用 SVG 或伪元素对齐基线。

直接用 data-change 属性 + CSS 属性选择器就能实现涨跌色标,不需要 JS 判断、不依赖框架、不触发重排,浏览器原生支持。
用 data-change + 属性选择器控制颜色
核心是把数值语义化地挂到 HTML 元素上,让 CSS 自己“看懂”正负:
-
td[data-change^="-"]匹配所有以-开头的data-change值(即负数),标红 -
td[data-change]:not([data-change^="-"])匹配所有有data-change但不以-开头的值(含0和正数),标绿 - 务必写全
td[data-change],否则0会被漏掉——data-change="0"不以-开头,但若省略[data-change]条件,:not([data-change^="-"])会匹配所有td,失去约束 - 示例 HTML:
<td data-change="2.1">+2.1%</td><td data-change="-0.8">-0.8%</td>
JS 渲染时别等 DOM 挂完再补属性
动态生成表格(比如用 fetch 拿到 JSON 后 map 拼字符串)时,常见错误是先塞 innerHTML,再 querySelectorAll 扫描、判断、setAttribute——这多一次遍历,还可能因异步时机错乱漏标。
- 正确做法:在字符串拼接阶段就决定好属性和 class,例如:
data.map(v => <td data-change="${v}" class="${v = 0 ? '+' : ''}${v}%</td>) -
class名用up/down而非red/green,换主题时只改 CSS 变量,JS 层零修改 - 如果数据里带空格或单位(如
"-1.2 %"),data-change必须只存纯数字(-1.2),否则^="-"失效
颜色值别用 green/red 关键字
系统高对比度模式下,color: green 可能被强制替换为白色或黄色,涨跌语义彻底丢失。
立即学习“前端免费学习笔记(深入)”;
- 用具体 RGB 值:
color: rgb(46, 125, 50)(Material 深绿)、color: rgb(211, 47, 47)(深红) - 更推荐定义 CSS 变量:
--up-color: rgb(46, 125, 50); --down-color: rgb(211, 47, 47);,后续加透明度或适配暗色模式都方便 - 避免用十六进制简写(如
#2e7d32),部分读屏软件对rgb()解析更稳定,尤其涉及无障碍场景时
箭头图标必须用 SVG 或伪元素
别往 HTML 里硬塞 ↑ ↓ 字符——它们 baseline 和数字不对齐,缩放后边缘模糊,且无法单独调色或响应 hover。
- 内联 SVG 最可控:
<svg width="12" height="12" viewBox="0 0 12 12"><path d="M6 2L2 6h8z" fill="currentColor"/></svg>,配合currentColor自动继承文字颜色 - 或用伪元素:
.up::after { content: ""; display: inline-block; width: 0; height: 0; border-left: 4px solid transparent; border-right: 4px solid transparent; border-bottom: 6px solid currentColor; } - 无论哪种,都要加
vertical-align: middle或top对齐数字基线,否则视觉悬浮感明显
真正难的不是写对那两行 CSS,而是确保每个 data-change 值都是干净数字、每个 td 都带这个属性、每种颜色都通过变量统一管理——漏一个环节,整套机制就断在生产环境里。



















