Block Attributes
The gallery block's stored shape — what each attribute holds, and its default.
The block is shaped-gallery/gallery. Everything a gallery is lives in its attributes, serialized into post content.
Read this alongside the inspector reference
Each attribute maps to a control. The Gallery Block says what each control does; this page says what it stores.
Conventions
Three shapes recur throughout.
Responsive scalar — one value per device, plus a unit:
{ "desktop": 4, "tablet": 3, "mobile": 2, "unit": "px" }Box model — per device, with an optional unit:
{ "desktop": { "top": 8, "right": 16, "bottom": 8, "left": 16 }, "tablet": {}, "mobile": {}, "unit": "px" }Grouped object — related settings under one key (imageVideo, content, ajaxPagination, filterSearch, motion, advanced, lightbox).
Core
| Attribute | Type | Default | Holds |
|---|---|---|---|
uniqueId | string | — | The gallery's CSS scope. |
galleryId | number | — | The saved gallery's post id, when it is one. |
layout | string | justified | One of justified, grid, masonry, metro, thumbnails, staggered, perspective. |
items | array | [] | The media items. |
categories | array | [] | This gallery's category vocabulary, as { id, name }. |
provider | string | media_library | The source the gallery was built from. |
order | string | default | default or random. |
clickAction | string | lightbox | lightbox, url or none. |
Never rewrite uniqueId or items[].id
uniqueId is the gallery's style scope — two galleries sharing one would share CSS. Item ids are meaningful only on the site that authored them, which is why imported patterns have all three stripped on the way in.
Shared layout
| Attribute | Type | Default |
|---|---|---|
columns | responsive | 4 / 3 / 2 |
horizontalGap | responsive | 15 px |
verticalGap | responsive | 15 px |
margin | box model | empty |
Per-layout
Justified
| Attribute | Type | Default |
|---|---|---|
rowHeightMode | string | auto |
maxRowHeight | number | 280 |
Staggered
| Attribute | Type | Default |
|---|---|---|
staggeredImageHeight | string | custom |
staggeredImageHeightSize | number | 280 |
preserveLayoutGaps | responsive | 50 % |
Metro
| Attribute | Type | Default |
|---|---|---|
featuredImageSize | string | 2 |
Stored but currently not exposed as a control — Metro ships as a fixed mosaic.
Thumbnails
| Attribute | Type | Default |
|---|---|---|
thumbnailCount | responsive | 5 / 4 / 3 |
thumbnailPosition | string | bottom |
thumbnailAreaWidth | string | auto |
thumbnailAreaWidthSize | responsive | 500 / 400 / 300 px |
thumbnailSideWidth | responsive | 110 px |
thumbnailHeight | responsive | 90 px |
thumbnailGap | responsive | 8 / 8 / 6 px |
activeThumbnailStyle | string | border-around |
thumbnailAlignment | string | left |
thumbnailNavArrow | boolean | false |
thumbnailStyle | object | (see below) |
thumbnailStyle holds autoplay, slidingSpeed (500), hoverEffect (normal), activeBorderWidth (2 px), activeBorderColor (#3858e9), the area's areaBackground / areaBorder / areaBorderWidth / areaBorderRadius / areaPadding, plus pauseOnHover (true), infiniteLoop (true) and keyNavigation (false).
Perspective
| Attribute | Type | Default |
|---|---|---|
gallerySize | object | width empty (auto), height 700 px |
perspectiveMode | string | table |
slideDirection | string | up |
slideSpeed | number | 3 |
perspectiveDepth | responsive | 800 px |
rotateX · rotateY · rotateZ | responsive | 0 deg |
edgeFade | boolean | false |
alternateColumns | boolean | false |
mouseTilt | boolean | true |
mouseParallax | responsive | 1 |
imageVideo
| Key | Default |
|---|---|
resolution | large |
lazyLoad | true |
imagePreloader | false |
imageWatermark | false |
rightClickProtection | false |
videoPlayMode | inline |
autoplay | true |
playIconSize | 48 |
displayIconOnHover | false |
hoverAnimation | zoom |
animationDuration | 500 |
style.normal · style.hover | per-state filter, opacity, overlay, border, radius, shadow |
content
| Key | Default |
|---|---|
imageTitle | false |
imageTitleSource | title |
imageTitleTag | h4 |
imageDescription | false |
imageDescriptionSource | caption |
descriptionLimit | 4 lines |
displayStyle | classic |
overlayStyle | full |
contentVisibility | always |
overlayOpacity | 0.4 |
overlayPosition | center |
overlaySize | 75 |
position | bottom |
alignment | left |
titleToDescGap | 16 px |
| Title / description typography, sizes, colours, plus the box's background, border, radius and padding | unset |
Overlay keys are always stored
They persist even while Content Display Style is Classic, so a gallery switching back and forth keeps its overlay configuration.
lightbox
One key: clickActionType, default full_image.
Everything else about the lightbox — which icon, its style, position, offset, and the whole viewer — is site-wide, in the Lightbox module's own settings, and merged in at render time. It is never stored on the block. Why →
ajaxPagination
| Key | Default |
|---|---|
enable | false |
type | load_more |
numberType | number |
numberGap | 10 px |
infinityLoad | false |
showPerView | 15 |
buttonLabel | Load More |
endingMessage | No more images available |
alignment | center |
style | typography, per-state button colours, radius, padding, margin |
filterSearch
| Key | Default |
|---|---|
enable | false |
filterStyle | minimal |
displayCount | false |
showAll | true |
allLabel | All |
filterGap | 16 px |
imageSearch | false |
searchBarStyle | minimal |
placeholder | true |
placeholderText | Search |
searchWidth | 25 % |
alignment | left |
orientation | inline |
barGap | 16 px |
justify | flex-start |
style · searchStyle | the chip and field styling bundles |
motion
| Key | Default |
|---|---|
entranceAnimation | none |
animationSpeed | 1 |
animationDelay | 0 |
advanced
| Key | Default |
|---|---|
background | unset |
padding · margin | empty box model |
visibility.mode | public |
visibility.password | '' |
visibility.hideDesktop · hideTablet · hideMobilePortrait · hideMobileLandscape | false |
customCssClass · customCssId | '' |
advanced.customCss may exist and is inert
Galleries built before the per-gallery CSS field was removed still carry the key. Nothing reads it and nothing prints it. It isn't migrated away, because rewriting every post to strip an inert key is a destructive pass for no gain.
Item shape
Each entry in items is a normalised media item, whatever provider it came from:
| Key | Holds |
|---|---|
id | Attachment id, or the URL for an external item. |
type | image or video. |
url · thumb · full | The display, thumbnail and full-size sources. |
width · height | Intrinsic dimensions, used by the measured layouts. |
alt · title · caption · description | Per-gallery text overrides. An empty value falls back to the attachment. |
link | The custom URL. |
categories | This gallery's category ids the item belongs to. |
provider | Which provider produced it. |
Things worth knowing
Defaults live in one place. Every default above is declared once and read by both the editor and the server, so a control and its rendering can't disagree.
Every value is re-validated on render. Attributes are block data, which means a user can edit them — so enums are allow-listed and numbers are clamped on the server, not trusted from the block.
Adding an attribute is a five-step change: the schema, the generated block.json, server-side validation and default, the inspector control, and something that consumes it. An attribute with no consumer is a control that saves and does nothing.
Where to go next
- The Gallery Block — what each of these controls does
- Hooks · Media Providers