env()不能赋值给Less变量,否则编译报Unrecognised input错误;正确写法是直接在CSS属性中使用env(safe-area-inset-top, 0px),或用~"env(...)"字符串插值(不可参与运算)。

env()不能赋值给Less变量,否则编译直接报错
Less编译器在构建阶段就尝试解析所有表达式,而env()是浏览器运行时才计算的CSS函数,它根本不在Less的语法认知范围内。写成@top: env(safe-area-inset-top); padding-top: @top;会触发Unrecognised input错误——不是兼容性问题,是编译根本过不去。
正确做法只有一条:绕过变量系统,把env()当纯CSS值直写进属性声明里。比如:
.header {
padding-top: env(safe-area-inset-top, 0px);
}
如果非得“看起来像变量”,可用~"env(...)";字符串插值骗过解析器,但仅限极简场景(如单个值),且无法参与运算(~"env(...) + 8px"无效)。
constant()和env()必须按顺序书写,fallback值不能省
旧版iOS(constant(),新版统一用env(),但它们不是互斥关系,而是降级链。浏览器按声明顺序从上到下匹配,遇到不支持的函数就跳过,继续看下一条。
立即学习“前端免费学习笔记(深入)”;
所以必须严格按“基础值 → constant() → env()”顺序写,且env()的第二个参数(fallback)必不可少:
-
padding-top: 20px;—— 所有设备兜底 -
padding-top: constant(safe-area-inset-top);—— 仅旧iOS生效 -
padding-top: env(safe-area-inset-top, 0px);—— 现代浏览器最终采用,0px确保不支持时不会退到0导致内容被刘海遮住
漏掉0px,在某些Android WebView或老微信X5内核里,整条声明会被丢弃,回退到上一条;若上一条也不存在,结果就是padding-top: 0。
@supports不能用在Less里检测env()兼容性
Less不理解@supports规则,把它当普通字符串原样输出,不会生成有效CSS条件逻辑。写@supports (padding-top: env(safe-area-inset-top)) { ... }在Less文件里,编译后只是无意义的文本,浏览器根本收不到。
想做特性检测,只能靠构建工具在CSS层注入,或者干脆放弃——因为iOS 11.2之前连@supports都不支持,双重fallback才是更实际的选择。真正起作用的,永远是那三行顺序排列的声明,而不是任何Less层面的条件判断。
viewport-fit=cover是前提,否则env()和constant()全失效
这两个函数只在<meta name="viewport" content="viewport-fit=cover">生效。H5页面默认是viewport-fit=auto,此时safe-area-inset-*全为0px,无论怎么写都白搭。
检查点有三个:
- HTML中
<meta>标签是否包含viewport-fit=cover - 是否在iOS Safari或支持该特性的WebView中打开(部分安卓WebView不支持)
- 是否在真机调试——模拟器可能不触发安全区计算
漏掉viewport-fit=cover,是90%以上“写了没反应”的根本原因,比语法错误还隐蔽。


















