Depth layers

Add depth to a .gravity-spot and its rings stack on the z axis. The layer in front is the one people read and use; the others wait behind it.

Each direct child of the .depth element is a layer: a ring, or a nested .gravity-spot when a layer needs several rings of its own.

  • data-depth="1" moves a layer one step back. Values go from 0 to 8.
  • .layer-front marks the active layer and places it at depth 0.
  • --o-z sets the position directly, in unitless pixels. Negative values are farther away.

Layers keep their apparent size: the scale makes up for the perspective, (perspective − z) / perspective. So three rings on orbit-6 would sit exactly on top of each other. --o-depth-grow makes each step back a bit bigger, so you can see them all. Depth changes animate.

A whole system as a layer

A layer can hold several rings, a label and a face that move together. Make it a nested .gravity-spot with data-depth. It has the same reach as its parent, so it needs no --o-force, and it does not block the pointer outside its satellites.

Below, three gauges are stacked that way. Click a face to bring it forward, and move the pointer over the frame to tilt the stack.

Perspective from an ancestor

By default the .depth element owns the perspective. To tilt the whole object, as above, an ancestor has to own it instead: add outer-perspective next to depth, give the ancestor a perspective, and set --o-perspective to the same number so layers still keep their apparent size. Elements between that ancestor and .depth need transform-style: preserve-3d; a .bigbang that holds the .depth element gets it automatically.

<div style="perspective: 1000px">
  <div class="bigbang">
    <div class="gravity-spot depth outer-perspective" style="--o-perspective: 1000">
      <div class="gravity-spot layer-front" data-depth="0">…</div>
      <div class="gravity-spot" data-depth="1">…</div>
    </div>
  </div>
</div>

Properties

Set these on the .depth element, or on a single layer.

PropertyDefaultWhat it does
--o-zdepth × stepPosition on the z axis in unitless pixels. Set it on a layer to override data-depth.
--o-depth-step-110Distance between depth steps.
--o-perspective900Perspective in unitless pixels.
--o-depth-grow0Extra size per step back. .42 gives 1×, 1.42×, 1.84×, so no two layers share a radius.
--o-depth-compensate10 lets farther layers look smaller.
--o-back-opacity1Opacity of the layers behind the front one.
--o-depth-duration.8sDuration of the depth transition.
--o-depth-easingcubic-bezier(.2,.8,.2,1)Easing of the depth transition.

The transition is off when the user prefers reduced motion.

Rules

  • Layers are direct children of .depth. An element in between flattens the 3D context.
  • Rings outside .depth are not transformed. data-depth alone does nothing.
  • Satellites, vectors, sides, <o-arc> and <o-progress> are never layers. They keep their own transforms; put them in a ring and move the ring.
  • Back layers still receive clicks. Rings ignore the pointer and satellites accept it, so a click on a satellite of a back layer reaches it. That is how the faces above come forward.

The depth demo has the gauges above at full size, and layered status rings a fuller example with alerts.