--- title: "HTML schema reference" description: "The current contract for a HyperFrames composition." --- HyperFrames uses normal HTML and CSS for appearance. A small set of attributes declares the frame size, duration, clips, media, and nested compositions. For a gentler explanation, start with [Compositions](/concepts/compositions) and [Data attributes](/concepts/data-attributes). ## Minimal composition ```html

Hello HyperFrames

``` The root is a real, explicitly sized box. Its `data-composition-id` matches the timeline registry key. ## Composition root | Attribute | Required | Meaning | | --- | --- | --- | | `data-composition-id` | Yes | Unique composition ID | | `data-start="0"` | Yes on the top-level root | Start of the composition | | `data-width` and `data-height` | Yes | Authored frame dimensions in pixels | | `data-duration` | Usually | Total render duration in seconds | | `data-no-timeline` | Only for a timeline-free composition | Tells the runtime not to wait for a timeline | An explicit root `data-duration` is the render length. The compiler reads it before composition scripts run, so a script or variable override cannot change that value for the same render. The root may omit `data-duration` only when HyperFrames can infer a finite duration from the registered animation runtime or timed media. Three.js, unbounded animation, and timeline-free compositions need an explicit duration. ## Timed clips | Attribute | Required | Meaning | | --- | --- | --- | | `id` | Yes | Stable identifier for timing, editing, and animation | | `data-start` | Yes | Start in seconds or a relative timing expression | | `data-duration` | Yes for DOM, image, and nested-composition clips | Visible slot length in seconds | | `data-track-index` | Yes | Timeline lane used to prevent temporal overlap | | `class="clip"` | Yes for authored timed DOM and image elements | Lets the runtime own their visibility window | `data-track-index` does not control paint order. Use CSS `z-index` for front-to-back layering. Two clips on the same track must not overlap in time. Video visibility is managed as media and does not require `class="clip"`. Audio has no visual lifecycle. ## Media ```html ``` | Attribute | Applies to | Meaning | | --- | --- | --- | | `data-media-start` | Video and audio | Offset into the source file | | `data-playback-start` | Video, audio, nested composition | Source-time offset used by trim and split operations | | `data-playback-rate` | Video, audio, nested composition | Playback multiplier from `0.1` to `5` | | `data-volume` | Video and audio | Static volume from `0` to `1` | | `data-has-audio="true"` | Video | Declares that the video contributes audio | Video and audio may omit `data-duration` when their intrinsic duration is known and the whole remaining source should play. Do not imperatively call `play()`, `pause()`, or set `currentTime`. HyperFrames owns media playback and seeking. A video should be `muted` unless it is intentionally audible and declares `data-has-audio="true"`. Media can live inside nested composition markup. Keep element IDs unique across the assembled project because render-time frame injection targets those IDs. ## Color grading and media effects Studio and the CLI store color correction, grading, finishing controls, LUTs, and media effects on an image or video with `data-color-grading`: ```html ``` The current effect families include essentials, retro and glitch, print, and art treatments. Run `npx hyperframes media-treatment --capabilities --json` for the current machine-readable surface instead of hard-coding an old effect list. The grading pipeline applies to real `` and `