最稳方案是用div容器+内部渐变div配合transform:scaleY()控制高度,设transform-origin:bottom、渐变to top,通过CSS变量驱动避免重排,刻度用flex+data-*属性精准定位,外层加touch-action:pan-y防滑动拦截。

用 CSS 渐变 + transform 做可动温度柱体,别碰 SVG 动画
纯 HTML + CSS 实现温度计式仪表盘,核心是让“水银柱”随数值伸缩。最稳的方案不是 SVG animate 或 JS 重绘路径,而是用一个 div 作为柱体容器,内部嵌套一个带线性渐变背景的 div,再用 transform: scaleY() 控制高度变化——这样 GPU 加速、无重排、兼容到 IE10+。
常见错误是直接改 height:触发 layout,动画卡顿;或用 clip-path 裁剪,iOS Safari 15.4 之前有渲染残留 bug。
实操建议:
- 柱体容器设固定
height和overflow: hidden,内部柱子设origin: bottom(配合transform-origin: bottom) - 渐变方向必须是
to top,否则scaleY(0.6)会从顶部压缩,看起来像“液面下沉”而非“液柱升高” - 数值映射到 0–1 区间时,注意温度范围是否含负值:比如显示 −20°C 到 50°C,0°C 对应的是 (0 − (−20)) / (50 − (−20)) = 0.286,不是 0.5
JS 更新温度值时,避免反复 setAttribute 或 innerHTML
每次温度变化都调用 element.setAttribute('style', ...) 或拼接 innerHTML,会导致样式重计算和 DOM 污染。尤其在每秒更新多次的场景(如串口读温湿度),页面会明显掉帧。
立即学习“前端免费学习笔记(深入)”;
正确做法是只操作 CSS 自定义属性,再由 CSS 变量驱动 transform:
document.documentElement.style.setProperty('--temp-ratio', ratio.toFixed(3));CSS 中写:
.thermometer-column { transform: scaleY(var(--temp-ratio)); }这样 JS 只做一次 style 写入,CSS 引擎自动合成,不触发 layout/paint。
注意点:
-
ratio必须是 0–1 的浮点数,超出范围会导致柱体消失(scaleY(1.2)没问题,但scaleY(-0.1)会翻转并裁剪) - IE 不支持 CSS 变量,若需兼容,改用
element.style.transform = `scaleY(${ratio})`,但要加前缀-ms-transform - 不要在循环里频繁读取
offsetHeight或getComputedStyle,它们强制同步 layout
刻度文字对齐不准?用 flex + data-* 属性生成更可控
很多人用绝对定位 + top: X% 放刻度标签,结果发现 37°C 标签总偏上 2px——这是因为百分比基于父容器高度,而字体 baseline、行高、padding 全部影响最终视觉位置。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
更可靠的方式是把刻度当 flex 项目排列,用 data-temp 存真实温度值,JS 计算后设置 order 或 margin-top:
<div class="scale"> <span data-temp="0">0°C</span> <span data-temp="20">20°C</span> <span data-temp="37">37°C</span> </div>
然后 CSS 设:
.scale { display: flex; flex-direction: column; height: 300px; }
.scale span { margin-top: calc(var(--pos) * 1px); } /* --pos 由 JS 注入 */优势是刻度位置完全脱离字体渲染干扰,且方便响应式重算(比如屏幕变窄时统一缩放所有 --pos)。
避坑提醒:
- 别用
position: absolute+calc()混合单位(如top: calc(50% - 1em)),Safari 对 calc 中混合单位解析不稳定 - 如果刻度文字需要旋转(如侧标),用
transform: rotate(-90deg)而非writing-mode,后者在 Firefox 中对齐异常
移动端触摸区域小、误触多?给 thermometer 加 touch-action
仪表盘常放在 dashboard 页面右下角,用户想滑动页面时,手指经过温度计区域容易被拦截——尤其 iOS Safari 默认对 transform 元素启用 touch-action: none,导致页面无法滚动。
解决方法很简单,在温度计最外层容器加:
touch-action: pan-y;
这样竖向滑动交还给页面,但温度计自身仍可响应点击或长按事件(比如点开详情)。
关键细节:
- 不要写
touch-action: auto,它在部分安卓 WebView 中等同于none - 如果仪表盘支持手势缩放(如双指放大柱体),才用
pinch-zoom,否则一律禁用,避免和浏览器默认行为冲突 - 测试真机时重点看微信内置浏览器(X5 内核),它对
touch-action支持滞后,必要时降级为passive事件监听
真正难的不是画出一根柱子,而是让它的高度变化始终和传感器数据对齐、不抖动、不卡顿、不抢滑动——这些细节都在 CSS 渲染管线和事件分发机制里,不在教程第一步。


















