WordPress.org

WordPress Developer Blog

Adding and using grid support in WordPress themes

Adding and using grid support in WordPress themes

Have you ever been building a website with modern WordPress and wished that WordPress had a grid layout type that you could use? 

Sometimes you just need some equal-width columns that flow naturally into rows based on rules that you decide. Maybe something like this “character card” pattern I recently built entirely in the Block Editor:

There are existing methods of achieving that effect with the Row and Columns blocks, but they are not ideal. What you really need for this scenario is a CSS grid layout.

Well, I have good news for you! Grid layout support first landed in Gutenberg 15.5 and officially shipped with WordPress 6.3. 

It’s just kind of hidden by default—we won’t let that get in our way now, will we?

Once I learned how to enable grid support, it made my life as a theme designer so much simpler. In this post, I’ll share how to obtain this superpower so you can make layouts like this pricing table pattern with much less work:

Aside from a couple of custom block styles for the list markers, that design was built on top of WordPress’s existing grid support. Straight from the Editor.

How to enable grid support

First, let me define what I mean by “grid support.” Specifically, I am referring to enabling CSS grid layout support for the built-in Group block. Like the flexbox-based Row and Stack variations, you will learn how to register a Grid variation.

The easiest way to do this is to install the Gutenberg plugin. Then, head over to the Gutenberg > Experiments screen in your WordPress admin and turn on the Grid variation for Group block option.

That’s a good way to simply test the variation, but it’s not much use when distributing your theme to the public or for use on a production site. Plus, it’d make this tutorial pretty useless, right?

Instead, we’re going to build a custom Grid variation of our own.

If you’re building a custom block, you can use grid layout support by following the instructions in the layout updates dev note for WordPress 6.3.

Loading a JavaScript file in the editor

First, create an empty block-variations.js file in your theme’s assets/js folder. You can use whatever preferred naming convention you want—just be sure to update any references to the file in your code.

Now load this file with the standard wp_enqueue_script() function on the enqueue_block_editor_assets hook by adding this code to your functions.php file:

add_action( 'enqueue_block_editor_assets', 'themeslug_editor_assets' );

function themeslug_editor_assets() {
	wp_enqueue_script(
		'themeslug-block-variations',
		get_parent_theme_file_uri( 'assets/js/block-variations.js' ),
		array( 
			'wp-blocks', 
			'wp-dom-ready',
			'wp-i18n'
		),
		wp_get_theme()->get( 'Version' ),
		true
	);
} 

Take note of the dependencies array that lists a few WordPress scripts. You’ll use each of them in your JavaScript code in the next step:

  • wp-blocks: This package includes the variation-related functions needed.
  • wp-dom-ready: You’ll use this to make sure your code is only executed when the DOM is loaded.
  • wp-i18n: This package is needed to get the internationalization functions.

Building a Grid variation

For this step, it’s useful—but not required—to know how to build block variations already. Honestly, it’s just a couple of short snippets of code, so you can always just copy and paste them.

Open your assets/js/block-variations.js file. The first thing to do is assign a few constants with functions pulled from the dependencies:

const { getBlockVariations, registerBlockVariation } = wp.blocks;
const { __ } = wp.i18n;
const domReady = wp.domReady;

One of the things we want to avoid when registering this specific variation is a conflict with the Grid variation currently in the Gutenberg plugin or WordPress in the future. To avoid any potential issues there, you’ll do two things, in this order:

  • Wait until the DOM is ready before running your code.
  • Check if the variation already exists by searching for it in the registered variations array.

These two things ensure that both WordPress and Gutenberg get the first shot at registering the variation and that your code will be forward compatible.

With those checks in place, you only need to call the standard registerBlockVariation() function.

Add this code to your assets/js/block-variations.js file:

domReady(() => {
	const variations = getBlockVariations('core/group');

	if (! variations.some(variation => 'group-grid' === variation.name)) {
		registerBlockVariation('core/group', {
			name: 'group-grid',
			title: __('Grid', 'themeslug'),
			icon: 'grid-view',
			description: __('Arrange blocks in a grid.', 'themeslug'),
			attributes: {
				layout: {
					type: 'grid' 
				}
			},
			scope: [ 'block', 'inserter', 'transform' ],
			isActive: (blockAttributes) =>
				blockAttributes.layout?.type === 'grid',
		});
	}
});

Now save your file and test it by going to the Post Editor and adding a new Group block. You should see a new Grid layout option:

Now we can get to the fun stuff.

Because we’re registering this variation from a theme, I showed how to do this in plain JavaScript with no extras. But I highly recommend following the instructions in the Theme Handbook for setting up a build process. You don’t need it for one-off things like this variation, but it’ll come in handy if you’re using a lot of JavaScript.

Bonus! You can also import the grid icon available in the @wordpress/icons package to use instead of the grid-view Dashicon used in the code above.

Using the Grid variation

Now that you’re all excited about building awesome stuff with the Grid variation, allow me to curb your enthusiasm just a tiny bit.

It’s important to understand that the current WordPress grid layout support is limited out of the box. CSS grid is a massive specification, and the Core implementation only uses grid-template-columns in one way at the moment.

Basically, you can create equal-width columns based on a minimum width that you define. Each column automatically fills out the available space and intrinsically flows to the next row when there is not enough room.

It’s a powerful feature to be sure, but it’s also only a hint of what’s possible with CSS grid.

Take a look at this example two-row, four-column team grid that I arranged in the editor:

Take note of these two things set in the UI:

  • The Minimum Column Width is set to 15rem. This value ensures that each column in the layout will naturally shrink and grow to fill out available space but will not go below the 15rem minimum.
  • The alignment option in the toolbar is set to Full Width. On a large enough screen, the grid could accommodate all eight of the columns. If you want to restrict that, you need to set a specific width.

If you’re interested in the CSS, WordPress will output something like this:

.wp-container-core-group-is-layout-0 {
	grid-template-columns: repeat(auto-fill, minmax(min(15rem, 100%), 1fr));
}

It’s a relatively simple implementation, but it covers a lot of use cases with minimal CSS overhead.

One of the great things about the Grid variation is the user experience feels so much more natural than other implementations. At the end of the day, it’s just a Group block, and you can make a grid of anything. Stick whatever blocks you want into it.

Try something like this layout that houses an Image and a Stack with a Quote and Gallery:

As I said earlier, some of this is possible with existing Core blocks, such as Columns. But I’ve found the experience of creating these types of layouts with the Grid variation much easier, requiring far fewer clicks around the editor.

It’s hard to convey just how much cleaner of an experience it is through text and screenshots alone. So you’ll just have to try it for yourself.

And, by the way, all of the examples I’ve shown break down on smaller screen sizes like tablets and mobile phones without issue.

Extending grid support

As I mentioned in the previous section, WordPress only supports a basic equal-width column implementation at the moment. While that may feel limiting to some, it’s an opportunity to explore what’s possible with CSS grid for others. I hope that you are in the latter group.

Let’s walk through an example that you can try without even enabling grid support for the Group block.

Did you know that WordPress already has support built in for its Post Template block? Here’s an example I built with the tools available in Core. I only had to add a custom block style to get the first post to stretch the full column width:

Want to try it for yourself? Drop this code into your functions.php to create a “Featured” style:

add_action( 'init', 'themslug_register_block_styles' );

function themeslug_register_block_styles() {
	register_block_style( 'core/post-template', [
		'name'  => 'featured',
		'label' => __( 'Featured', 'themeslug' ),
		'inline_style' => '.wp-block-post-template-is-layout-grid.is-style-featured  .wp-block-post:first-child {
			grid-column: 1 / -1;
		}'
	] );
}

In the Editor, select the Grid option for the Post Template block and your new Featured style. I’ll leave laying out the rest of the design to you. The goal is to show that you can manipulate the grid with something as basic to theme development as a block style.

Of course, you can take this to the next level and build custom controls in the UI, as described in the Beyond Block Styles series. Whatever you decide, have a bit of fun with it!

Props to @ndiego and @rmartinezduque for feedback and review on this post.

9 responses to “Adding and using grid support in WordPress themes”

  1. Phil Doneski Avatar

    This is huge! Love the fact that with every update Gutenberg is adding these amazing features.

  2. Rio Avatar

    Amazing…
    I love using Block Editor to make the website faster. How will this feature affect my existing grid layouts?

    1. Justin Tadlock Avatar

      It shouldn’t affect any existing grid implementations that you’ve built. This would be contained to the specific use of the Grid variation and not leak out to other elements.

  3. Steve Struemph Avatar
    Steve Struemph

    Woohoo!

  4. Rupesh Avatar

    This is great news!

  5. Kevin Avatar

    Can someone explain why the Gutenberg team can’t just give us a decent out-of-the-box grid builder? Nearly every page builder has done it! But, once again, the block editor team can only manage to give us some half-baked, VS Code-necessary implementation. It’s like they’re experts at snatching defeat from the jaws of victory.

    Is, “it’s gotta be really limited and super convoluted” the primary requirement of shipping a new feature?

    Real question.

    1. Justin Tadlock Avatar

      Hi Kevin, this is currently an early experimental feature and is not quite ready to put into the Core codebase. But we wanted to give folks a chance to begin testing it with the ultimate goal of improving the end product that does ship with WordPress.

      It sounds like you are increasingly frustrated with Gutenberg and might have a use case that is not being met. If so, it would be helpful for the team to know more about what you are trying to do. The best place to share your feedback on the roadmap would be on this tracking ticket for layout issues. There is also a more specific ticket for improving grid and sub-grid support.

      Please also keep in mind that the purpose of this blog is to help WordPress developers learn about the latest features in WordPress. We invite you to collaborate with us by communicating kindly and constructively, especially by focusing on the issues you are experiencing with the editor.

  6. Silas Köhler Avatar

    Isn’t the `grid` icon in the @wordpress/icons package and not in the @wordpress/scripts package?

    1. Justin Tadlock Avatar

      Yes, good catch! The link was pointing to the correct package, but the text was wrong. I’ve updated the post.

Leave a Reply

Your email address will not be published. Required fields are marked *