1# 网页中安全区域计算和避让适配
2
3## 概述
4安全区域定义为页面的显示区域,其默认不与系统设置的非安全区域(如状态栏、导航栏)重叠,以确保开发者设计的界面均布局于安全区域内。然而,当Web组件启用沉浸式模式时,网页元素可能会出现与状态栏或导航栏重叠的问题。具体示例如图1所示,红色虚线框划定的区域即为安全区域,而顶部状态栏、屏幕挖孔区域和底部导航条则被界定为非安全区域,Web组件开启沉浸式效果时,网页内底部元素与导航条发生重叠。
5
6**图1** Web组件开启沉浸式效果时网页内底部元素与导航条发生重叠
7
8![web-safe-area](figures/arkweb_safearea2.png)
9
10Web组件提供了利用W3C CSS进行安全区域计算并避让适配的能力,用来支持异形屏幕设备在沉浸式效果下页面的正常显示,网页开发者可以使用该能力对重叠元素进行避让。ArkWeb内核将持续监测Web组件及系统安全区域的位置与尺寸,依据两者的重叠部分,计算出当前Web组件的安全区域,以及在各个方向上所需避让的具体距离。
11
12## 实现场景
13
14### 开启Web组件沉浸式效果
15
16开发者可以通过[expandSafeArea](../reference/apis-arkui/arkui-ts/ts-universal-attributes-expand-safe-area.md)来开启沉浸式效果。
17
18  ```ts
19  // xxx.ets
20  import { webview } from '@kit.ArkWeb';
21
22  @Entry
23  @Component
24  struct WebComponent {
25    controller: webview.WebviewController = new webview.WebviewController();
26
27    build() {
28      Column() {
29        Web({ src: 'www.example.com', controller: this.controller })
30          .width('100%').height('100%')
31          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
32      }
33    }
34  }
35  ```
36
37### 设置网页在可视窗口中的布局方式
38
39`viewport-fit`用于限制网页在安全区域内的展示形态。默认为`auto`,与`contain`表现一致,表示可视窗口完全包含网页内容,即网页全部内容展示于安全区域内。而`cover`则表示网页内容完全覆盖可视窗口,即网页内容不仅展示于安全区域,还包含非安全区域,即可能与状态栏和导航栏发生重叠,只有这种场景下网页需要进行避让适配,设置方式如下:
40
41```
42<meta name='viewport' content='viewport-fit=cover'>
43```
44### 对网页元素进行避让
45
46网页元素的避让适配主要依赖于`env()` CSS函数,该函数用于在CSS中插入由用户代码定义的变量。这使得开发人员能够将内容置于可视窗口(viewport)的安全区域内。在规范中定义的`safe-area-inset-*`值,确保了即使在非矩形视区中,内容也能得到完全显示。其语法如下:
47```
48/* safe-area-inset-*可设置上、右、下、左,四个方向上的避让值 */
49env(safe-area-inset-top);
50env(safe-area-inset-right);
51env(safe-area-inset-bottom);
52env(safe-area-inset-left);
53
54/* 基于fallback,使用safe-area-inset-*设置四个方向上的避让值 */
55/* 下述长度单位参见:https://developer.mozilla.org/zh-CN/docs/Web/CSS/length */
56env(safe-area-inset-top, 20px);
57env(safe-area-inset-right, 1em);
58env(safe-area-inset-bottom, 0.5vh);
59env(safe-area-inset-left, 1.4rem);
60```
61
62>  **说明:**
63>
64> `safe-area-inset-*`由四个环境变量组成,分别定义了可视窗口边缘内矩形的`top`、`right`、`bottom`和`left`,确保内容可以安全地放置,避免被非矩形显示区域切断。在矩形视口(如普通2in1设备的显示器)中,这些值等于零。而对于非矩形显示器(例如圆形表盘、移动设备屏幕等),所有内容都将在用户代理设定的四个值所形成的矩形区域内可见。
65
66不同于其他的CSS属性,用户代理定义的属性名字对大小写敏感。同时,需要注意`env()`必须配合`viewport-fit=cover`使用。
67
68对于一些购物网站,首页网页底部为Tab形式的绝对布局元素,在沉浸式状态下这些绝对布局元素就需要进行底部避让,以防止绝对布局元素与系统导航条发生重叠遮挡,避让效果见图2:
69```
70.tab-bottom {
71    padding-bottom: env(safe-area-inset-bottom);
72}
73```
74同时,上述`env()`使用还能基于部分数学计算函数`calc()`,`min()`,`max()`组合计算,如:
75```
76.tab-bottom {
77    padding-bottom: max(env(safe-area-inset-bottom), 30px);
78}
79```
80
81**图2** Web组件开启沉浸式效果时网页内底部元素避让导航条区域
82
83![web-safe-area](figures/arkweb_safearea1.png)
84