[4] safe-area问题

393 阅读2分钟

目录

1.背景

在iPhoneX发布后,许多厂商相继推出了具有边缘屏幕的手机。

image.png 首先,safe-area只针对iOS系统。

在iPhone X横空出世之后,带来了两个创新性的设计,即:上面的刘海屏,下面的小黑条

这两个区域,我们在做页面开发时,是要留出来的,不然会存在dom元素被挡住导致展示不全的情况。因此iOS 11引入了safe-area这一概念,让开发者可以绕开这两个区域。

2.iOS 11 为 Safe Area 提供了哪些前端可用的工具来适配页面

【1】新的 viewport 属性

viewport-fit包含三个属性:

auto:

contain: 可视窗口完全包含网页内容

cover:网页内容完全覆盖可视窗口。开启全屏模式。

我们如何做?

设置为iewport-fit=cover" 开启全屏模式,例如你app是黄色,你就可以改变这颜色了。否则app在上下方补上黑色,形成矩形屏幕效果。

【2】新增CSS 函数-env、constant

我们需要将顶部和底部合理的摆放在安全区域内,iOS11新增了两个CSS函数env、constant,用于设定安全区域与边界的距离。

函数内部可以是四个常量:

  • safe-area-inset-left:安全区域距离左边边界距离
  • safe-area-inset-right:安全区域距离右边边界距离
  • safe-area-inset-top:安全区域距离顶部边界距离
  • safe-area-inset-bottom:安全区域距离底部边界距离 -到小黑线的距离

注意:我们必须指定viweport-fit后才能使用这两个函数:

<meta name="viewport" content="viewport-fit=cover">

constant在iOS < 11.2的版本中生效,

env在iOS >= 11.2的版本中生效,这意味着我们往往要同时设置他们,将页面限制在安全区域内:

body {
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

当使用底部固定导航栏时,我们要为他们设置padding值:

{
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

3. 回归我们如何做的

3.1 判断环境

首先,我们得判断是Android还是iOS,因为只有iOS下需要处理safe-area。

具体判断代码随意,最终要添加到.android或者.ios的class到html上,以便于后续mixin处理。

参考我们流传下来的代码:

image.png

3.2 safe-area在css中如何获取

// _safe-area.scss

@mixin safe-area-value($prop: 'padding-top', $direction: 'top', $optional: '0rem') {
  & {
    #{$prop}: $optional;
  }
  .ios[data-dpr="1"] & {
    #{$prop}: calc(constant(safe-area-inset-#{$direction}) + #{$optional});
    #{$prop}: calc(env(safe-area-inset-#{$direction}) + #{$optional});
  }
  .ios[data-dpr="2"] & {
    #{$prop}: calc((constant(safe-area-inset-#{$direction}) * 2) + #{$optional});
    #{$prop}: calc((env(safe-area-inset-#{$direction}) * 2) + #{$optional});
  }
  .ios[data-dpr="3"] & {
    #{$prop}: calc((constant(safe-area-inset-#{$direction}) * 3) + #{$optional});
    #{$prop}: calc((env(safe-area-inset-#{$direction}) * 3) + #{$optional});
  }
}

使用;

一般都用padding-bottom去解决

特殊的情况需要改变盒模型

@import '~@modules/scss/safe-area';
.buy-submit {
        position: fixed;
   			left: 0;
        bottom: 0;
  
        width: 100%;  // 删除了的
        width: calc(100% - .3rem - .24rem); // 新加的。
        height: 1.2rem;
  
        padding-left: .3rem;
        padding-right: .24rem;
        background: #fff;
        box-shadow: 0 -1px 0 0 #E5E5E5;
      
        display: flex;
        align-items: center;
        justify-content: space-between;
      
        box-sizing: content-box;   // 新加的
        @include safe-area-bottom-value('padding-bottom', 'bottom'); // 新加的  // padding-top= constant() top的距离+.88rem 。因为你设置了cover。全屏幕模式
        }