The WordPress Gutenberg editor has come a long way since its inception in 2018 with the WordPress 5.0 release with the introduction of full site editing in WordPress 5.9. Yesterday (24th May 2020), WordPress 6.0 was released, but we are still missing key responsive features that make it a viable solution for building no-code websites in comparison to its competing page builders like Divi and Elementor being the most popular.

Thankfully, the block API has filters to add additional options to blocks which we will use here to show how we added additional options to solve these issues to a certain degree.

Responsive Column Selections

By default, you can set the number of columns you want to display on desktop devices with a toggle to stack them into a single column on mobile devices. For the most part, this may be good enough when displaying larger items but there are times when you might want 2 columns on mobile, but what about tablet devices?

So let’s say, for example, you have 4 columns of text on a desktop device and mobile stacks to a single column. Great! On a tablet device, however, your text now gets pretty squished up.

Now we will use the block JS API to create a filter to add additional options to the Gutenberg UI and output new classes which we can use to style our blocks. Following in Bootstraps’ footsteps, we used a 12-column grid to define the values of our column count.

import classnames from 'classnames';

function addColumnsAttribute(settings, name) {
	if (typeof settings.settings !== 'undefined') {
		if (name == 'core/columns') {
			settings.supports = Object.assign(settings.supports, {
				align: true,
				alignWide: true,
			});
		}
	}

	if (typeof settings.attributes !== 'undefined') {
		if (name == 'core/columns') {
			settings.attributes = Object.assign(settings.attributes, {
				columnsMobile: {
					type: 'integer',
					default: 1,
				},
				columnsTablet: {
					type: 'integer',
					default: 2,
				}
			});
		}
	}

	return settings;
}

function columnsApplyExtraStyle(extraProps, blockType, attributes) {
	const { columnsMobile, columnsTablet } = attributes;

	if (typeof columnsMobile !== 'undefined' && columnsMobile && typeof columnsTablet !== 'undefined' && columnsTablet) {
		extraProps.className = classnames(extraProps.className, 'mobile-columns-' + columnsMobile, 'tablet-columns-' + columnsTablet);
	}

	return extraProps;
}

const columnsAdvancedControls = wp.compose.createHigherOrderComponent((BlockEdit) => {
	return (props) => {
		const { Fragment } = wp.element;
		const { RangeControl } = wp.components;
		const { InspectorControls } = wp.blockEditor;
		const { attributes, setAttributes, isSelected } = props;

		return (
			
				
				{isSelected && (props.name == 'core/columns') &&
					
							 setAttributes({ columnsMobile: newval })}
								min={1}
								max={12}
							/>
							 setAttributes({ columnsTablet: newval })}
								min={1}
								max={12}
							/>
					
				}
			
		);
	};
}, 'columnsAdvancedControls');

wp.hooks.addFilter(
	'blocks.registerBlockType',
	'swwwift/columns-responsive-styles',
	addColumnsAttribute
);

wp.hooks.addFilter(
	'editor.BlockEdit',
	'swwwift/columns-advanced-controls',
	columnsAdvancedControls
);

wp.hooks.addFilter(
	'blocks.getSaveContent.extraProps',
	'swwwift/columns-apply-styles',
	columnsApplyExtraStyle
);




This will output additional CSS classes in our columns block:

.tablet-columns-{selectedNumber}

.mobile-columns-{selectedNumber}

We can then go on to style this. I primarily use SASS so I have a handy mixin to generate our CSS classes.

@for $i from 1 through 12 { /* Set to max 6 if you intend on keeping WordPress defaults */
    .wp-block-columns:not(.is-not-stacked-on-mobile).tablet-columns-#{$i} > .wp-block-column {
        @media (max-width: 1024px) {
            flex-basis: calc(100% / $i - var(--wp--style--block-gap, 2em)/2) !important;
        }
    }
}

@for $i from 1 through 12 { /* Set to max 6 if you intend on keeping WordPress defaults */
    .wp-block-columns:not(.is-not-stacked-on-mobile).mobile-columns-#{$i} > .wp-block-column {
        @media (max-width: 576px) {
            flex-basis: calc(100% / $i - var(--wp--style--block-gap, 2em)/2) !important;
        }
    }
}

There you have it. I would suggest if you are following Bootstrap or Tailwinds 12-column grid that you use these filters to change the max value on the default desktop columns as by default it only allows 6, or if you’d like to stick with 6 you can simply change the filters max attribute and use the SASS mixin to generate 6 variations rather than 12.

Hiding/Showing Blocks on Various Breakpoints

Another issue with Gutenberg is the inability to hide/show content at specific breakpoints. Now, generally, I would suggest not hiding major content as search engines may take issue with doing that but that’s for another post altogether. This functionality comes in handy when you have the following scenario:

You have a navigation menu that may be full width on desktop but you’d like to collapse that to a mobile menu and have it in line with your logo in the header.

By default, if you choose a full-width menu and have that switch to a button on mobile as is provided by Gutenberg, you’ll find the button is on its own line.

You could alleviate this issue by hiding your full-width menu on mobile and tablet devices and having another navigation block in line with your logo that’s hidden on desktop devices but shown on mobile and tablet devices.

To do this, we added a few more options to all blocks, which again apply a new class.

import classnames from 'classnames';

function addColumnsAttribute(settings, name) {
	if (typeof settings.settings !== 'undefined') {
		if (name == 'core/columns') {
			settings.supports = Object.assign(settings.supports, {
				align: true,
				alignWide: true,
			});
		}
	}

	if (typeof settings.attributes !== 'undefined') {
		if (name == 'core/columns') {
			settings.attributes = Object.assign(settings.attributes, {
				columnsMobile: {
					type: 'integer',
					default: 1,
				},
				columnsTablet: {
					type: 'integer',
					default: 2,
				}
			});
		}
	}

	return settings;
}

function columnsApplyExtraStyle(extraProps, blockType, attributes) {
	const { columnsMobile, columnsTablet } = attributes;

	if (typeof columnsMobile !== 'undefined' && columnsMobile && typeof columnsTablet !== 'undefined' && columnsTablet) {
		extraProps.className = classnames(extraProps.className, 'mobile-columns-' + columnsMobile, 'tablet-columns-' + columnsTablet);
	}

	return extraProps;
}

const columnsAdvancedControls = wp.compose.createHigherOrderComponent((BlockEdit) => {
	return (props) => {
		const { Fragment } = wp.element;
		const { RangeControl } = wp.components;
		const { InspectorControls } = wp.blockEditor;
		const { attributes, setAttributes, isSelected } = props;

		return (
			
				
				{isSelected && (props.name == 'core/columns') &&
					
							 setAttributes({ columnsMobile: newval })}
								min={1}
								max={12}
							/>
							 setAttributes({ columnsTablet: newval })}
								min={1}
								max={12}
							/>
					
				}
			
		);
	};
}, 'columnsAdvancedControls');

wp.hooks.addFilter(
	'blocks.registerBlockType',
	'swwwift/columns-responsive-styles',
	addColumnsAttribute
);

wp.hooks.addFilter(
	'editor.BlockEdit',
	'swwwift/columns-advanced-controls',
	columnsAdvancedControls
);

wp.hooks.addFilter(
	'blocks.getSaveContent.extraProps',
	'swwwift/columns-apply-styles',
	columnsApplyExtraStyle
);

This will create your new options.

Couple this with the following CSS:

.hide-mobile {
    @media (max-width: 576px) {
        display: none !important;
    }
}

.hide-tablet {
    @media (min-width: 576px) and (max-width: 767px) {
        display: none !important;
    }
}

.hide-desktop {
    @media (min-width: 768px) {
        display: none !important;
    }
}

You now have blocks you can hide and show at different breakpoints!

Gutenberg Responsiveness Round-Up

So with these snippets of code, we created additional block options on pre-existing blocks to cater for a few responsive options Gutenberg doesn’t have by default. These should help you create responsive websites using Gutenberg by allowing you to be a little more granular in the specific blocks and also allowing your clients to have a little more flexibility in the responsive elements when building landing pages. Of course, you could just use CSS to overcome these but being able to apply these options on a per-block basis is a lot easier.