Less无法动态设置HTML字体大小,因其是编译时预处理器;实际需JS根据clientWidth动态设置根字号,Less仅基于固定基准值(如37.5)静态换算rem。

Less本身不能动态设置html字体大小
这是最容易误解的一点:Less是编译时预处理器,所有变量、计算都在构建阶段完成,生成的是静态CSS。它无法读取document.documentElement.clientWidth或响应屏幕缩放——这些必须由运行时JS完成。
所以「在Less中动态计算根字号」这个说法本身不成立。真正要做的,是让Less配合JS设定的基准值,做静态换算。
用@base-font-size统一管理REM基准值
实际项目中,我们约定设计稿宽度为750px(iPhone 6/7/8二倍图),并按「视口宽度 ÷ 10」动态设置html字体大小。这意味着:在375px宽设备上,html字号为37.5px;在414px宽设备上为41.4px。
Less里只需固定一个参考基准(比如37.5),所有尺寸都按此换算,JS负责最终缩放对齐:
立即学习“前端免费学习笔记(深入)”;
-
@base-font-size: 37.5;—— 基于750px设计稿的1/10 - 所有尺寸写法:
.btn { width: unit(150 / @base-font-size, rem); } - 也可封装mixin:
.fs(@px) { font-size: unit(@px / @base-font-size, rem); },调用.fs(28);
为什么不用@media手动写断点设font-size
有人会想用Less的@media配合html { font-size: ... }分屏设置,但这会带来三个问题:
- 断点覆盖不全:Android碎片化严重,360/375/384/412/414等宽度都要手写,维护成本爆炸
- 无法响应横竖屏切换:
@media (orientation: landscape)触发后,JS能立刻重算,纯CSS断点却不会重新匹配 - 和真实渲染逻辑脱节:JS设置的根字号是基于
clientWidth,而@media (width: 375px)匹配的是设备逻辑分辨率,二者在缩放/UA干扰下常不一致
JS设置根字号的最小可靠写法
别直接抄lib-flexible那种复杂方案。现在最简且兼容iOS/Android主流机型的写法是:
(function () {
function setRootFontSize() {
const w = document.documentElement.clientWidth || 375;
// 强制不低于320,避免小屏异常
document.documentElement.style.fontSize = Math.max(w / 10, 32) + 'px';
}
setRootFontSize();
window.addEventListener('resize', setRootFontSize);
window.addEventListener('orientationchange', setRootFontSize);
})();
注意:这个JS必须在任何CSS(包括<link>样式表)之前执行,否则首屏会闪动。建议内联在顶部。
真正容易被忽略的点是——Less里的rem换算永远只对「设计稿像素值」负责;而JS设置的根字号,才是最终决定真实缩放比例的唯一开关。两者分工必须清晰,混在一起反而难调试。


















