Skip to content

Blocks: Fill fixed-size cells in manual placement grids - #84504

Draft
draganescu wants to merge 23 commits into
add/grid-equal-cellsfrom
add/image-cover-manual-grid
Draft

draganescu wants to merge 23 commits into
add/grid-equal-cellsfrom
add/image-cover-manual-grid

Conversation

@draganescu

@draganescu draganescu commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

What?

Behind the gutenberg-grid-interactivity experiment, blocks fill their cell in a manual placement grid whose cells have a fixed size: Image, Cover, Video, Media & Text and Post Featured Image. Filling is not optional: wherever it makes sense for a block, the cell decides the block's size.

This PR targets the branch of #84499 (same-size cells for manual placement grids), add/grid-equal-cells, and uses the signal it adds. Split out of #84340.

Why?

With #84499, a manual placement grid has same-size cells whose size comes from the grid's width, and content never makes them bigger. Any block with a size of its own then either leaves empty space in its cell or overflows it: an image keeps its natural aspect ratio, and a Cover keeps its 430px minimum height, so it overflows every cell shorter than that.

An earlier version of this PR made only images cover their cells, with .wp-block-image rules written into the grid layout (editor and PHP) and the Image block repeating the grid's conditions to drop its inline height: auto. That tied a generic layout to one block, and every other block that needed the same treatment would have needed edits in both layout files. This version splits the job: the grid says whether its cells are fixed, and each block decides how to fill a cell.

