最近,我有一项任务是使用iOS 11和WebKit的功能为iPhone X实现新的布局功能。

viewport-fit=cover在视口元标记中启用这些功能。

<meta name=“viewport” content=”initial-scale=1, viewport-fit=cover”>

现在,如果设备能够理解,它将使用内容区域(安全区域)的完整显示布局。

然后,您可以使用constant()iOS 11.0-11.2和env()iOS版本高于11.2。

padding-top:env(safe-area-inset-top);

CSS环境预定义变量名称是:

  • safe-area-inset-top
  • safe-area-inset-right
  • safe-area-inset-bottom
  • safe-area-inset-left

您可以在内部constant()env()功能中使用它们。

您可以在互联网上的许多来源找到适用于env()任何地方的var()工作,但事实并非如此。根据经验,有时它不会在里面工作calc()。在这种情况下,请使用自定义CSS属性(CSS本机变量)。

例如:

//这不行 
.selector {
  height: calc(100% + (env(safe-area-inset-top) + env(safe-area-inset-bottom)));
}

//这会奏效 
.selector {
  --safe-area-inset-top: env(safe-area-inset-top);
  --safe-area-inset-bottom: env(safe-area-inset-bottom);
  height: calc(100% + (var(--safe-area-inset-top) + var(--safe-area-inset-bottom)));
}

env()在较旧的设备上使用会产生一些BUG,因为较旧的浏览器不知道如何理解env()。要支持旧设备,您可以使用回退属性值


例如:


//较旧的浏览器(现在支持CSS环境变量)。
.selector { 
  height:100%; 
}
//部分支持CSS环境变量的浏览器(iOS 11.0-11.2)。
@supports (padding-top: constant(safe-area-inset-top)) {
  .selector {
    --safe-area-inset-top: constant(safe-area-inset-top);
    height: calc(100% + var(--safe-area-inset-top));
  }
}

//完全支持CSS环境变量的浏览器(iOS 11.2+)。
@supports (padding-top: env(safe-area-inset-top)) {
  .selector {
    --safe-area-inset-top: env(safe-area-inset-top);
    height: calc(100% + var(--safe-area-inset-top));
  }
}

这里提供一个iphonex的适配css文件,可以参考root根源,来应用到你的项目中,兼容不同iphone手机,向上向下兼容



safe-area.css



:root {
  /* no safe area */
  --safe-area-inset-top: 0px;
  --safe-area-inset-bottom: 0px;
  --safe-area-inset-left: 0px;
  --safe-area-inset-right: 0px;
}

/* ios11.2 before */
@supports (bottom: constant(safe-area-inset-bottom)) {
  :root {
    --safe-area-inset-top: constant(safe-area-inset-top);
    --safe-area-inset-bottom: constant(safe-area-inset-bottom);
    --safe-area-inset-left: constant(safe-area-inset-left);
    --safe-area-inset-right: constant(safe-area-inset-right);
  }
}

/* ios11.2 later */
@supports (bottom: env(safe-area-inset-bottom)) {
  :root {
    --safe-area-inset-top: env(safe-area-inset-top);
    --safe-area-inset-bottom: env(safe-area-inset-bottom);
    --safe-area-inset-left: env(safe-area-inset-left);
    --safe-area-inset-right: env(safe-area-inset-right);
  }
}

/* not support safe-area constants */
@supports not ((bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom))) {
  /* iphoneX */
  @media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) {
    
    :root {
      --safe-area-inset-top: 44px;
      --safe-area-inset-bottom: 34px;
      --safe-area-inset-left: 0;
      --safe-area-inset-right: 0;
    }
  }

  /* iphoneX landscape mode */
  @media only screen and (device-width: 812px) and (device-height: 375px) and (-webkit-device-pixel-ratio: 3) {
    :root {
      --safe-area-inset-top: 0;
      --safe-area-inset-bottom: 21px;
      --safe-area-inset-left: 44px;
      --safe-area-inset-right: 44px;
    }
  }       
}