OTTODesign System

Components

Cinema

The cinema provides a way to display multiple items in a horizontal slide.

Configurator

LiveCinema: resizing, spacing, items per page and controls
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes Zustellung
HTML
<oc-cinema-v1 oc-aria-label="Wohnideen" cut="0.25" gap="8px" stage-spacing="0px" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1>

Usage

Anatomy

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben 12345
  1. Item
  2. Stage spacing (16px)
  3. Gap between items (16px)
  4. Scroll button, next item cut
  5. Pagination dots (optional)
LiveAnatomy
HTML
<div class="anatomy" style="display:block;margin:28px 0">
<oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1>
<span class="anatomy-pin" style="left:20%;top:45%">1</span><span class="anatomy-pin" style="left:0%;top:10%">2</span><span class="anatomy-pin" style="left:38.5%;top:10%">3</span><span class="anatomy-pin" style="left:97%;top:30%">4</span><span class="anatomy-pin" style="left:41%;top:95%">5</span>
<ol class="anatomy-key"><li data-n="1">Item</li><li data-n="2">Stage spacing (16px)</li><li data-n="3">Gap between items (16px)</li><li data-n="4">Scroll button, next item cut</li><li data-n="5">Pagination dots (optional)</li></ol>

Item set: An item set contains the number of items that can be displayed at once without cutting.

Item stage: All items of the cinema are stored in the item stage.

Pagination dots: Pagination dots show the amount of item-sets in the cinema. When tapping a pagination dot, the cinema will scroll into the corresponding view. Pagination dots are optional.

Behavior

States

The cinema has no own states, but uses the states of the scroll buttons, the content and the pagination dots.

Interaction

The items of the cinema navigate by tapping the scroll buttons or scrolling horizontally. The scroll buttons react to taps, they snap the next item set into the viewport. Horizontal scroll does not use snapping for navigating the items.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

Click the scroll button: the cinema moves by one page ↓

Livehorizontal scrolling by tapping a scroll button
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">Click the scroll button: the cinema moves by one page ↓</p></div>
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als StilllebenKopfhörerSitzecke auf dem OTTO Campus

Scroll horizontally (trackpad, swipe): items snap into place

Livehorizontal scrolling using mouse or trackpad with horizontal scroll feature or touch.
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/headphones-through-shapes.webp" alt="Kopfhörer" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-campus-social-space.webp" alt="Sitzecke auf dem OTTO Campus" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">Scroll horizontally (trackpad, swipe): items snap into place</p></div>

Infinite scrolling: The cinema does not support infinite scrolling. That means, whenever users get to the last item, there is no shortcut back to the first item.

Auto-forwarding: The cinema does not support auto-forwarding. This can lead to unease, create unnecessary feelings of urgency, and necessitate the provision of a pause option.

Placement

To position the cinema, use fill-parent with no spacing to the left or right. This ensures that items can scroll out of view without disappearing too early or too late. The gap between items, left-spacing of the first item and right-spacing of the last item are 16px by default, but may be adjusted.

fill-parent, 16px stage spacing and 16px gap (default)

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
Liveplacement
HTML
<p class="demo-label" style="text-align:center">fill-parent, 16px stage spacing and 16px gap (default)</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div></div>

Responsiveness

On mobile, the scroll buttons will be hidden automatically and the pagination dots represent the number of item sets in the cinema. On desktop the pagination dots of the cinema do not represent the number of items, but rather the number of item sets. An item set contains the number of items that can be displayed at once without cutting.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

default position (50%)

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

custom position (arrow-button-position="80%")

Liveresponsiveness
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">default position (50%)</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" arrow-button-position="80%"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">custom position (arrow-button-position="80%")</p></div>

The left scroll button is hidden at the start of the cinema. The right scroll button is hidden when you reach the end of the cinema.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als StilllebenKopfhörerSitzecke auf dem OTTO Campus

start: only the right scroll button; at the end only the left one remains

Livestart and end
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/headphones-through-shapes.webp" alt="Kopfhörer" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-campus-social-space.webp" alt="Sitzecke auf dem OTTO Campus" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">start: only the right scroll button; at the end only the left one remains</p></div>

By default, the vertical position of the scroll buttons is set to 50% of the height of the cinema. If needed, this can be customized.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

default position (50%)

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

custom position

Livescroll button position
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">default position (50%)</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots arrow-button-position="80%"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">custom position</p></div>

Resizing

If there are too few items to fill the viewport, the cinema automatically hides its controls.

There are three options of how the items inside a cinema can be resized: stretch, cut and stretch-cut.

If you want the items to fill the cinema space, you can set them to stretch. This only applies when there are so few items that the item stage wouldn't fill the viewport.

For the cut option, the items are arranged so that one item is always cut in the middle, unless it is the last item in the cinema. The original size acts as the minimum size, and 'cut' only increases the size of items.

Set the resizing to stretch-cut if you want both options - filling the available space and cutting off items if they overflow. This is highly recommended.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit Spielzeug

too few items: controls hidden (resizing="none")

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit Spielzeug

stretch

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben

cut

Liveresizing
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" resizing="none"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">too few items: controls hidden (resizing="none")</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" resizing="stretch"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">stretch</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" resizing="cut" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">cut</p></div>

Use the cinema to display multiple items at a time. Alternatively, you can use the carousel to display only one item at at time.

Best practices

Paket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als StilllebenKopfhörerSitzecke auf dem OTTO CampusWohnzimmer mit Sofa und StehlampeKinderzimmer mit Spielzeug
DoPlace within a layout with full-bleed.
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
Don'tPlace with additional outer spacing.
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
DoUse default left and right spacings.
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
Don'tUse custom left and right spacings.
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
DoPlace a cinema on canvas or frame.
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der Haustür
Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der Haustür
Don'tPlace cinemas within other cinemas - doubled horizontal scrolling does not work.

Accessibility

As of "WCAG 2.2 Success Criterion 2.5.8 Target Size", the hitbox of the pagination dots is 'undersized'. However, this is acceptable as there is an equivalent control (horizontal scrolling/scroll buttons) for this function.

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der Haustür

Each pagination dot has a hitbox of at least 16 × 16 px

Liveundersized hitbox of pagination dots
HTML
<div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div><p class="demo-label" style="text-align:center">Each pagination dot has a hitbox of at least 16 × 16 px</p></div>

When entering a cinema using keyboard navigation, a skip link is shown that offers an option to "Überspringen". If this should be made more specific, "oc-aria-label" may be used to change this skip link to "[label] überspringen".

If a cinema provides only few items, disable the automatic skip link.

Press Tab to move into the cinema: the skip link „Überspringen“ appears

Wohnzimmer mit Sofa und StehlampeKinderzimmer mit SpielzeugMojo Drop SweatshirtBücher im OTTO SortimentPaket vor der HaustürHermes ZustellungGeflochtene LampenSpielzeug als Stillleben
Liveskip link within cinema
HTML
<p class="demo-label" style="text-align:center">Press Tab to move into the cinema: the skip link „Überspringen“ appears</p><div style="background:#fff;padding:24px 0"><oc-cinema-v1 oc-aria-label="Wohnideen" pagination-dots><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="Wohnzimmer mit Sofa und Stehlampe" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="Kinderzimmer mit Spielzeug" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-fashion-drop-mojo-06.webp" alt="Mojo Drop Sweatshirt" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-buecher-sortiment.webp" alt="Bücher im OTTO Sortiment" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="Paket vor der Haustür" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/references/images/otto/otto-peak2025-hermes-zustellung.webp" alt="Hermes Zustellung" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="Geflochtene Lampen" width="296" height="197" loading="lazy" style="display:block;height:auto"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="Spielzeug als Stillleben" width="296" height="197" loading="lazy" style="display:block;height:auto"></oc-cinema-v1></div></div>

For information on accessibility, refer to the technical documentation.

Status

Implementation

Live demo

LiveReal OTTO components, rendered by the OTTO component runtime
HTML
<div>
<div style="background:#fff;padding:8px 0 16px">
<div style="display:flex;justify-content:space-between;align-items:baseline;padding:0 16px 16px"><p class="oc-headline-200" style="margin:0">Inspiration für dein Zuhause</p><oc-link-v2><a href="#">Alle anzeigen</a></oc-link-v2></div>
<oc-cinema-v1 oc-aria-label="Inspiration für dein Zuhause" pagination-dots>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-living-room.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Wohnzimmer</span><span class="oc-copy-75">Gemütlich einrichten mit Holz und Grün</span></a>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-kids-room.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Kinderzimmer</span><span class="oc-copy-75">Spielen, lernen, träumen</span></a>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-group-layered-photo/woven-lamps.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Leuchten</span><span class="oc-copy-75">Warmes Licht aus Rattan</span></a>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-lifestyle-photo/lifestyle-parcel-doorstep.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Lieferservice</span><span class="oc-copy-75">Bis in die Wohnung, auf Wunsch mit Aufbau</span></a>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-group-layered-photo/still-life-toy.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Spielzeug</span><span class="oc-copy-75">Holzspielzeug, das lange Freude macht</span></a>
  <a href="#" style="display:grid;gap:8px;width:260px;color:inherit;text-decoration:none"><img src="/previews/imagery/samples/otto-group-layered-photo/over-shoulder-laptop.webp" alt="" width="260" height="173" loading="lazy" style="display:block;width:100%;height:auto;border-radius:8px"><span class="oc-copy-100" style="font-weight:700">Homeoffice</span><span class="oc-copy-75">Alles für deinen Arbeitsplatz zu Hause</span></a>
</oc-cinema-v1>

Code

Version Tag Status API
v1 <oc-cinema-v1> Stable, allowed for generation CinemaV1

Overview (v1)

Cinema

The cinema component provides a way to display multiple items in a horizontal slide. This component is useful in cases where visual space is limited, and you want to present a series of related content (e.g., images or cards) that the user can navigate through.

Default variation
ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9 ITEM 10 ITEM 11 ITEM 12 ITEM 13 ITEM 14 ITEM 15 ITEM 16 ITEM 17 ITEM 18 ITEM 19 ITEM 20 ITEM 21 ITEM 22 ITEM 23 ITEM 24 ITEM 25 ITEM 26 ITEM 27 ITEM 28 ITEM 29 ITEM 30
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>
Configuration

The cinema component is configurable, allowing you to tailor its features and appearance to your specific needs. To explore all the available options and adjust the component, use the component configurator and see the changes affect the component in real-time.

Usage guidelines

Before integrating the cinema component into your project, make sure you have correctly installed the OTTO components package. Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.

Info

See the Cinema UX documentation for detailed user experience guidelines.

Accessibility

The cinema component comes with a set of built-in accessibility features to ensure a seamless experience for all users.

Provide an ARIA label

To make the cinema recognizable for screen readers, use the oc-aria-label attribute to provide clear and descriptive context information. See the general accessibility documentation for guidance on using oc-aria-label, including how it works with link and masked link behavior.

Alternatively, you can surround the component with a <section> (or role="region") element with an ARIA label.

<section aria-label="My cinema section">
  <oc-cinema>
    <!-- Cinema items here -->
  </oc-cinema>
</section>
Events

The cinema component provides events for checking the item visibility and the stage scroll state.

Item visibility changed

The oc-item-visibility-changed event triggers, whenever the stage is scrolled and new items enter the viewport. The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, the scroll direction of the cinema stage, whether it is currently scrolling or not and the source that triggered the scroll:

myCinema.addEventListener("oc-item-visibility-changed", (event) => {
  event.detail; // Returns: { { visibleItems: {elements: HTMLElement[]; indices: number[] }, scrollDirection: "left | right", stageIsScrolling: boolean, scrollSource: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});

For more information on tracking the visibility state of the component itself, see the visibility tracking documentation.

Stage scroll

The oc-stage-scroll event triggers when the stage is being scrolled. It returns the boolean isScrolling that reflects the current state as well as the source that initiated the scroll:

myCinema.addEventListener("oc-stage-scroll", (event) => {
  event.detail; // Returns: { isScrolling: boolean, source: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});
Stage scroll completed

The oc-stage-scroll-completed event triggers when the stage scroll has been completed. It returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, the scroll direction of the cinema stage and the source that triggered the scroll:

myCinema.addEventListener("oc-stage-scroll-completed", (event) => {
  event.detail; // Returns: { { visibleItems: {elements: HTMLElement[]; indices: number[] }, scrollDirection: "left | right", scrollSource: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});

Sources that initiate the scroll can be:

  • arrows - When the user interacts via the visual buttons.
  • pagination-dots - When the user interacts via the additional pagination-dots.
  • move-method - When the stage is being scrolled programmatically.
  • swipe - When the user interacts via swipe gestures on smartphones or laptop touchpads.

Configuration (v1)

Cinema configuration

Configure the cinema component with the controls below and see the changes live in the preview canvas. Click the Show code button within the preview canvas to see the source code for the current component configuration.

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9 ITEM 10 ITEM 11 ITEM 12 ITEM 13 ITEM 14 ITEM 15 ITEM 16 ITEM 17 ITEM 18 ITEM 19 ITEM 20 ITEM 21 ITEM 22 ITEM 23 ITEM 24 ITEM 25 ITEM 26 ITEM 27 ITEM 28 ITEM 29 ITEM 30
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>

Interactive configurator (Storybook controls); every option is listed in the API section of this file.

API v1

Cinema v1 API

API: <oc-cinema-v1> (CinemaV1)

The Cinema component provides a way to display multiple items in a horizontal slide. This component is useful in cases where visual space is limited, and you want to present a series of related content (e.g., images or cards) that the user can navigate through.

The Cinema component supports navigation through arrow buttons. The position of these buttons can be customized. It also supports ARIA labels for accessibility.

Attributes / properties
Attribute Type Default Required Description
resizing "none" | "stretch" | "cut" | "stretch-cut" "stretch-cut" no Specifies the resizing behavior of the items in the cinema. The resizing behavior determines - none Items are not resized. - stretch Items are stretched to fill the available space. - cut Items are cut off when they overflow. - stretch-cut Items are stretched to fill the available space, and cut off when they overflow.
cut string "0.5" no Sets the cut percentage of the items.

Used when the resizing property is set to cut or stretch-cut.
pagination-dots boolean false no Whether Pagination Dots should be visible. Pagination dots provide a visual indication of the number of items in the cinema, and which item is currently being viewed.
hide-skip-link boolean false no Hides the skip link that allows users to skip the carousel content. Set to true to hide the skip link.
items-per-page string no Sets the desired amount of items per page
gap string "16px" no Sets the gap between items.
stage-spacing string "16px" no Sets the spacing on the outer sides of the stage.
arrow-button-position string "50%" no Specifies the custom position of the arrow buttons. This can be any valid CSS value for the top property. The arrow buttons are used to navigate through the items in the cinema.
item-visibility-threshold number[] no The custom threshold used for tracking the visibility of the items
visible-items HTMLElement[] no The amount of current visible items.
oc-aria-label string no Sets the ARIA label of the cinema section. This label is used by screen readers to provide context to users with visual impairments. The label should describe the overall content or purpose of the cinema.

Providing an ARIA label can also be done by adding a surrounding <section> (or role="region") element with an ARIA label.
Slots
Slot Required Description
default yes Defines the main content of the cinema. This slot should contain a series of items (e.g., images or cards) that you want to present in a cinema format.
Events
Event Detail type Description
oc-item-visibility-changed CustomEvent<ScrollEventDetail> Scrolling the cinema triggers the oc-item-visibility-changed event. The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, and the scroll direction of the cinema stage
oc-stage-scroll CustomEvent<ScrollEventDetail> Scrolling the cinema triggers the oc-stage-scroll event. The event returns a boolean of the current state as well as the source that initiated the scroll.
oc-stage-scroll-completed CustomEvent<ScrollEventDetail> Dispatched after stage scroll initiated by user or programmatically has completed. Meaning there is no scrolling of the stage within a defined timeout. The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, and the scroll direction of the cinema stage. The event also returns the source that initiated the scroll.
oc-property-change OcCinemaV1Events["oc-property-change"] Whenever a property value changes, this event triggers. Use this event to track all property changes within the component.

Refer to the Events documentation for more information.
oc-mount { component: string; } Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime.
oc-unmount { component: string; } Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime.
Methods
  • moveTo: (index: number, options?: { source?: "arrows" | "pagination-dots" | undefined; reducedMotion?: boolean | undefined; } | undefined) => void

    Scrolls cinema elements to the specified page index. The index corresponds to the pages calculated based on the container width and item sizes.

    Parameters:

    • index: number - The index of the page that should be scrolled to.
    • options: { source?: "arrows" | "pagination-dots" | undefined; reducedMotion?: boolean | undefined; } | undefined - Optional scroll behavior settings.

    Returns: void

    Example:

    const cinema = document.querySelector("oc-cinema-v1");
    cinema.moveTo(2, { reducedMotion: true, source: "pagination-dots" });
    
CSS custom properties
Custom property Default Description
--arrow-button-position 50% Sets the position of the arrow buttons.
--cut 0.5 Sets the cut percentage of the items.

Used when the resizing property is set to cut or stretch-cut.
--gap 16px Sets the gap between items.
--items-per-page Sets the desired amount of items per page Works only when resizing-mode is set to stretch-cut or cut
--stage-spacing 16px Sets the spacing on the outer sides of the stage.

Variations (v1)

Variations

Listed below are the most common variations of the cinema component as well as specific component variations for different use cases.

You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.

Default

Story: components-cinema-variations--default · tags: components, cinema, v1

The default configuration with resizing set to stretch-cut.

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9 ITEM 10 ITEM 11 ITEM 12 ITEM 13 ITEM 14 ITEM 15 ITEM 16 ITEM 17 ITEM 18 ITEM 19 ITEM 20 ITEM 21 ITEM 22 ITEM 23 ITEM 24 ITEM 25 ITEM 26 ITEM 27 ITEM 28 ITEM 29 ITEM 30
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
      <oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>
3 Items

Story: components-cinema-variations--three-items · tags: components, cinema, v1

The configuration with 3 items. The resizing is set to none. The items are not resized.

Args: defaultSlot=(see snippet), resizing=none

ITEM 1 ITEM 2 ITEM 3
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="none">
<oc-placeholder-v1  style="width: 100px" interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1  style="width: 100px"   interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1   style="width: 100px"  interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
Stretch-Items

Story: components-cinema-variations--stretch-items · tags: components, cinema, v1

The configuration with 3 items. The resizing is set to stretch. The items are stretched to fill the available space.

Args: defaultSlot=(see snippet), resizing=stretch

ITEM 1 ITEM 2 ITEM 3
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="stretch">
<oc-placeholder-v1   interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
Different Item-Widths

Story: components-cinema-variations--different-item-widths · tags: components, cinema, v1

The configuration with items of different widths. The resizing is set to stretch.

Args: defaultSlot=(see snippet), resizing=stretch

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="stretch">
<oc-placeholder-v1  interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true"  style="width: 85%">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
Custom items per page

Story: components-cinema-variations--custom-items-per-page · tags: components, cinema, v1

The configuration with a set number of items per page.

Args: defaultSlot=(see snippet), items-per-page=7

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9
HTML
<oc-cinema-v1 oc-aria-label="cinema of placeholders" items-per-page="7">
<oc-placeholder-v1  interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1  interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
Demo: Custom stage spacing

Story: components-cinema-variations--demo-custom-stage-spacing · tags: components, cinema, v1

Demo showcasing on how stage-spacing can be customized.

<div style="border: 2px dashed lightgray; padding: 16px 0">
  <oc-cinema-v1>
    <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
    <oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
    <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
  </oc-cinema-v1>
</div>

<div style="display: flex; flex-direction: column; gap: 16px;  margin-top: 32px;">
  <div style="display: flex; gap: 16px; align-items: center;">
    <label for="stage-spacing-slider">Stage Spacing</label>
    <input
      type="range"
      name="stage-spacing-slider"
      id="stage-spacing-slider"
      min="0"
      max="64"
      value="16"
    />
    <span id="stage-spacing-slider-value">16px</span>
  </div>
</div>

<script>
  (() => {
    const cinema = document.querySelector("oc-cinema-v1");
    const stageSpacingSlider = document.getElementById("stage-spacing-slider");
    const stageSpacingSliderValue = document.getElementById("stage-spacing-slider-value");

    stageSpacingSlider.addEventListener("input", (event) => {
      const value = event.target.value + "px";
      cinema.style.setProperty("--stage-spacing", value);
      stageSpacingSliderValue.textContent = value;
    });
  })();
</script>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Custom stage spacing",
  argTypes: hideControlsBadge(Metadata),
  parameters: {
    chromatic: {
      hideInChromatic: true,
      disableSnapshot: true
    },
    controls: {
      disabled: true
    }
  },
  render: () => {
    return html`
      <div style="border: 2px dashed lightgray; padding: 16px 0">
        <oc-cinema-v1>
          <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
          <oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
          <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        </oc-cinema-v1>
      </div>

      <div style="display: flex; flex-direction: column; gap: 16px;  margin-top: 32px;">
        <div style="display: flex; gap: 16px; align-items: center;">
          <label for="stage-spacing-slider">Stage Spacing</label>
          <input
            type="range"
            name="stage-spacing-slider"
            id="stage-spacing-slider"
            min="0"
            max="64"
            value="16"
          />
          <span id="stage-spacing-slider-value">16px</span>
        </div>
      </div>

      <script>
        (() => {
          const cinema = document.querySelector("oc-cinema-v1");
          const stageSpacingSlider = document.getElementById("stage-spacing-slider");
          const stageSpacingSliderValue = document.getElementById("stage-spacing-slider-value");

          stageSpacingSlider.addEventListener("input", (event) => {
            const value = event.target.value + "px";
            cinema.style.setProperty("--stage-spacing", value);
            stageSpacingSliderValue.textContent = value;
          });
        })();
      </script>
    `;
  }
}
Demo: Move-Method

Story: components-cinema-variations--demo-move-method · tags: components, cinema, v1

Demo showcasing the movement of the stage programmatically.

Args: defaultSlot=(see snippet), pagination-dots=true

<!-- The component-->
<oc-cinema-v1 oc-aria-label="cinema of placeholders" pagination-dots><oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    </oc-cinema-v1>

<br />
<br />
<p>
  <oc-button-v1 size="50"> Move stage to page 5 </oc-button-v1>
  <br />
  <br />
  <textarea
    style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
    aria-label="example"
    disabled
  >
  const moveMyCinema = (myCinema) => {
    myCinema.moveTo(5);
  }
  </textarea>
</p>
<br />
<br />
<p>
  <oc-button-v1 size="50"> Move stage to page 5 (reduced motion)</oc-button-v1>
  <br />
  <br />
  <textarea
    style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
    aria-label="example"
    disabled
  >
  const moveMyCinema = (myCinema) => {
    myCinema.moveTo(5, { reducedMotion: true });
  }
  </textarea>
</p>

<script>
  (() => {
    const [moveStage, moveStageReducedMotion] = document.getElementsByTagName("oc-button-v1");

    moveStage.addEventListener("click", () => {
      document.querySelector("oc-cinema-v1").moveTo(5);
    });

    moveStageReducedMotion.addEventListener("click", () => {
      document.querySelector("oc-cinema-v1").moveTo(5, { reducedMotion: true });
    });
  })();
</script>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Move-Method",
  parameters: {
    chromatic: {
      hideInChromatic: true,
      disableSnapshot: true
    }
  },
  args: {
    defaultSlot: `<oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    <oc-placeholder-v1  variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
    `,
    "pagination-dots": true
  },
  render: ({
    defaultSlot,
    ...props
  }) => {
    return html`
      <!-- The component-->
      <oc-cinema-v1 ${spread(props)}>${unsafeHTML(defaultSlot)}</oc-cinema-v1>

      <br />
      <br />
      <p>
        <oc-button-v1 size="50"> Move stage to page 5 </oc-button-v1>
        <br />
        <br />
        <textarea
          style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
          aria-label="example"
          disabled
        >
        const moveMyCinema = (myCinema) => {
          myCinema.moveTo(5);
        }
        </textarea>
      </p>
      <br />
      <br />
      <p>
        <oc-button-v1 size="50"> Move stage to page 5 (reduced motion)</oc-button-v1>
        <br />
        <br />
        <textarea
          style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
          aria-label="example"
          disabled
        >
        const moveMyCinema = (myCinema) => {
          myCinema.moveTo(5, { reducedMotion: true });
        }
        </textarea>
      </p>

      <script>
        (() => {
          const [moveStage, moveStageReducedMotion] = document.getElementsByTagName("oc-button-v1");

          moveStage.addEventListener("click", () => {
            document.querySelector("oc-cinema-v1").moveTo(5);
          });

          moveStageReducedMotion.addEventListener("click", () => {
            document.querySelector("oc-cinema-v1").moveTo(5, { reducedMotion: true });
          });
        })();
      </script>
    `;
  }
}
Demo: Multiple Cinemas

Story: components-cinema-variations--demo-multiple-cinemas · tags: components, cinema, v1

The configuration with items of different widths. The resizing is set to stretch.

List of Cinemas

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9
ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9
ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9

This cinema element has special tracking attributes (starting with data-tr-v1), which configure the tracking engine to observe the element by utilizing the provided threshold values. The element will be tracked when it becomes visible by at least 50% (as configured). And then tracking engin will first emit an event tr-become-visible containing the tracking trigger. and then if the event is not canceled, it will submit the default tracking method submitMiniAction to the tracking library (bct).

you can make the submission visible in the console by enabling the tracking debug mode and providing a fake implementation (since bct is not enabled in storybook)


  otto.tracking.submitMiniAction.assignFunction(console.log);
  o_global.debug.activate("nexus.otto.tracking", "debug");
ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

ITEM 1 ITEM 2 ITEM 3 ITEM 4 ITEM 5 ITEM 6 ITEM 7 ITEM 8 ITEM 9

Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit, necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta. Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam placeat facilis facere quia doloribus.

HTML
<h1>List of Cinemas</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1
id="cinema-1"
pagination-dots
item-visibility-threshold="[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]"
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-2" pagination-dots item-visibility-threshold="[0.4, 0.8]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-3" pagination-dots item-visibility-threshold="[0.3, 0.6, 0.9]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-4" pagination-dots>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
This cinema element has special tracking attributes (starting with <code>data-tr-v1</code>),
which configure the tracking engine to observe the element by utilizing the provided
threshold values. The element will be tracked when it becomes visible by at least 50% (as
configured). And then tracking engin will first emit an event
<code>tr-become-visible</code> containing the tracking trigger. and then if the event is not
canceled, it will submit the default tracking method <code>submitMiniAction</code> to the
tracking library (bct).
</p>
<p>
you can make the submission visible in the console by enabling the tracking debug mode and
providing a fake implementation (since bct is not enabled in storybook)
</p>
<pre><code>
otto.tracking.submitMiniAction.assignFunction(console.log);
o_global.debug.activate("nexus.otto.tracking", "debug");
</code></pre>
<oc-cinema-v1
id="cinema-5"
pagination-dots
data-tr-v1
data-tr-v1-tr-become-visible.observer='{ "threshold": 0.5 }'
data-tr-v1-tr-become-visible.updates='[{ "featureId": "foo-barid", "status": "works" }]'
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-6" pagination-dots item-visibility-threshold="[0.5]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Multiple Cinemas",
  parameters: {
    controls: {
      disabled: true
    },
    chromatic: {
      hideInChromatic: true,
      disableSnapshot: true
    }
  },
  render: () => {
    return html`
      <h1>List of Cinemas</h1>

      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>

      <oc-cinema-v1
        id="cinema-1"
        pagination-dots
        item-visibility-threshold="[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]"
      >
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>
      <div style="margin-top: 32px"></div>
      <oc-cinema-v1 id="cinema-2" pagination-dots item-visibility-threshold="[0.4, 0.8]">
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>
      <div style="margin-top: 32px"></div>

      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>

      <oc-cinema-v1 id="cinema-3" pagination-dots item-visibility-threshold="[0.3, 0.6, 0.9]">
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>
      <div style="margin-top: 32px"></div>
      <oc-cinema-v1 id="cinema-4" pagination-dots>
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>
      <p>
        This cinema element has special tracking attributes (starting with <code>data-tr-v1</code>),
        which configure the tracking engine to observe the element by utilizing the provided
        threshold values. The element will be tracked when it becomes visible by at least 50% (as
        configured). And then tracking engin will first emit an event
        <code>tr-become-visible</code> containing the tracking trigger. and then if the event is not
        canceled, it will submit the default tracking method <code>submitMiniAction</code> to the
        tracking library (bct).
      </p>
      <p>
        you can make the submission visible in the console by enabling the tracking debug mode and
        providing a fake implementation (since bct is not enabled in storybook)
      </p>
      <pre><code>
        otto.tracking.submitMiniAction.assignFunction(console.log);
        o_global.debug.activate("nexus.otto.tracking", "debug");
      </code></pre>
      <oc-cinema-v1
        id="cinema-5"
        pagination-dots
        data-tr-v1
        data-tr-v1-tr-become-visible.observer='{ "threshold": 0.5 }'
        data-tr-v1-tr-become-visible.updates='[{ "featureId": "foo-barid", "status": "works" }]'
      >
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>

      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
      <oc-cinema-v1 id="cinema-6" pagination-dots item-visibility-threshold="[0.5]">
        <oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
        <oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
      </oc-cinema-v1>

      <p>
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
        maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
        repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
        laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
        itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
        optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
        necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
        exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
        dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
        atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
        maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
        eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
        laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
        Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
        reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
        dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
        qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
        placeat facilis facere quia doloribus.
      </p>
    `;
  }
}
Demo: Device Type Detection

Story: components-cinema-variations--demo-device-type-detection · tags: components, cinema, v1

Demo showing the detected device type and how it affects the cinema navigation arrows. On touch-only devices, arrows are hidden. On hybrid and desktop devices, arrows are shown.

<p>
  <strong>Detected device type:</strong> ${deviceType}<br />
  <code
    >isTouchable: ${pt.isTouchable} · isHybrid: ${pt.isHybrid} · isMouse: ${pt.isMouse}</code
  >
</p>
<p>
  On <strong>touch-only</strong> devices, navigation arrows are hidden (users swipe
  natively).<br />
  On <strong>hybrid</strong> and <strong>desktop/mouse</strong> devices, navigation arrows are
  visible.
</p>
<oc-cinema-v1 pagination-dots>
  ${unsafeHTML(Array.from(Array(8), (_, i) => `<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM ${i + 1}</oc-placeholder-v1>`).join(""))}
</oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Device Type Detection",
  parameters: {
    controls: {
      disabled: true
    },
    chromatic: {
      hideInChromatic: true,
      disableSnapshot: true
    }
  },
  render: () => {
    const pt = pointerType.get();
    let deviceType: string;
    if (pt.isHybrid) {
      deviceType = "Hybrid (touch + pointer)";
    } else if (pt.isTouchable) {
      deviceType = "Touch only";
    } else {
      deviceType = "Mouse / Desktop";
    }
    return html`
      <p>
        <strong>Detected device type:</strong> ${deviceType}<br />
        <code
          >isTouchable: ${pt.isTouchable} · isHybrid: ${pt.isHybrid} · isMouse: ${pt.isMouse}</code
        >
      </p>
      <p>
        On <strong>touch-only</strong> devices, navigation arrows are hidden (users swipe
        natively).<br />
        On <strong>hybrid</strong> and <strong>desktop/mouse</strong> devices, navigation arrows are
        visible.
      </p>
      <oc-cinema-v1 pagination-dots>
        ${unsafeHTML(Array.from(Array(8), (_, i) => `<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM ${i + 1}</oc-placeholder-v1>`).join(""))}
      </oc-cinema-v1>
    `;
  }
}

Interaction tests (CinemaV1.interactions.stories.ts)

Interaction test stories (automated tests, not usage patterns).

Move Cinema

Story: components-cinema-interaction-tests--move-cinema · tags: components, cinema, v1, interactions, play-fn

Args: pagination-dots=true, defaultSlot=(see snippet)

Content
Content
Content
Content
Content
Content
HTML
<oc-cinema-v1 style="width: 800px" pagination-dots>
<div tabindex="0" style="background: lightcyan">
            Content
        <div tabindex="0" style="background: lightcyan">
            Content
        <div tabindex="0" style="background: lightcyan">
            Content
        <div tabindex="0" style="background: lightcyan">
            Content
        <div tabindex="0" style="background: lightcyan">
            Content
        <div tabindex="0" style="background: lightcyan">
            Content
</oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
  args: {
    "pagination-dots": true,
    defaultSlot: `${new Array(6).fill(`<div tabindex="0" style="background: lightcyan">
              Content
            </div>
          `).join("")}`
  },
  parameters: {
    chromatic: {
      disableSnapshot: true
    }
  },
  render(args) {
    const {
      defaultSlot,
      ...props
    } = args;
    return html` <oc-cinema-v1 style="width: 800px" ${spread(props)}>
      ${unsafeHTML(defaultSlot)}
    </oc-cinema-v1>`;
  },
  play: async ({
    canvasElement
  }) => {
    await macrotasks(10);
    const {
      paginationDots,
      stageElement,
      prevButton,
      nextButton
    } = getSutElements(canvasElement);
    await waitFor("initial", async () => {
      await expect(stageElement.scrollLeft, "scrollLeft should be correct").toBe(0);
      await expect(prevButton, "previous button should not be visible").not.toBeVisible();
      await expect(nextButton, "next button should be visible").toBeVisible();
      await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([1, 0, 0]);
    });

    // Perform scroll to the right
    await click(nextButton);
    await waitFor("scrolled to right", async () => {
      await expect(prevButton, "previous button should be visible").toBeVisible();
      await expect(nextButton, "next button should be visible").toBeVisible();
      await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 1, 0]);
    });

    // Perform scroll to the right
    await click(nextButton);
    await waitFor("scrolled to right", async () => {
      await expect(prevButton, "previous button should be visible").toBeVisible();
      await expect(nextButton, "next button should not be visible").not.toBeVisible();
      await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 0, 1]);
    });

    // Perform scroll to the left
    await click(prevButton);
    await waitFor("scrolled to left", async () => {
      await expect(prevButton, "previous button should be visible").toBeVisible();
      await expect(nextButton, "next button should be visible").toBeVisible();
      await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 1, 0]);
    });

    // Perform scroll to the left
    await click(prevButton);
    await waitFor("scrolled to left", async () => {
      await expect(prevButton, "previous button should not be visible").not.toBeVisible();
      await expect(nextButton, "next button should be visible").toBeVisible();
      await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([1, 0, 0]);
    });
  }
}