How?

  • Grid: Give manual placement grids same-size cells #84499 sets --wp--style--grid-cells: fixed on a manual grid wherever its cells take their size from its width, auto in a viewport that sizes rows by content again, and resets it to auto for grids nested inside.
  • Each block reads it in its own style.scss with a container style query, @container style(--wp--style--grid-cells: fixed), on .is-layout-grid > .wp-block-*. A style query looks at the element's parent, and the child combinator keeps it to blocks placed directly in the grid. A block inside a Group inside a cell is left alone.
  • Image: the figure becomes a flex column; the image, linked or not, takes the space left by the caption and covers it (object-fit: cover). Images inside the caption are left alone.
  • Video: same as Image, for the video element.
  • Cover: drops its minimum height and aspect ratio, so it stretches to the cell like any grid item. Its background already covers the block.
  • Media & Text: drops its minimum height, its single row fills the block, and the media fills its side of the block, cropped. Stacked on mobile, the media takes the space left by the text.
  • Post Featured Image: the image fills the figure, which the grid already stretches to the cell.
  • The cell wins over sizes set on the block, so these rules use !important where a block writes inline styles: an image's width and height, the Cover's and Media & Text's minimum height, the Cover's aspect ratio. A user-set scale (for example "contain") and focal point still apply, since they only position the media inside the cell.
  • Because the rules live in block styles, the Image block no longer drops its editor-only inline height: auto for grids: the !important rule wins over it. Nothing in image/edit.jsx or image/image.jsx changes, and nothing in the layout names a block.
  • Left out on purpose: Embed (cropping a player is wrong), Gallery (it is a grid of its own), and text blocks (they already stretch; whether overflowing text should clip is a separate question).
  • In the editor, controls that would have no effect in a fixed cell are hidden: the Image and Post Featured Image dimension controls, and the Cover's minimum height control, resize handle and full height toggle. A private block-editor hook, useIsInFixedGridCell( clientId ), reads the parent grid's layout for the viewport whose styles are being edited (getStyleStateViewport() plus the parent's style[ viewport ].layout) and checks it with hasFixedGridCells(), the same function the grid layout uses for its CSS, so the editor UI and the styles agree on which cells are fixed. Values set before the block was moved into the grid are kept, and the controls come back when it leaves the grid or in a viewport where its cells are not fixed.
  • Style queries on custom properties are supported by every browser in Gutenberg's support range (Chrome and Edge 111, Safari 18, Firefox 151). Without them, blocks keep their own size, as on trunk. With the experiment off, nothing sets the custom property, so nothing changes.

Known limitations:

  • Controls that come from block supports rather than the block itself still show: the Cover's aspect ratio and the Media & Text minimum height (both in the Dimensions panel). The block-editor Dimensions panel cannot tell which blocks fill their cells, so hiding these would need a way for a block to declare it.
  • When responsive editing is off, the inspector edits the default (desktop) styles, so controls are hidden according to the desktop layout even while the canvas previews a narrower device.
  • Content taller than its cell, such as long text in a Cover or Media & Text, is clipped or overflows, as before.

Testing Instructions

  1. Enable the "Grid interactivity" experiment in Gutenberg > Experiments.
  2. Add a Grid block, switch it to manual placement (for example 3 columns, 2 rows, no minimum column width).
  3. Add to its cells: an Image with a caption, a linked Image with a width and height set, a Cover with a minimum height of 500px, a Video with a caption, a Media & Text block, and (in a template) a Post Featured Image.
  4. Check that every block fills its cell exactly, with media cropped as needed and captions inside the cell. Check the same on the front end.
  5. Select the Image, the Cover and the Post Featured Image: their size controls (Image and Featured Image dimensions; Cover minimum height, resize handle and the full height toolbar button) are not shown. Move the Image out of the grid: its dimension controls are back.
  6. Add a Group with an auto placement grid layout inside one cell, and a Cover inside that Group: the nested Cover keeps its own minimum height.
  7. Remove the minimum column width override if any; in the Tablet viewport, set a minimum column width: blocks keep their own sizes in that viewport only and fill their cells on desktop.
  8. Turn the experiment off and check that the grid and its blocks look as they do on trunk.

Testing Instructions for Keyboard

No new controls or interactions; nothing changes for keyboard use.

Screenshots or screencast

To add.

Use of AI Tools

Reworked with Claude Code (Claude Opus 5.5) after a review of the earlier, image-only version with the PR author, who chose to make filling the default and only behavior and to move the signal into #84499. The rules were checked in WebKit against a static page using the built block styles and the layout's new output: fixed cells, a viewport reset to auto, a nested auto grid, and the experiment off.

🤖 Generated with Claude Code

draganescu and others added 2 commits October 10, 2026 11:34
Behind the grid interactivity experiment, images in a manual placement
grid whose cells take their size from its width cover their cells,
below any caption. The cover rules follow the grid's aspect ratio
exactly: a grid with a minimum column width sizes its rows by their
content, where an image taking its height from the row would collapse,
so its images keep their own height, and a viewport that adds a
minimum column width puts images back to their own height.

In the editor, images in such a grid leave out their default inline
`height: auto` so the layout can size them; a linked image otherwise
keeps its natural height inside its link.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cover rule matched any image in a grid's Image block, including
inline images in its caption, which then shared the cell's height with
the main image and could collapse it. It now targets only the block's
own image, linked or not. A viewport that stops covering also resets
the image's width, so small images are no longer stretched there.

The Image block's flag becomes `hasHeightFromGrid`, which says what it
means. Tests cover a grid with a minimum column width whose viewport
changes the column count, and the reset inside a rendered block's
media query.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

🤖 PR meta 🤖

🏷️ Labels

This pull request needs exactly one label indicating its type, and has 0.

  • Required: any label starting with [Type].
  • Found: none.

Read more about Type labels in Gutenberg. If you cannot add labels yourself, a reviewer can do it for you.

📦 Bundle size

Size Change: +3.06 kB (+0.03%)

Total Size: 9.07 MB

📦 View Changed
Filename Size Change
build/scripts/block-editor/index.min.js 606 kB +171 B (+0.03%)
build/scripts/block-library/index.min.js 449 kB +121 B (+0.03%)
build/styles/block-library/cover/style-rtl.css 2.6 kB +58 B (+2.28%)
build/styles/block-library/cover/style-rtl.min.css 1.93 kB +59 B (+3.15%)
build/styles/block-library/cover/style.css 2.62 kB +58 B (+2.26%)
build/styles/block-library/cover/style.min.css 1.92 kB +59 B (+3.17%)
build/styles/block-library/image/style-rtl.css 3.11 kB +107 B (+3.56%)
build/styles/block-library/image/style-rtl.min.css 2.04 kB +93 B (+4.78%) 🔍
build/styles/block-library/image/style.css 3.12 kB +106 B (+3.52%)
build/styles/block-library/image/style.min.css 2.03 kB +91 B (+4.7%) 🔍
build/styles/block-library/media-text/style-rtl.css 1 kB +102 B (+11.31%) ⚠️
build/styles/block-library/media-text/style-rtl.min.css 666 B +85 B (+14.63%) ⚠️
build/styles/block-library/media-text/style.css 1.03 kB +103 B (+11.09%) ⚠️
build/styles/block-library/media-text/style.min.css 663 B +85 B (+14.71%) ⚠️
build/styles/block-library/post-featured-image/style-rtl.css 482 B +90 B (+22.96%) 🚨
build/styles/block-library/post-featured-image/style-rtl.min.css 433 B +83 B (+23.71%) 🚨
build/styles/block-library/post-featured-image/style.css 482 B +90 B (+22.96%) 🚨
build/styles/block-library/post-featured-image/style.min.css 433 B +83 B (+23.71%) 🚨
build/styles/block-library/style-rtl.css 23.1 kB +295 B (+1.29%)
build/styles/block-library/style-rtl.min.css 19.6 kB +228 B (+1.18%)
build/styles/block-library/style.css 23.2 kB +297 B (+1.29%)
build/styles/block-library/style.min.css 19.6 kB +226 B (+1.17%)
build/styles/block-library/video/style-rtl.css 1.22 kB +97 B (+8.65%) 🔍
build/styles/block-library/video/style-rtl.min.css 288 B +86 B (+42.57%) 🚨
build/styles/block-library/video/style.css 1.22 kB +97 B (+8.65%) 🔍
build/styles/block-library/video/style.min.css 288 B +86 B (+42.57%) 🚨

5cf0add Run

⚡ Performance

Show the results

Client side metrics exclude the server response time.

front-end-block-theme

Metric 5de5a22 trunk % Change
timeToFirstByte 52.4 ms +9.35% -2.58% 54.45 ms +11.85% -3.21% -3.76%
largestContentfulPaint 94 ms +4.26% -10.64% 96 ms +0% -8.33% -2.08%
lcpMinusTtfb 38.85 ms +6.69% -14.03% 34.05 ms +26.87% -6.17% 14.1%
wpBeforeTemplate 28.04 ms +6.53% -1.71% 28.59 ms +18.22% -1.33% -1.92%
wpTemplate 20.33 ms +5.61% -2.36% 21.44 ms +4.9% -2.94% -5.18%
wpTotal 48.65 ms +10.09% -2.2% 50.52 ms +10.95% -3.01% -3.7%
wpMemoryUsage 7.68 MB +0% -0% 7.65 MB +0% -0% 0.43%
wpDbQueries 16 +0% -0% 16 +0% -0% 0%

front-end-classic-theme

Metric 5de5a22 trunk % Change
timeToFirstByte 45.2 ms +4.76% -1.33% 46.6 ms +7.51% -2.04% -3%
largestContentfulPaint 100 ms +2% -0% 100 ms +4% -0% 0%
lcpMinusTtfb 54.8 ms +1.37% -1.19% 54.15 ms +1.2% -1.39% 1.2%
wpBeforeTemplate 26.07 ms +1.96% -0.81% 26.57 ms +8.24% -0.53% -1.88%
wpTemplate 15.95 ms +1.69% -1.88% 16.5 ms +3.7% -1.76% -3.33%
wpTotal 42.11 ms +5.01% -1.07% 43.5 ms +7.54% -1.84% -3.2%
wpMemoryUsage 6.37 MB +0% -0% 6.34 MB +0% -0% 0.54%
wpDbQueries 13 +0% -0% 13 +0% -0% 0%

media-processing

Metric 5de5a22 trunk % Change
mediaProcessingJpeg 399.06 ms +1.66% -0.98% 400.58 ms +0.65% -0.27% -0.38%
mediaProcessingAvif 6074.89 ms +0.21% -0.19% 6078.19 ms +0.14% -0.17% -0.05%
mediaProcessingJpegToAvif 4188.92 ms +0.16% -0.3% 4189.65 ms +0.12% -0.17% -0.02%

media-upload

Metric 5de5a22 trunk % Change
jpegUploadProcessing 1703.83 ms +15.73% -15.93% 1435.43 ms +0.79% -1.3% 18.7%
pngUploadProcessing 213.51 ms +2.7% -12.02% 206.15 ms +14.47% -13.98% 3.57%
largeJpegUploadProcessing 1415.8 ms +1.41% -0.92% 1434.47 ms +0.54% -0.69% -1.3%
multipleImageUploadProcessing 2089.5 ms +0.59% -2.22% 2079.67 ms +1.21% -6.76% 0.47%

post-editor

Metric 5de5a22 trunk % Change
serverResponse 516.76 ms +0.57% -9.52% 513.21 ms +1.44% -10.42% 0.69%
firstPaint 464.78 ms +9.94% -39.73% 477.93 ms +4.13% -2.81% -2.75%
domContentLoaded 1185.65 ms +1.91% -1.65% 1186.53 ms +3.96% -1.06% -0.07%
loaded 1186.94 ms +1.89% -1.68% 1187.47 ms +4.01% -1.06% -0.04%
firstContentfulPaint 511.47 ms +3.01% -7.45% 494.71 ms +9.56% -3.8% 3.39%
firstBlock 3397.13 ms +2.63% -2.06% 3389.61 ms +4.22% -0.63% 0.22%
type 17.27 ms +5.21% -1.8% 18.4 ms +5.16% -6.74% -6.14%
typeWithoutInspector 16.79 ms +4.82% -0.3% 17.43 ms +4.42% -4.3% -3.67%
typeWithTopToolbar 23.49 ms +7.45% -3.96% 23.18 ms +4.79% -4.18% 1.34%
typeContainer 8.46 ms +10.4% -6.03% 8.11 ms +11.84% -9.37% 4.32%
focus 119.49 ms +7.93% -2.69% 121.85 ms +3.36% -6.07% -1.94%
firstFocus 232.07 ms +0% -0% 228.87 ms +0% -0% 1.4%
selectAll 540.89 ms +0.15% -3.15% 557.22 ms +1.11% -1.51% -2.93%
listViewOpen 80.14 ms +1.36% -8.21% 83.26 ms +2.32% -5.69% -3.75%
inserterOpen 42.45 ms +11.33% -7.84% 40.93 ms +8.87% -9.6% 3.71%
inserterHover 11.29 ms +8.15% -11.07% 11.93 ms +7.88% -11.9% -5.36%
inserterSearch 7.86 ms +13.61% -2.67% 7.85 ms +6.5% -4.84% 0.13%
loadPatterns 613.72 ms +4.18% -4.66% 625.87 ms +6.32% -5.49% -1.94%
wpTotal 506.28 ms +0.76% -9.56% 502.8 ms +1.67% -10.65% 0.69%
wpMemoryUsage 14.71 MB +0% -0% 14.68 MB +0% -0% 0.24%
wpDbQueries 55 +0% -1.82% 55 +0% -1.82% 0%

site-editor

Metric 5de5a22 trunk % Change
serverResponse 501.94 ms +1.3% -1.59% 488 ms +1.2% -3.38% 2.86%
firstPaint 247.34 ms +11.01% -9.38% 250.6 ms +15.17% -2.51% -1.3%
domContentLoaded 1304.09 ms +1.2% -1.66% 1289.34 ms +1.04% -1.17% 1.14%
loaded 1305.49 ms +1.2% -1.65% 1290.42 ms +1.04% -1.15% 1.17%
firstContentfulPaint 519.03 ms +2.07% -5.35% 513.27 ms +4.37% -1.17% 1.12%
firstBlock 4674.66 ms +0.24% -0.44% 4616.3 ms +0.5% -0.45% 1.26%
type 18.42 ms +2.17% -2.23% 19.4 ms +11.39% -3.61% -5.05%
navigate 119.43 ms +8.41% -0.9% 116.05 ms +12.01% -5.45% 2.91%
loadPatterns 1230.06 ms +18.91% -3.85% 1260.67 ms +7.44% -2.36% -2.43%
loadPages 970.1 ms +1.45% -3.03% 978.09 ms +5.41% -2.62% -0.82%
wpTotal 492.64 ms +1.25% -1.67% 478.54 ms +1.21% -3.34% 2.95%
wpMemoryUsage 12.73 MB +0% -0% 12.69 MB +0% -0% 0.28%
wpDbQueries 44 +2.27% -0% 44 +2.27% -0% 0%

5cf0add Run

🏁 Flaky tests

Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

Backspace in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  -  5
+ Received  + 11

@@ -1,25 +1,31 @@
  Array [
    Object {
      "innerBlocks": Array [
        Object {
          "attributes": Object {
-           "content": "1",
+           "content": "1‸a",
          },
-         "innerBlocks": Array [
+         "innerBlocks": Array [],
+         "name": "core/list-item",
+       },
        Object {
+         "attributes": Object {
+           "content": "2",
+         },
          "innerBlocks": Array [
            Object {
              "attributes": Object {
-                   "content": "a‸2",
+               "ordered": false,
+               "values": "",
              },
-                 "name": "core/list-item",
-               },
+             "innerBlocks": Array [
                Object {
                  "attributes": Object {
                    "content": "b",
                  },
+                 "innerBlocks": Array [],
                  "name": "core/list-item",
                },
              ],
              "name": "core/list",
            },

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:2041:42
Custom Completer: should allow newlines after multiple option completions in /test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 2
+ Received  + 2

@@ -5,15 +5,15 @@
  <!-- wp:paragraph -->
  <p>🫐 test</p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph -->
- <p>🫐 test</p>
+ <p>🍎 test</p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph -->
- <p>🫐 test</p>
+ <p>🍎 test</p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph -->
  <p></p>
  <!-- /wp:paragraph -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js:466:6
Custom Completer: should not insert disabled options in /test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

  <!-- wp:paragraph -->
- <p>Sorry, we are all out of ~g grapes.</p>
+ <p>Sorry, we are all out of 🍎 grapes.</p>
  <!-- /wp:paragraph -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/autocomplete-and-mentions.spec.js:391:7
Delete (forward) in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  -  2
+ Received  + 25

@@ -1,25 +1,48 @@
  Array [
    Object {
      "innerBlocks": Array [
        Object {
          "attributes": Object {
-           "content": "1",
+           "content": "‸",
          },
          "innerBlocks": Array [
            Object {
+             "attributes": Object {
+               "ordered": false,
+               "values": "",
+             },
              "innerBlocks": Array [
                Object {
                  "attributes": Object {
-                   "content": "a‸2",
+                   "content": "a",
                  },
+                 "innerBlocks": Array [],
                  "name": "core/list-item",
+               },
+             ],
+             "name": "core/list",
            },
+         ],
+         "name": "core/list-item",
+       },
+       Object {
+         "attributes": Object {
+           "content": "2",
+         },
+         "innerBlocks": Array [
            Object {
              "attributes": Object {
+               "ordered": false,
+               "values": "",
+             },
+             "innerBlocks": Array [
+               Object {
+                 "attributes": Object {
                    "content": "b",
                  },
+                 "innerBlocks": Array [],
                  "name": "core/list-item",
                },
              ],
              "name": "core/list",
            },

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:2056:42
Regression: updating a specific option will only change its value and will not corrupt others in /test/e2e/specs/editor/various/core-settings.spec.js, passed after 1 failed attempt.
Error: expect(received).toStrictEqual(expected) // deep equality

- Expected  - 1
+ Received  + 1

  Array [
    "rewrite_rules",
-   "SERIALIZED DATA",
+   "",
  ]
    at forEach (/home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:46:26)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/core-settings.spec.js:43:35
Undo restores the post selection when another synced entity is loaded (RTC WebSocket) in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 2,
+   "offset": 2,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
Undo restores the post selection when another synced entity is loaded in /test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 2
+ Received  + 2

  Object {
    "attributeKey": "content",
    "blockIndex": 0,
    "content": "abcdef",
-   "endOffset": 3,
-   "offset": 3,
+   "endOffset": 1,
+   "offset": 1,
  }

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/collaboration/collaboration-undo-redo.spec.ts:363:5
can be converted to a quote in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

@@ -1,9 +1,9 @@
  <!-- wp:quote -->
  <blockquote class="wp-block-quote"><!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>one</li>
+ <li>ne</li>
  <!-- /wp:list-item -->

  <!-- wp:list-item -->
  <li>two</li>
  <!-- /wp:list-item --></ul>

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:436:52
can be converted to paragraphs in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

  <!-- wp:paragraph -->
- <p>one</p>
+ <p>ne</p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph -->
  <p>two</p>
  <!-- /wp:paragraph -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:391:52
can be converted when nested to paragraphs in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

  <!-- wp:paragraph -->
- <p>one</p>
+ <p>e</p>
  <!-- /wp:paragraph -->

  <!-- wp:paragraph -->
  <p>two</p>
  <!-- /wp:paragraph -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:417:52
can be copied from multi selection in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 2
+ Received  + 2

@@ -1,18 +1,18 @@
  <!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>one</li>
+ <li>ne</li>
  <!-- /wp:list-item -->

  <!-- wp:list-item -->
  <li>two</li>
  <!-- /wp:list-item --></ul>
  <!-- /wp:list -->

  <!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>one</li>
+ <li>ne</li>
  <!-- /wp:list-item -->

  <!-- wp:list-item -->
  <li>two</li>
  <!-- /wp:list-item --></ul>
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:33:49
should be immediately saved on indentation in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
TimeoutError: locator.click: Timeout 10000ms exceeded.
Call log:
  - waiting for locator('role=toolbar[name="Block tools"i]').locator('role=button[name="Indent"]')

    at Editor.clickBlockToolbarButton (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/editor/click-block-toolbar-button.ts:17:15)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:692:3
should change the indented list type in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
TimeoutError: locator.click: Timeout 10000ms exceeded.
Call log:
  - waiting for locator('role=toolbar[name="Block tools"i]').locator('role=button[name="Indent"]')

    at Editor.clickBlockToolbarButton (/home/runner/work/gutenberg/gutenberg/packages/e2e-test-utils-playwright/src/editor/click-block-toolbar-button.ts:17:15)
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:727:3
should create paragraph on Enter in quote block in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
TimeoutError: locator.click: Timeout 10000ms exceeded.
Call log:
  - waiting for getByRole('option', { name: 'List', exact: true })

    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:751:67
should create paragraph on split at end and merge back with content in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 1
+ Received  + 1

@@ -1,8 +1,8 @@
  <!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>one</li>
+ <li>e</li>
  <!-- /wp:list-item --></ul>
  <!-- /wp:list -->

  <!-- wp:paragraph -->
  <p></p>

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:461:52
should cut and paste individual blocks with collapsed selection in /test/e2e/specs/editor/various/copy-cut-paste.spec.js, passed after 1 failed attempt.
Error: expect(string).toMatchSnapshot(expected) failed

  @@ -1,3 +1,3 @@
   <!-- wp:paragraph -->
  -<p>2Cut - collapsed selection</p>
  +<p>2</p>
   <!-- /wp:paragraph -->


    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/copy-cut-paste.spec.js:45:49
should gradually multi-select in /test/e2e/specs/editor/various/multi-block-selection.spec.js, passed after 1 failed attempt.
Error: expect(received).toMatchObject(expected)

- Expected  - 3
+ Received  + 7

  Array [
    Object {
-     "name": "core/column",
+     "attributes": Object {
+       "content": "1",
+       "dropCap": false,
      },
-   Object {
-     "name": "core/column",
+     "clientId": "fe21c71d-a848-4cd2-8f2f-b67acd1d16c0",
+     "innerBlocks": Array [],
+     "isValid": true,
+     "name": "core/paragraph",
    },
  ]

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/various/multi-block-selection.spec.js:1151:5
should indent and outdent a list item when its content is fully selected in /test/e2e/specs/editor/blocks/list.spec.js, passed after 1 failed attempt.
Error: expect(received).toBe(expected) // Object.is equality

- Expected  - 5
+ Received  + 1

  <!-- wp:list -->
  <ul class="wp-block-list"><!-- wp:list-item -->
- <li>a<!-- wp:list -->
- <ul class="wp-block-list"><!-- wp:list-item -->
- <li>b</li>
- <!-- /wp:list-item --></ul>
- <!-- /wp:list --></li>
+ <li></li>
  <!-- /wp:list-item --></ul>
  <!-- /wp:list -->

Call Log:
- Timeout 5000ms exceeded while waiting on the predicate
    at /home/runner/work/gutenberg/gutenberg/test/e2e/specs/editor/blocks/list.spec.js:819:52

Truncated. See the full report.

5cf0add Run

@github-actions github-actions Bot added [Package] Block library /packages/block-library [Package] Block editor /packages/block-editor labels Oct 10, 2026
@draganescu draganescu changed the title Image: Cover their cells in manual placement grids Image: Cover the cell in manual placement grids Oct 10, 2026
# Conflicts:
#	packages/block-editor/CHANGELOG.md
draganescu and others added 3 commits October 10, 2026 13:40
Blocks now fill fixed-size cells from their own styles, reading the
grid's `--wp--style--grid-cells` signal, so the layout no longer needs
to know about the Image block, and the Image block no longer needs to
repeat the grid's conditions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Image, Cover, Video, Media & Text and Post Featured Image fill their cell
when a manual placement grid sets `--wp--style--grid-cells: fixed`. Each
block reads it with a container style query in its own stylesheet and
decides how to fill: media blocks crop with `object-fit: cover`, Cover
and Media & Text drop their minimum height. The cell wins over sizes set
on the block. Embeds, galleries and text blocks are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot removed the [Package] Block editor /packages/block-editor label Oct 10, 2026
@draganescu draganescu changed the title Image: Cover the cell in manual placement grids Blocks: Fill fixed-size cells in manual placement grids Oct 10, 2026
A private block-editor hook, useIsInFixedGridCell, tells a block whether
its parent grid has fixed-size cells in the viewport whose styles are
being edited, reading the parent's viewport layout through
getStyleForState. It shares hasFixedGridCells with the grid layout's own
CSS, so the editor and the styles agree on which cells are fixed.

Image and Post Featured Image hide their dimension controls in such
cells, and Cover hides its minimum height control, resize handle and full
height toggle, since the cell decides their size.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the [Package] Block editor /packages/block-editor label Oct 10, 2026
draganescu and others added 8 commits October 14, 2026 14:48
# Conflicts:
#	packages/block-library/CHANGELOG.md
…peScript

Trunk converted the grid layout and its tests to TypeScript, so
`hasFixedGridCells` and the experiment flag saved in its tests need
types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New files in block-editor must be TypeScript. Types the registry select,
the parent block's layout and style attributes, and the test setup; the
runtime logic is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
draganescu and others added 7 commits October 23, 2026 12:04
In a grid cell with a fixed size, the cell decides a block's size. The
block editor's dimensions hook now turns off the minimum height and
aspect ratio block-support controls there, so Cover, Media & Text and
Video hide them the same way. Cover still hides its own minimum height
control, resize handle and full height toggle, which aren't block
supports.

Image and Post Featured Image no longer hide their whole size panel.
They keep Scale, and Image keeps its focal point, which needs Scale:
picking a focal point sets the scale to cover, which the cell already
uses. `DimensionsTool` shows Scale whenever it is the only tool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Block editor /packages/block-editor [Package] Block library /packages/block-library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant