HyImageGallery
Usage examples on this page are written for Lit / plain HTML (
<hy-image-gallery>). The same component ships asHyImageGalleryin@whitespaceux/harmony-react(native React 19), with typed wrappers for Angular, Solid, Svelte, and Vue. The API reference below applies to all frameworks.
Child components: <hy-image-gallery-item> — used only inside this one.
A responsive, accessible, CLS-free grid of slotted images. Lays out hy-image-gallery-item children, enforces a uniform aspect ratio, and emits a click contract (item-click) that a separate viewer (e.g. a dialog) can consume.
Grid-only by design — the full-screen lightbox is a separate concern (compose item-click with hy-dialog). Uses list semantics (role="list" here, role="listitem" on each item) and native Tab order, not a custom keyboard grid.
Performance
The author owns each <img>. Eager-load (and fetchpriority="high") the first row for LCP; lazy-load the rest. The fixed aspect-ratio crop box reserves space so there is no layout shift while images load.
When to use
- A set of pictures people look through: product photos, a portfolio, uploads.
Do
- Show the pictures at one
aspect-ratio. - Add a caption when the picture alone does not say what it is.
When not to use
- Images shown one at a time in sequence:
hy-carousel. - Tiles with titles, details or actions:
hy-cardin a grid of your own. - Records with a thumbnail:
hy-tableorhy-datagridwith an image column. - One hero or inline image: a plain
<img>. - A larger view of a picked image: mark items
interactiveand open anhy-dialogfromitem-click. The gallery has no viewer.
Accessibility: your part
- Give every slotted image meaningful
alttext, oralt=""when it only decorates. - When a viewer opened from
item-clickcloses, return focus to the item that opened it.
Examples
Responsive grid
<hy-image-gallery label="Photos">
<hy-image-gallery-item caption="One"><img src="/1.jpg" alt="One" /></hy-image-gallery-item>
<hy-image-gallery-item caption="Two"><img src="/2.jpg" alt="Two" /></hy-image-gallery-item>
</hy-image-gallery>Open a viewer on click
<hy-image-gallery label="Photos">
<hy-image-gallery-item interactive><img src="/1.jpg" alt="One" /></hy-image-gallery-item>
</hy-image-gallery>
<script>
gallery.addEventListener('item-click', (e) => openDialog(e.detail.index));
</script>API
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
columns | columns | ImageGalleryColumns | 'auto' | 'auto' (responsive auto-fit) or a fixed number of columns. |
minColumn | min-column | string | '16rem' | Minimum column width for the auto grid. Maps to --hy-image-gallery-min-column. |
gap | gap | string | '' | Gap override; default comes from --hy-image-gallery-gap-container-md. |
aspectRatio | aspect-ratio | string | '1 / 1' | Uniform crop aspect ratio for every item. 'auto' requires layout="masonry". |
objectFit | object-fit | 'cover' | 'contain' | 'cover' | How items meet their crop box: cover fills it, cropping the image; contain shows the whole image on the item's crop background. |
layout | layout | 'uniform' | 'masonry' | 'uniform' | Layout mode. masonry is progressive-enhancement. |
label | label | string | '' | Accessible name for the list region (aria-label). |
state | state | 'idle' | 'loading' | 'empty' | 'error' | 'idle' | Data-region state (consumer-driven). |
listLabel | list-label | string | 'Image gallery' | Accessible name of the image list when label is unset. Use for internationalization. |
statusLabel | status-label | string | 'Gallery' | Accessible name of the empty / error region (state="empty" / "error") when label is unset. Use for internationalization. |
emptyHeadingText | empty-heading-text | string | undefined | — | Heading of the empty state (state="empty"). Unset, it is hy-empty-state's English default: Nothing here yet. Use for internationalization. |
errorHeadingText | error-heading-text | string | undefined | — | Heading of the error state (state="error"). Unset, it is hy-empty-state's English default: Something went wrong. Use for internationalization. |
errorDescriptionText | error-description-text | string | undefined | — | Description of the error state (state="error"). Unset, it is hy-empty-state's English default: We couldn't load this. Please try again. Use for internationalization. |
retryLabel | retry-label | string | undefined | — | Label of the error state's retry button. Unset, it is hy-empty-state's English default: Retry. Use for internationalization. |
Events
| Event | Detail | Description |
|---|---|---|
item-click | — | An interactive item was activated. Detail: { index: number, item: HyImageGalleryItem } |
retry | — | The error-state retry button was clicked. Detail: {} |
Slots
| Slot | Description |
|---|---|
default | The hy-image-gallery-item children. |
CSS Parts
| Part | Description |
|---|---|
base | The grid list (<ul role="list">). |
CSS Custom Properties
The documented hooks. Every override hook the component reads — one per token it paints — is listed in @whitespaceux/harmony/theme-api.json, and @whitespaceux/harmony/component-bindings.json (the Harmony MCP get-bindings tool) says which part and state each one paints.
| Property | Default | Description |
|---|---|---|
--hy-image-gallery-gap-container-md | var(--hy-gap-container-md) | Gap between cells. |
--hy-image-gallery-min-column | — | Minimum column width for the auto grid. |
--hy-image-gallery-aspect-ratio | — | Uniform crop aspect ratio (cascades to items). |
--hy-image-gallery-object-fit | cover | How items fill their crop box (cascades to items). |