Ari Stathopoulos

Web Developer, Accessibility & Sustainability evangelist, Human.

Using CSS Grid for Gutenberg Columns

29 October 2019

The Gutenberg editor allows you to create columns and each column can have its own width. By default all columns are the same width, but you can define if for example you want the to be 1/3 - 2/3 etc.

What Gutenberg Generates

The default HTML generated by the WordPress editor looks something like this:

<div class="wp-block-columns">
    <div class="wp-block-column" style="flex-basis:33.33%">
        <p>Column 1</p>
    </div>

    <div class="wp-block-column" style="flex-basis:66.66%">
        <p>Column 2</p>
    </div>
</div>

The accompanying styles relevant to what we want to do here:

.wp-block-columns {
    display: flex;
}

What it does is pretty clever and elegant(ish), but depending on what you’re working on it may not always be the best solution. If the theme you’re working on has a relatively simple layout then getting things to work properly is a piece of cake. However if you have a more complex layout then flex may not be the best choice, and the reason is padding. If columns don’t have a padding, then there will not be any space between columns. I’ve seen themes use padding, margins, for a while I even user this:

.wp-block-column {
    border-left: 0.5em solid transparent;
    border-right: 0.5em solid transparent;
}

The above code will add an extra 0.5em border on the left and right of your columns, therefore separating them and creating a “gap” between them. The problem however with solutions like that is that they add additional space on the left and right of all columns, therefore making the contents of your columns narrower and they don’t line up vertically with the rest of your content. If you can add a left margin on the .wp-block-columns element and just make it larger by 1em then you’re OK. But what if you can’t?
See, flex is OK, but in some cases using grid makes more sense. For columns the benefit of grid is the css-gap property.

Unfortunately I haven’t found a filter or anything like that that would allow me to change the egenerated markup. We’re a bit “trapped” by a limited system.
The only available alternative is to use JS to change things.

Here’s some code you can use:

function griddConvertColumnsToGridLayout() {

    // Get all column-wrappers.
	var griddColumns = document.querySelectorAll( '.wp-block-columns' );

    // Loop column-wrappers.
	griddColumns.forEach( function( columnsWrapper ) {
		var columns = columnsWrapper.childNodes,
			gridTemplateCols = [];

        // Loop columns.
		columns.forEach( function( column ) {
			if ( column.style.flexBasis ) {
				gridTemplateCols.push( 'minmax(300px, calc(' + column.style.flexBasis + ' - 0.5em))'  );
			} else {
				gridTemplateCols.push( 'minmax(300px, 1fr)' );
			}
		});

		columnsWrapper.style.display = 'grid';
		columnsWrapper.style.gridTemplateColumns = gridTemplateCols.join( ' ' );
		columnsWrapper.style.gridGap = 'calc(1em';
	});
}
griddConvertColumnsToGridLayout();

The above snippet (taken from the currently alpha version of the Gridd 2.0.0 theme) is vanilla JS and will convert your columns to use a grid layout.

Of course if you use that you’ll also have to take into account mobile visitors and make sure that columns collapse by adding some CSS:

@media screen and (min-width:600px) {
    .wp-block-columns {
        display: flex; /* block also works fine. */
    }
}

Comments

    No comments found for this article. Comments posted before 2019-09-15 are no longer available due to a system migration since I no longer use Disqus for comments.

    Join the discussion for this article on this ticket. Comments appear on this page instantly.