Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 339

Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 392

Deprecated: parse_url(): Passing null to parameter #1 ($url) of type string is deprecated in /www/wwwroot/blog_qqvbc_com/usr/plugins/Access/Access_Core.php on line 394
移动端CSS获得手机上、下安全距离 - Joyber 的博客

calc(20rpx + env(safe‑area‑inset‑bottom)) 详解

env() 是CSS环境变量函数,safe‑area‑inset‑bottom 代表iOS全面屏底部手势条(小黑条)的避让高度,单位px。

你的写法含义:20rpx固定距离 + 系统给的底部安全区px距离,常用于小程序底部fixed悬浮按钮、底部栏的bottom / padding‑bottom。

一、四个安全区环境变量

env(safe-area-inset-top);    /* 顶部刘海/灵动岛高度 px */
env(safe-area-inset-right);  /* 右边避让,横屏生效 px */
env(safe-area-inset-bottom); /* 底部手势条高度 px */
env(safe-area-inset-left);   /* 左边避让,横屏生效 px */
  • 非全面屏手机:safe‑area‑inset‑bottom = 0px,表达式等价于 calc(20rpx + 0),只会保留你的20rpx基础距离。
  • iPhone全面屏:会自动叠加小黑条的高度(34px等)。

二、关键坑点(高频踩坑)

1️⃣ H5网页必须开启 viewport‑fit=cover

不加,safe‑area‑inset‑bottom 永远等于0,完全失效。

<meta name="viewport" content="width=device‑width,initial‑scale=1,viewport‑fit=cover">
微信小程序不需要写meta,框架默认开启cover模式,直接可用。

2️⃣ 历史兼容:constant()(iOS11.2以前旧版本)

旧版Safari用constant(),新版本用env(),constant写在env上方,做降级兼容。

/* 兼容旧iOS */
padding‑bottom: calc(20rpx + constant(safe‑area‑inset‑bottom));
padding‑bottom: calc(20rpx + env(safe‑area‑inset‑bottom));

3️⃣ calc内部符号两侧必须空格,否则直接失效

✅正确:calc(20rpx + env(safe‑area‑inset‑bottom))
❌错误:calc(20rpx+env(safe‑area‑inset‑bottom)) +两边没空格会解析失败。

4️⃣ 单位混用注意(小程序)

env(safe‑area‑inset‑bottom) 返回px;你写的是rpx。

微信小程序内部会自动做单位换算,calc(rpx + env(xxx)) 是支持直接写的,不需要手动转px,小程序引擎自动处理。
H5不支持rpx单位,H5要统一全部改成px。

5️⃣ env支持回退默认值(第二个参数)

设备不支持安全区变量时,使用回退值:

env(safe‑area‑inset‑bottom, 0px);

示例:

padding‑bottom: calc(20rpx + env(safe‑area‑inset‑bottom,0px));

三、两种业务场景示例(微信小程序)

场景1:底部fixed悬浮按钮,bottom定位

.fixed‑btn{
  position: fixed;
  bottom: calc(20rpx + env(safe‑area‑inset‑bottom));
  right: 30rpx;
}

含义:距离底部基础20rpx,iPhone全面屏再叠加手势条高度。普通安卓/非全面屏,就只有20rpx。

场景2:底部栏增加内边距padding‑bottom(推荐,避免内容被小黑条遮挡)

.footer‑bar{
  padding‑bottom: calc(24rpx + constant(safe‑area‑inset‑bottom));
  padding‑bottom: calc(24rpx + env(safe‑area‑inset‑bottom));
}

四、常见错误现象排查清单

  1. env完全不起作用:

    • H5:检查meta有没有加viewport‑fit=cover
    • 符号+忘记加空格;
    • 顺序写反,env写在constant前面。
  2. iPhone底部距离变得巨大:>

    你写的是基础距离 + safe‑area‑inset‑bottom,如果你本身元素已经靠到屏幕最底边,就不要额外再加基础值,直接写 env(safe‑area‑inset‑bottom),否则会双重叠加,留白过大。

五、H5完整可复制样板

.bottom‑wrap {
  padding‑bottom: calc(16px + constant(safe‑area‑inset‑bottom));
  padding‑bottom: calc(16px + env(safe‑area‑inset‑bottom,0px));
}
小程序直接复制,把px替换成rpx即可。

标签: none

添加新评论