Repository navigation
Description
This is the implementation overview for #81796, which tracks turning manual grid placement into a free-form canvas. It lists the work in the order we plan to land it and links each item to the pull requests that cover it today. Most of the code exists as a stack of draft PRs (#85397), which will be reorganised to follow this order. Review findings for the stack are collected in #85295.
All of it is behind the "Grid interactivity" experiment. Rotation needs no experiment: it is a block support that blocks opt into with supports.rotation.
Foundation
General fixes and block features the canvas relies on, but which are useful on their own. They come first because they can land on trunk independently, and each one that lands makes the PRs after it smaller.
- Rotate block support — Add a rotation block support #84505 (Core: Editor: Add the rotation block support wordpress-develop#14707). Rotation is a general block support stored with the block's styles, so it works in any layout; the canvas only adds a handle for it later.
- Fix resize handles hiding when a block touches the edge of its container — commit d2f799f inside Grid: Add and remove rows of manual placement grids #84502, to be split out. A side touching the grid's edge loses its handle even though the block can still shrink from there, and the check goes stale when the block moves.
- Fix dragging with a drop target inside another drop target — Compose: Start useDropZone drags on the document's first dragover #85412, plus the stuck drag fix in Grid: Snap drags to cells in manual placement grids #84500. When a drop area drawn over the editor canvas (like the grid's) takes a drop, the editor can miss the end of the drag and keep block tools hidden until another drag ends.
- Let some blocks fill their area and keep their proportions when resized — Blocks: Fill fixed-size cells in manual placement grids #84504. Image, Cover, Video, Media & Text and Featured Image crop to fill their cells instead of overflowing or leaving gaps, so resizing changes the frame, not the shape of the media. It reads a "cells have a fixed size" signal from the grid, so it either lands with equal cells or brings that signal with it.
- Smaller fixes already split out against trunk — Preserve block's child layout attributes when it is transformed #85045 keeps a block's grid position and size when it is transformed (Paragraph to Heading, for example). Layout: Keep box-sizing for fixed-width children of flex layouts #85373 keeps
box-sizingon the front end, which free placement needs and which already fixes fixed-width items in Row and Stack. Next candidate to split: the cell inserter dropping a pattern's own styles, fixed inside Grid: Draw blocks across cells in manual placement grids #84503. - Migrate content that already uses manual placement, starting with the navigation overlay — no PR yet. The navigation overlay pattern has shipped without an experiment since Navigation overlay: remove experiment #74968, and its markup sets
isManualPlacement: trueon a two-column, two-row grid (lib/overlay-patterns.php). It does this so the editor keeps its rows and block positions: in auto mode the grid's layout sync removesrowCount. Patterns are copied into content when they are inserted, so every overlay a site has saved, and every manual grid people saved while trying the experiment, carries the flag that the canvas features key on. When the experiment is stabilised, those grids pick up the canvas behaviour without anyone choosing it: equal rows on the front end, the canvas tools in the editor, and the "Canvas" name, since the variation matches any manual grid. Changing the pattern file only fixes future insertions, so this needs two parts: the overlay pattern reworked so it no longer depends on manual placement, and a conversion for saved content, either when the block is parsed in the editor (as core already does for older grid attributes) or when the layout is rendered. It has to land before the experiment is stabilised, and Grid interactivity stack: review findings #85295 already lists it as a requirement ("a migration or an opt-in, not a default flip"). - Grid: Resize blocks from the corners #85763 Explore a corner resize handle A corner handle changes width and height in one move, as people expect from canvas tools. It also needs an answer for rotated blocks, Holding Shift should keep the aspect ratio, so the modifier for free placement needs to be a different key? Maybe.
- Explore a block context menu — no PR yet. Right-click, Shift+F10 or a long press on a block opens a menu at the pointer; Gutenberg only does this in List View today. Layouts and blocks add their own items, so the canvas can put its placing and arranging commands where people expect them in a design tool without crowding the toolbar.
- Explore a corner radius handle — no PR yet. A handle at a block's corner rounds its corners as you drag, writing the border radius the block already supports, so every block with radius support gets it, not only canvas items.
- Explore image shapes — no PR yet. A set of mask shapes for images (circle, arch, flower and others), as a block support that works anywhere. The photo always fills the shape, which either stretches to the frame or keeps its own proportions.
- Explore repositioning an image inside its frame — no PR yet. Double-clicking a cropped image lets you drag the photo inside its frame or shape, with the hidden part shown faintly, and writes the focal point Image already has. Today the focal point can only be set in the sidebar.
Canvas UX
Makes a manual grid look and behave like a canvas: even cells, a ready-made block to start from, toolbars that stay out of the way, and a height you can change on the canvas. This comes before adding and placing blocks because those tools measure and snap to cells, so the cells have to be predictable first.
- Equal grid cell size in manual mode — Grid: Give manual placement grids same-size cells #84499. Rows were sized by their content, so cells grew with whatever was in them; equal, close to square cells make placement predictable and are what snapping and guides measure against.
- Explore lining the grid up with the theme's layout — no PR yet. Today a manual grid divides its own box into columns, so its cells have no relation to the rest of the page. In a full-width section on a theme with a 1200px wide size, a heading spanning columns 2 to 11 starts about 176px from the left on a 1600px screen, while the content of the sections around it starts at 200px; on a 1400px screen the heading starts at about 160px and the content around it at 100px. The heading never lines up with its neighbours, and the mismatch changes as the window is resized. Laying the columns out inside the theme's wide area, with extra cells continuing at the same spacing out to the section's edges, gives a canvas the same cells as the rest of the site. Blocks can then be attached to those edges: a heading attached to the wide edges stays lined up with the sections around it at any width, and an image attached to the section's edge always reaches the edge of the screen. Choosing the number of columns from the section's alignment (more for full width, fewer for wide) keeps cells the same size from one section to the next.
- Introduce the Canvas grid block variation — in Grid: Show the canvas handles in a small toolbar, and add a Canvas block #84947 (32 by 32 cells in Grid: Select the grid on empty cells, draw drag tiles behind blocks, 32×32 Canvas #85277), to be split from the handles toolbar. A Group variation that starts as a full-width manual grid, so starting a layout doesn't mean inserting a Grid, switching it to manual and setting columns and rows by hand.
- Explore starting from a canvas pattern — no PR yet. An empty canvas shows its cells and an "Add pattern" button that opens a chooser limited to patterns built as canvases, and the toolbar has "Add pattern after" to add the next section from the same chooser, so people start from a finished composition instead of an empty grid. Canvas patterns need to be written for this, and their images need licensing.
- Absorb child block toolbars — in Grid: Show block toolbars over manual grids and add a drag handle #84894, to be split from the drag handle. On a canvas blocks sit next to and on top of each other, so a toolbar floating over each one covers its neighbours; showing children's toolbars over the grid keeps them in one place, as Navigation and Buttons already do.
- Make the grid resizable vertically — Grid: Add and remove rows of manual placement grids #84502. Handles on the grid's top and bottom edges add or remove rows, and dragging a block past the last row adds rows, so you can make room without going to the sidebar. Rows that have blocks in them can't be removed.
- Explore a full height option — no PR yet. A toolbar toggle that makes the canvas at least as tall as the screen, adding rows of the same size rather than stretching them, so a section can fill the first screen at any height.
Adding blocks
Ways to put a new block on the canvas at a useful place and size. This comes after the canvas basics because insertion depends on cell sizes, and before placing because a block has to exist before you move it.
- Click on a cell to insert a block — trunk already has cell inserters, and Grid: Draw blocks across cells in manual placement grids #84503 improves them. Grid: Select the grid on empty cells, draw drag tiles behind blocks, 32×32 Canvas #85277 currently removes them in favour of selecting the grid, which needs to be settled. Clicking where you want a block is the most direct way to add one.
- Drag across cells to create insertion space — Grid: Draw blocks across cells in manual placement grids #84503 (removed again in Grid: Select the grid on empty cells, draw drag tiles behind blocks, 32×32 Canvas #85277); see also Grid: drag to select cells to insert a block #64162. Drawing the area first places and sizes the block in one step, instead of inserting into one cell and resizing afterwards.
- Add a permanent block inserter in the grid toolbar only — no PR yet. There should be one reliable place to add blocks to a canvas that doesn't depend on hitting an empty cell, without adding an inserter to every child's toolbar. Trunk's Block Toolbar: Only show the parent selector plus when no allowed block splits #84645 currently hides the parent selector's plus for Group-based grids.
- Minimum size in cells for placeholders to fit — Grid: Draw blocks across cells in manual placement grids #84503. Cells can be smaller than a block's placeholder (Image needs about 300 by 300 pixels), so a new block grows until its placeholder fits, up to half the grid.
- Explore offering a short list of blocks in a canvas — no PR yet. The grid accepts any block today. Offering only Heading, Paragraph, Image, Buttons and Video would keep the canvas inserter simple and let each of those blocks be tuned for the canvas (fill, shapes), while accepting any block keeps more possible. The variation's allowed blocks can express either.
- Explore a simpler placeholder for media in a canvas — no PR yet. Empty images and videos show only the placeholder illustration, open the media library on double-click, and keep only Replace and Link in the toolbar, so an empty image looks like a frame on the canvas rather than a form, and doesn't need the 300 pixel minimum size.
Placing blocks
Moving, aligning and turning blocks once they are on the canvas. It builds on everything above: even cells to measure against, toolbars that stay out of the way, and blocks to move.
- Drag to place blocks inside the grid, relative to cells — Grid: Drag and resize blocks freely in manual grids, Shift to snap #85210, on top of the drag handling in Grid: Snap drags to cells in manual placement grids #84500. While dragging, the canvas shows its cells and highlights the ones the block will land in. Blocks land where they are dropped and keep the size they were resized to; the position is stored relative to the cells they cover, so CSS grid still does the layout and the front end needs no JavaScript. Today Grid: Snap drags to cells in manual placement grids #84500 snaps to cells and Grid: Drag and resize blocks freely in manual grids, Shift to snap #85210 adds free placement; which one is the default is the next item.
- Snap by default, place freely when you choose — Grid: Drag and resize blocks freely in manual grids, Shift to snap #85210, with its modifier reversed. Moves and resizes snap to whole cells, which keeps layouts aligned and most content stored as plain cells; holding a modifier places a block exactly where it is dropped. Touch has no modifier, so it needs another way to switch.
- Show alignment guides — Grid: Show alignment guides while dragging in manual grids #84501. Lines appear when a block's edges or centre line up with the grid or with another block, so things line up without counting cells. Also explore a dotted centre line while dragging, lines that turn solid when something lines up, and the distance in cells to the canvas edges shown along them.
- Explore snapping to guides — no PR yet. When placing freely, a block's edges and centre are pulled onto nearby guides (the canvas centre, other blocks' edges and centres) within a few pixels, so lining things up doesn't take exact pointer work.
- Explore moving text blocks by their body — no PR yet. Inside a canvas, the first click selects a block as an object: dragging moves it, the arrow keys move it (see Keyboard placement), and typing does nothing. Double-click or Enter starts editing the text, and Escape goes back to moving. Writing and laying out are different tasks, so the canvas uses the select-first model of design tools, building on block-editor's existing select (navigation) mode. This becomes the main way to move text blocks, and the drag handle a fallback.
- Explore keyboard placement — no PR yet. Arrow keys move the selected block by a cell, or by 1 and 10 pixels when placing freely, and the resize handles can be reached and moved with the keyboard. Free placement is pointer-only today, which Grid interactivity stack: review findings #85295 lists as a WCAG 2.5.7 problem.
- Explore duplicating by dragging with Option (Alt) — no PR yet. Holding Option while dragging leaves the block in place and drops a copy, as in most design tools.
- Explore moving, resizing, aligning and distributing several blocks — no PR yet. A multi-selection moves and resizes as one, and can be aligned by edges or centres, spaced evenly, or given equal widths; single blocks and selections can also be centred in the canvas. Today a multi-selection drag leaves the grid and goes back to block order.
- Explore grouping blocks without moving them — no PR yet. Grouping selected blocks keeps each where it was, and the group then moves as one; ungrouping puts them back exactly. Core's Group lays out what it wraps, so a canvas needs a group that keeps positions.
- Introduce the secondary grid toolbar for placing (drag, rotate, delete) — Grid: Show the canvas handles in a small toolbar, and add a Canvas block #84947, with the drag handle from Grid: Show block toolbars over manual grids and add a drag handle #84894 and the rotate handle from Grid: Rotate manual grid items from the canvas #84512. One small toolbar keeps the canvas handles together. With blocks moved by their body (above), the drag handle is a fallback rather than the main way to move text blocks. Also explore rotating a block by holding Cmd (Ctrl) while dragging a corner, without reaching for the handle.
- Explore turning on rotation for all blocks automatically — Add a rotation block support #84505 now makes rotation opt-in, as the review in Grid interactivity stack: review findings #85295 suggested: only blocks that declare
supports.rotationcan rotate (Group, Heading, Image and Video so far). This decides whether rotation stays per block, is offered on any block inside a canvas, or is offered everywhere. - Explore a stacking order (z-index) UI beyond List View order — no PR yet; see Grid: Add non drag-and-drop way to adjust stacking / z-index #63971 and Grid: Swap the position of grid items when they are re-arranged in the List View? #63974. Blocks can overlap on a canvas, and today the only way to change which one is on top is to reorder blocks, which also changes reading order. Dropping or moving a block also re-sorts it into reading order today, which would undo any stacking order, so that has to change first.
- Explore canvas commands in the block context menu — no PR yet; needs the block context menu. For each block type, the commands that apply to it: bring to front and send to back, centre, fill area (crop or show the whole image or video; size text to fill its box), lock aspect ratio, shape for images, fit text. On the canvas itself: add a block at the clicked point, turn snapping on or off, and reset responsive layouts.
Responsiveness
How a canvas behaves on smaller screens. It comes after placement because the right defaults depend on how blocks are positioned and sized.
- Optional stacking on mobile; by default, scale the grid and its contents — stacking is in Grid: Stack manual grids on mobile, and edit them from the stack #84509, scaling isn't started. A canvas laid out on desktop should look the same on a phone, only smaller, unless the author chooses to stack blocks in reading order; scaling only works if text scales too.
- Explore text that fills its box and scales with the grid — no PR yet. With fill turned on (the default for headings), the editor finds the largest size at which the text fits its box and saves it relative to the canvas width (
cqi), so the text shrinks with the grid, keeps its line breaks and never spills out of its cells, with no front-end JavaScript. With fill off, text keeps the theme's sizes. - Resize filled text when its box or text changes — no PR yet. Resizing a block, editing its text or changing its font recalculates the saved size, so filled text always fits the box it is in.
- Font sizes per viewport for text that doesn't fill its box — no PR yet. Text with fill turned off can overflow its cells on smaller screens, and the author fixes that by setting a smaller size for tablet or mobile. That needs font size in the per-viewport styles, as text alignment already has.
- Edit a canvas per viewport — partly in Grid: Stack manual grids on mobile, and edit them from the stack #84509 and trunk's per-viewport styles. Moving or resizing a block in the Tablet or Mobile view saves an override for that block only, and the other blocks keep following the scaled desktop layout. On a stacked grid, Grid: Stack manual grids on mobile, and edit them from the stack #84509 currently writes every block's mobile position on the first edit, which should be limited to the block being edited.
- Explore resetting responsive layouts — no PR yet. One action that removes a canvas's tablet and mobile overrides, so it goes back to the scaled desktop layout.
Discoverability
Ways for people to reach the canvas from content they already have. It comes last because converting a layout only makes sense once the canvas can do everything the converted layout needs.
- Transform certain blocks to a canvas (Columns, Groups, patterns) — Grid: Convert a container to a canvas, keeping its layout #85039. Most sections start from patterns built with Groups and Columns; converting keeps blocks where they were on screen instead of dropping each into the next free cell.
- Explore transforming automatically on drag — no PR yet. Dragging a block onto free space in a regular layout could turn that layout into a canvas, so people find it while doing what it's for.
Where today's PRs go in this order
- Add a rotation block support #84505, Preserve block's child layout attributes when it is transformed #85045, Layout: Keep box-sizing for fixed-width children of flex layouts #85373, Compose: Start useDropZone drags on the document's first dragover #85412: Foundation, already against trunk.
- Grid: Give manual placement grids same-size cells #84499 Equal cells: Canvas UX.
- Blocks: Fill fixed-size cells in manual placement grids #84504 Fill cells: Foundation.
- Grid: Snap drags to cells in manual placement grids #84500 Drag handling with cell snapping: Placing blocks, together with free placement from Grid: Drag and resize blocks freely in manual grids, Shift to snap #85210. Its copy of the drag fix goes away once Compose: Start useDropZone drags on the document's first dragover #85412 lands.
- Grid: Show alignment guides while dragging in manual grids #84501 Alignment guides: Placing blocks.
- Grid: Add and remove rows of manual placement grids #84502 Row handles: Canvas UX. Its resize handle fix: Foundation.
- Grid: Draw blocks across cells in manual placement grids #84503 Draw to insert, minimum size, placing blocks added without a cell, dragging blocks in from the inserter: Adding blocks. Its pattern style fix: Foundation.
- Grid: Stack manual grids on mobile, and edit them from the stack #84509 Stack on mobile, and editing a stacked grid: Responsiveness.
- Grid: Rotate manual grid items from the canvas #84512 Rotate handle: Placing blocks (secondary toolbar).
- Grid: Show block toolbars over manual grids and add a drag handle #84894 Child toolbars over the grid: Canvas UX. Drag handle: Placing blocks.
- Grid: Show the canvas handles in a small toolbar, and add a Canvas block #84947 Canvas variation: Canvas UX. Handles toolbar with Delete: Placing blocks.
- Grid: Drag and resize blocks freely in manual grids, Shift to snap #85210 Free placement, Shift to snap (to be reversed: snap by default, a modifier for free placement), keeping placements when the column count changes: Placing blocks.
- Grid: Select the grid on empty cells, draw drag tiles behind blocks, 32×32 Canvas #85277 Removing cell inserters and drag to insert, drag tiles behind blocks, 32 by 32 Canvas: Adding blocks and Canvas UX, to be reconciled with "Click on a cell to insert a block".
- Grid: Convert a container to a canvas, keeping its layout #85039 Convert to canvas: Discoverability.
Activity
draganescu commentedon Oct 26, 2026
On a second thought, after a discussion with @tellthemachines, we want to merge this issue into #81796 to make it easier to track.