Move Cinema Without Resizing

Story: components-cinema-interaction-tests--move-cinema-without-resizing · tags: components, cinema, v1, interactions

Args: resizing=none, pagination-dots=true, defaultSlot=(see snippet)

Story source (TypeScript, verbatim from Storybook)
MoveCinemaWithoutResizingStories.MoveCinemaWithoutResizing

Asynchronous Content

Story: components-cinema-interaction-tests--asynchronous-content · tags: components, cinema, v1, interactions, play-fn

HTML
<oc-cinema-v1 pagination-dots style="width: 500px"></oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html` <oc-cinema-v1 pagination-dots style="width: 500px"></oc-cinema-v1>`;
  },
  play: async ({
    canvasElement
  }) => {
    await macrotasks(10);
    const {
      cinemaElement
    } = getSutElements(canvasElement);
    const item = document.createElement("div");
    item.innerHTML = "Content";
    item.tabIndex = 0;
    const items = Array.from({
      length: 20
    }).map(() => item.cloneNode(true) as HTMLElement);

    // eslint-disable-next-line no-restricted-syntax
    for (const i of items) {
      cinemaElement.append(i);
      // eslint-disable-next-line no-await-in-loop
      await macrotasks(1);
    }
    const paginationDots = Array.from(cinemaElement.shadowRoot!.querySelectorAll(".paginationdots__item"));
    await expect(paginationDots.length, "pagination dots should be rendered").toBe(20);
    await expect(paginationDots[0].classList.contains("paginationdots__item--selected"), "first pagination dot should be selected").toBeTruthy();
    await expect(paginationDots.slice(1).some(e => e.classList.contains("paginationdots__item--selected")), "other pagination dots should not be selected").toBeFalsy();
  }
}

Pagination With Different Sizes

Story: components-cinema-interaction-tests--pagination-with-different-sizes · tags: components, cinema, v1, interactions, play-fn

<div tabindex="0" style="background: lightcyan; width: ${w}px">
  ${i + 1}. ${w}px
</div>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    const items = (widthes: number[]) => {
      return widthes.map((w, i) => html`<div tabindex="0" style="background: lightcyan; width: ${w}px">
            ${i + 1}. ${w}px
          </div>`);
    };
    return html`
      <div data-testid="cinema1">
        <h3>Gap=default</h3>
        <oc-cinema-v1 pagination-dots style="width: 500px" resizing="none">
          ${items([124, 157, 131, 219, 84, 92, 317, 160, 142])}
        </oc-cinema-v1>
      </div>

      <div data-testid="cinema2">
        <h3>Gap=50px perfect fit 3 items</h3>
        <oc-cinema-v1 pagination-dots style="width: 466px" resizing="none" gap="50px">
          ${items([100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100])}
        </oc-cinema-v1>
      </div>

      <div data-testid="cinema3">
        <h3>Gap=50px perfect fit 1 item</h3>
        <oc-cinema-v1 pagination-dots style="width: 466px" resizing="none" gap="50px">
          ${items([400, 400, 400])}
        </oc-cinema-v1>
      </div>

      <style>
        div > oc-cinema-v1 {
          background: lightcoral;
        }
      </style>
    `;
  },
  play: async ({
    canvasElement
  }) => {
    await macrotasks(10);
    const sut1 = getSutElements(canvasElement.querySelector('[data-testid="cinema1"]')!);
    sut1.prevButton.style.display = "none"; // hide buttons for better debugging
    sut1.nextButton.style.display = "none"; // hide buttons for better debugging

    const sut2 = getSutElements(canvasElement.querySelector('[data-testid="cinema2"]')!);
    sut2.prevButton.style.display = "none"; // hide buttons for better debugging
    sut2.nextButton.style.display = "none"; // hide buttons for better debugging

    const sut3 = getSutElements(canvasElement.querySelector('[data-testid="cinema3"]')!);
    sut3.prevButton.style.display = "none"; // hide buttons for better debugging
    sut3.nextButton.style.display = "none"; // hide buttons for better debugging

    // TEST CINEMA 1
    await expect(sut1.paginationDots.length).toBe(4);
    await expect(sut1.stageElement.scrollLeft).toBe(0);
    await click(sut1.paginationDots[1]);
    await waitFor("cinema 1 page 2", async () => {
      await expect(sut1.stageElement.scrollLeft).toBeGreaterThanOrEqual(439);
      await expect(sut1.stageElement.scrollLeft).toBeLessThanOrEqual(440);
    });
    await click(sut1.paginationDots[2]);
    await waitFor("cinema 1 page 3", async () => {
      await expect(sut1.stageElement.scrollLeft).toBeGreaterThanOrEqual(827);
      await expect(sut1.stageElement.scrollLeft).toBeLessThanOrEqual(828);
    });
    await click(sut1.paginationDots[3]);
    await waitFor("cinema 1 page 4", async () => {
      await expect(sut1.stageElement.scrollLeft === 1086 || sut1.stageElement.scrollLeft === 1070).toBeTruthy();
    });

    // TEST CINEMA 2
    await expect(sut2.paginationDots.length).toBe(6);
    await expect(sut2.stageElement.scrollLeft).toBe(0);
    await click(sut2.paginationDots[1]);
    await waitFor("cinema 2 page 2", async () => {
      await expect([416, 433].includes(sut2.stageElement.scrollLeft)).toBeTruthy();
    });
    await click(sut2.paginationDots[2]);
    await waitFor("cinema 2 page 3", async () => {
      await expect(sut2.stageElement.scrollLeft).toBe(883);
    });
    await click(sut2.paginationDots[3]);
    await waitFor("cinema 2 page 4", async () => {
      await expect(sut2.stageElement.scrollLeft).toBe(1333);
    });

    // TEST CINEMA 3
    await expect(sut3.paginationDots.length).toBe(3);
    await expect(sut3.stageElement.scrollLeft).toBe(0);
    await click(sut3.paginationDots[1]);
    await waitFor("cinema 3 page 2", async () => {
      await expect(sut3.stageElement.scrollLeft).toBe(433);
    });
    await click(sut3.paginationDots[2]);
    await waitFor("cinema 3 page 3", async () => {
      await expect([850, 866].includes(sut3.stageElement.scrollLeft)).toBeTruthy();
    });
  }
}