跳到主要内容

back

概述

back 是 WebSpatial 在现有 Web 标准基础上新增的 CSS 属性,提供最基本的在 3D 空间中布局的能力,可以让 HTML 元素作为 2D 面片被「抬升」到网页平面前方的空间中。

适用对象

通过 WebSpatial SDK 在一个 HTML 元素上使用 back 的时候,需要这个元素被标记为空间化 HTML 元素

3D 容器元素<Model><Reality>)都是空间化 HTML 元素,所以也能作为一个 2D 面片(相当于 3D 容器的背板)使用这个属性。

只适用于设置了 position: relativeposition: absoluteposition: fixedpositioned element

心智模型

top, left, bottom, right 一样属于 inset 属性,但影响的不是 HTML 元素在 X/Y 轴上的位置,而是元素在 Z 轴上的位置,相当于让元素沿着垂直于网页平面的 Z 轴方向,在网页平面前方的 3D 空间中定位,作为一个 2D 面片悬浮在空间中。

这个 2D 面片「抬升」后,在空间中 X/Y 轴上的位置,仍然由网页的 HTML/CSS 布局系统决定。

back 表示的是这个 2D 面片跟「背后」之间的距离。这个「背后」对应的是哪个 2D 平面,由 position 的值决定:

backposition: absolute 组合使用时,可以理解为让当前元素相对于父层级中最近的空间化 HTML 元素对应的 2D 平面进行定位,如果父层级中没有空间化 HTML 元素,就会相对于当前网页对应的 2D 平面进行定位。 等价于让当前元素相对于元素原本所在的 2D 平面进行定位。

为什么这仍然符合现有 Web 标准

在 Web 标准中,inset 属性在跟 position: absoluteposition: fixed 组合使用时,元素是相对于父层级中距离最近的 containing block(可理解为 position 值不是 static 的元素)进行定位。

一个 HTML 元素被标记为空间化 HTML 元素后,就自动成为了 containing block,相当于被设置为 position: relative

如果当前元素和父层级中最近的空间化 HTML 元素之间还有其他 position: relative 的父元素,由于这个父元素不是空间化 HTML 元素,不能「浮起」,所以一定位于父层级中最近的空间化 HTML 元素对应的 2D 平面上,back 的最终结果都是相对于这个 2D 平面进行定位。

backposition: fixed 组合使用时,当前元素始终相对于 initial containing block (也就是 <html> 元素,相当于当前网页对应的 2D 平面)进行定位,并且不会随页面滚动。

backposition: relative 组合使用时,可以理解为让当前元素相对于元素原本所在的 2D 平面进行定位。

语法

标准化完成前的临时 CSS 命名

WebSpatial API 中的 CSS 属性在标准化完成前,需要加上 -xr- 前缀。 在 WebSpatial SDK 当前的实现中,出于性能考虑,是用 CSS 自定义变量来实现新的 CSS API,因此 back 的属性名在 CSS 样式和 style 属性里都要写成 --xr-back

示例:

p {
position: absolute;
left: 0;
right: 0;
--xr-back: 20px;
}
.product-detail-info {
border-radius: 50px;
padding: 50px;
position: fixed;
top: 0;
right: 0;
bottom: 0;
--xr-back: 20px;
margin: auto;
width: 400px;
}
.link-card {
position: relative;
--xr-back: 50px;
}
export default function Demo() {
return (
<div
style={{
"--xr-back": "50px",
left: "0",
}}></div>
);
}

值语法

在 WebSpatial SDK 当前的实现中,back 的值只支持用 px 作为单位,等价于 2D GUI 使用的 point 单位(参考单位转换 API)。

以下写法都是 px 单位:

--xr-back: 20px;
--xr-back: 20;

对于数值,最多允许精确到小数点后一位:

--xr-back: 1px;
--xr-back: 0.5px;

初始值

初始值相当于:

--xr-back: 0;

是否继承

子元素不会继承父元素的 back 属性。

但是在跟 position: relativeposition: absolute 组合使用时,父元素中的空间化 HTML 元素因为 back 属性发生了 Z 轴方向上的位移,子元素(包括空间化 HTML 元素)也会有相应的位移(因为子元素是相对于父元素定位的)。

是否可动画化

在 WebSpatial SDK 当前的实现中,暂时不支持在 CSS 动画中使用 back 属性。

当前限制

空间化 HTML 元素整体目前都不支持 CSS 动画。

back 支持 JS 动画的实现方式,可以对一个元素用 JS 反复修改 style 属性里 --xr-back 的值。

JSX API 示例:

export default function Demo({ animatedOffsetZ, animatedOffsetX }) {
return (
<div
style={{
"--xr-back": animatedOffsetZ,
left: animatedOffsetX,
}}></div>
);
}

DOM API 示例:

ref.current.style["--xr-back"] = animatedOffsetZ;

与其他 CSS API 的交互

back 是布局属性,用 back 让元素「浮起」,相当于改变元素在 Z 轴上的布局位置。CSS Transform 是相对于这个布局位置进一步改变这个元素的显示效果(不影响实际布局位置)。

back 能跟 top, left, bottom, right 组合使用,改变元素对应的 2D 面片在 3D 空间中 X、Y、Z 轴上的布局位置。

DOM 与 JS 映射

back 让元素「浮起」后,可以用 DOM API 里新增的 offsetBack 属性读取这个元素相对于原本所在 2D 平面「浮起」的距离。

在 2D HTML 元素上触发空间交互事件 SpatialTapEventSpatialDragStartEvent 获取到的相对于全局坐标系的交互位置信息(clientZ)也由 back 决定。

还可以获得一个元素的 ref 后,直接读写 styleback 属性的值:

const currentOffsetZ = ref.current.style["--xr-back"];

回退行为

在不支持 WebSpatial 的环境里,back 会被自动忽略。