Skip to content

Grid canvas: Implementation overview #85505

Open

Description

@draganescu

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-sizing on 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: true on 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 removes rowCount. 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.

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.rotation can 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

Activity

  1. added
    [Type] OverviewComprehensive, high level view of an area of focus often with multiple tracking issues
    [Feature] LayoutLayout block support, its UI controls, and style output.
    on Oct 24, 2026
  2. draganescu commented on Oct 26, 2026

    @draganescu
    ContributorAuthor

    On a second thought, after a discussion with @tellthemachines, we want to merge this issue into #81796 to make it easier to track.

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

Metadata

Metadata

Labels

[Feature] LayoutLayout block support, its UI controls, and style output.[Type] OverviewComprehensive, high level view of an area of focus often with multiple tracking issues

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions