← Learn

Scroll Semantics for 3D Sites: Rails, Detents, and Scroll Grammars

Software 4 Senses LLC · Last updated

A 3D website does not need a new input model. The approach described here keeps the visitor's familiar one-dimensional scroll gesture and maps it, through a single scalar called the rail cursor, onto authored camera and world motion — with snap detents for section structure, a small catalog of named "scroll grammars" for what forward motion means, and build-time vestibular safety checks. The reference implementation is the Software 4 Senses 3D Spatial Web Studio ("the Studio" below).

Scroll here is a 2D input grammar driving a 3D document: rails bind the camera and the world-side elements of the Scene Document Model — pure 3D elements with document structure, among them the distance-field text and image planes the visitor reads. "World-moves" grammars are document elements traveling past a still camera.

Rails, not WASD

"Rails, not WASD" means the visitor never pilots the camera: they keep the one-dimensional scroll input they already have, and the site translates it into bounded, choreographed motion. Scroll stays scroll and click stays click; what changes is what the world does in response.

Rails, not WASD — the input philosophy of a 3D Spatial Web Interface: the visitor emits simple one-dimensional intents, and the site translates them into authored, bounded camera and world motion. The camera is on rails, and the rails are the design — spatial richness lives in the choreography, not in free movement.

Free piloting fails general audiences for a structural reason: WASD-plus-mouselook is a trained skill, and a website's audience arrives with reading reflexes, not piloting ones. The moment a visitor can steer freely, "lost", "stuck", "facing the wrong way", and "motion sick" all become reachable states, and content becomes missable. The Studio's design contract makes the alternative checkable as guardrail G1: one-dimensional input must suffice to reach every piece of content. A second stance follows: world-moves by default, camera-moves for meaningful navigation — within a section content flows past a nearly still camera; between sections the camera makes one deliberate, eased move.

One scalar to rule the stage

Every camera pose and every bound world translation on a stage — one continuous camera-space experience, the spatial equivalent of a page — is a pure function of one scalar: the rail cursor s, measured in rail units (approximately CSS pixels of wheel travel). A rail is a piecewise sequence of spans laid end to end along that axis — camera spans carry an arc-length-sampled pose track (the visitor travels), while world spans bind group translations (content travels past a fixed camera). The path model has no engine, DOM, or time dependency, which makes the whole scroll system deterministic and unit-testable: give it an s, get back the exact pose.

Between the input device and that pure function sits a six-mode dynamics machine — idle, tracking, coasting, settling, gliding, suspended. The modes encode a deliberate asymmetry between self-driven and autonomous motion:

Autonomous glides are additionally driven, when available, by a real Web Animations API animation on one leased CSS custom property — the rail cursor itself — so easing is closed-form and time-parameterized: every sampled value sits exactly on the curve regardless of frame jitter. The interruption contract holds throughout: input wins immediately, from the live value — same-direction input steals control back to tracking, opposing input reverses the transition natively.

Detents and snap

A detent is a named snap point on the rail — the anchor of one section — and each one declares one of three snap modes. Soft detents capture a coast whose projected stop lands inside their basin (the default capture fraction of 0.5 tiles the whole gap between neighbors, so a soft rail always comes to rest on a detent). Hard detents always complete the settle to the nearest detent, whatever the distance — elevator floors, where parking between floors is not a legal state. None marks a labeled free span where reading can idle anywhere.

Detent — a named snap point on a scroll rail, the 3D equivalent of a section anchor. Snap modes are soft (basin capture), hard (always settle to the nearest detent), and none (free span); detent ids are stable addresses, designed to double as URL anchors.

Release behavior is directional, not merely nearest-neighbor. Displacement from the last settled detent past a commit fraction of the gap — 12% by default — commits the release forward to the neighbor rather than tugging the visitor back into the basin they left. That threshold began at 20% and was tuned down to 12% in user feel-testing (): a slow, deliberate scroll should not have to fight the basin it is leaving. Two companion heuristics round out the feel: wheels emit no release event, so a short input-silence window (50 ms by default) stands in for "gesture ended", and a release faster than a flick-skip threshold (2,500 rail units/s by default) targets one detent past the natural stopping point — one hard flick, one section skipped.

Input devices are normalized before any of this runs. Discrete mouse wheels report large, quantized pixel deltas (the ±120-per-notch family), while trackpads stream small fractional deltas at high rate; the rail input layer maps each detected notch to a fixed 100 rail units, so a notched mouse and a trackpad traverse a rail comparably instead of the notched mouse arriving everywhere first.

Every number in this section — the 0.12 commit fraction, friction 4/s, the 0.5 capture fraction, 100 rail units per notch, the 50 ms silence window, the 2,500 units/s flick threshold — is a designed, feel-tested default in the Studio's rail layer, overridable per rail. None of them is a performance measurement or a benchmark result.

The eight scroll grammars

A scroll grammar is a named answer to the question "what does scrolling mean here?" — chosen per rail span, and allowed to change at section boundaries. Scroll on the 2D web quietly conflates three roles: advancing through content, sensing position, and pacing. Each grammar answers all three with a different spatial metaphor, and because position along the rail is visible in the world itself, every grammar gets a diegetic progress read — you can see how much is left.

Scroll grammar — a named genre of forward motion that a rail span adopts, defining what the one-dimensional scroll gesture does to the camera and the world on that span. The Studio's design catalog names eight.

IDGrammarWhat scrolling meansStatus
S1ConveyorThe world flows past a fixed camera — the comfort default for content flows.Shipped choreography (working scene, including departure choreography).
S2Dolly RailThe camera travels a corridor of content.Mechanics shipped — camera rail spans implement dolly movement; no dedicated showcase scene.
S3ElevatorSections are floors; scroll moves the cab vertically, hard-snapping to floors.Mechanics shipped — hard detents settle a vertical camera span onto its floors.
S4TurntableScroll rotates a radial hub of content around the viewer's position.Named design taxonomy.
S5Focus PullScroll moves the focal plane through a z-stack of content.Named design taxonomy.
S6Page Turn / FoldScroll folds or turns content like leaves of a physical document.Named design taxonomy.
S7Semantic ZoomScroll changes scale of attention — a "Powers of Ten" descent through detail levels.Named design taxonomy; explicitly a v2 candidate.
S8Orbit VignettesScroll advances between vignettes, each allowing a bounded ±30° orbit.Named design taxonomy.

The status column is the honest part of the table. The taxonomy of eight is published design vocabulary; what ships today as working choreography is the Conveyor, with elevator mechanics (hard detents on a vertical camera span) and dolly mechanics (camera spans) present in the rail layer. The remaining five are the named roadmap — useful now precisely because naming a grammar is how a span declares its intent.

Vestibular safety as lintable code

Comfort in this model is not a review checklist — the properties that protect the visitor's inner ear are structural, or are validated when the rail is built, not discovered when a visitor gets dizzy.

The division of labor matters: the roll-free up vector, the pitch cap, the angular-rate guard, and the reduced-motion collapse are shipped code in the Studio's rail layer; the broader ten-guardrail comfort contract they come from is a published design contract the code progressively absorbs. A comfort rule a build step can reject is worth ten a style guide can only recommend.

Related reading