Precision layout with the Columns block
UpdatedPredefined layouts in the Columns block have been around for a long time now, first shipped in the Gutenberg plugin back in June 2019. This genuinely helpful feature is a prime example of how the block editor can improve user experience when composing content in a CMS like WordPress: potentially dull and technically challenging decision-making for the user is solved by a visual prompt and a single click. Unfortunately, some of these layouts are not precisely defined for the front-end.
Here, I’ll be demonstrating a solution to achieve more intentional column layout patterns, using the Block Variations API available since WordPress 5.4. This approach will allow you to add predefined patterns to the Columns block, specific to your project requirements.
The Columns block layout picker
The default patterns offered for the Columns block are common, highly reusable container types for page content. Three of the current offered options are layouts with irregular column widths:
- 70/30
- 30/70
- 25/50/25
These labels roughly correspond to container ratios of 2:1, 1:2, and 1:2:1, respectively.
Building a layout system to account for multiple possible configurations of sibling and nested content is prone to alignment errors, even when taking a defensive approach to CSS. If you’re anything like me, you appreciate having a reference grid as an aid to visually reveal errors that can easily slip into a build.
For example, choosing the 70/30
pattern results in a column layout that feels off when compared against a reference grid:
Primary pain points to address
- Layout pattern has inline styles applied
- Block stylesheet applies an arbitrary margin
- Pattern label is not representative of actual outcome
Layout pattern has inline styles applied
While the label says 70/30, the style declarations flex-basis: 66.66%
and flex-basis: 33.33%
are automatically applied inline to the wide and slim columns, respectively.
Block stylesheet applies an arbitrary margin
margin-left: 32px
is applied to each .wp-block-column
, excluding the first instance. This presumes you’re not already opting to dequeue the stylesheet shipped with the block editor for front-end display.
Pattern label is not descriptive of end result
70/30 simply doesn’t match the actual values applied to each column width.
The goal
Ultimately, the columns are not aligned to the visual grid I’m using. Here’s the ideal outcome in this instance:
Setting up a custom columns variation
Unregister the default pattern
First, let’s unregister the default 70/30 pattern before adding our own custom one:
A simple way to find a block variation’s registered name (and an excuse to go digging in the latest version of the block editor) is in the Gutenberg plugin repository. For this example, the name can be sourced from gutenberg/packages/block-library/src/columns/variations.js.
Register a custom pattern
It’s a case of simple configuration from here:
A breakdown of what’s happening here:
- The Block Variations API is called via the function
registerBlockVariation
. - Two parameters are required: the name of the block the variation applies to—
core/columns
—followed by a settings object - name is a unique name for the variation
- title is the label displayed in the editor UI
- icon is a graphic representative of the variation displayed in the editor UI
- innerBlocks defines the composition of the variation
- A scope of '
block
' ensures the variation only appears in the Columns block layout picker
A unique CSS class has also been added to each column via the settings object for each core/column
block used.
Set up a custom icon
In this example I’m creating a variation with a suitable icon already available but this won’t always be the case. Adding a custom icon can be achieved as follows:
A new block variation
That’s it! The resulting markup for this example looks like this:
At this point the block variation appears as an option in the Columns block layout picker and is ready to receive CSS specific to your project.
All together now
Avoiding wp.domReady()
wp.domReady
appears to have been broken since the end of 2020. The above snippet has been updated to use window.addEventListener('load', function () {}
.
Some context for doing this
It’s important to stress this isn’t some kind of futile attempt to achieve pixel perfection. This is purely about ensuring predictable and intentional container structures.
The issue described here is also likely not considered to be an issue at all by anyone working from a CMS-first perspective. Following along with the Gutenberg project, it’s often felt to me as though conversations there consider all content design to be solved prior to actual content being involved. This perspective may help with understanding how some of the more opinionated presentation rules have made their way into the stylesheet shipped with the block editor.