Custom styling settings for custom elements could be so easy: use the block selector API to define the selector where the styles should apply and enable the applicable styles in the block.json. But unfortunately, it doesn’t work this way. If you need to apply styling to a custom element inside your block and not the surrounding element, you need to implement it manually. Luckily, Aki Hamano shared a how-to on GitHub.

Getting inline styles to work for your custom element

First, you need to declare supports for the styles you want to support. In my case, it was border, colors and shadows. Margins and paddings don’t have this problem, so there is nothing left to do here. At least one good message. 🙂

Declaring support for these styles looks the following in my block.json:

	"supports": {
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true,
			"__experimentalDefaultControls": {
				"radius": true,
				"color": true,
				"width": true,
				"style": true
			},
			"__experimentalSkipSerialization": true
		},
		"color": {
			"gradients": true
			"background": true,
			"gradients": true,
			"text": true,
			"__experimentalSkipSerialization": true
		},
		"shadow": {
			"__experimentalSkipSerialization": true
		},
	}
Code language: JSON / JSON with Comments (json)

Since border is currently defined as “experimental”, you need to flag it as such. The most important part here is that for everything you want to support styling a non-default element (which is the most outer surrounding element), you need to set __experimentalSkipSerialization to true in order to disable adding these styles to the default element.

Then, in your block’s edit function you need to grab those styling settings and manually apply them to your desired element:

import {
	useBlockProps,
	__experimentalUseBorderProps as useBorderProps,
	__experimentalGetShadowClassesAndStyles as useShadowProps,
	__experimentalUseColorProps as useColorProps,
} from '@wordpress/block-editor';
import clsx from 'clsx';

export default function Edit( props ) {
	const blockProps = useBlockProps();
	const borderProps = useBorderProps( props.attributes );
	const colorProps = useColorProps( props.attributes );
	const shadowProps = useShadowProps( props.attributes );
	return (
		<div { ...blockProps }>
			<span
				className={ clsx(
					borderProps.className,
					shadowProps.className,
					colorProps.className
				) }
				style={ {
					...borderProps.style,
					...colorProps.style,
					...shadowProps.style,
				} }
			/>
		</div>
	);
}
Code language: JavaScript (javascript)

These styling properties contain a className string (or undefined) and a style object with the styles to apply. In the example, I applied them to a custom span element.

For the save function, it works similar, but it’s a different selector:

import {
	useBlockProps,
	__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
	__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
	__experimentalGetShadowClassesAndStyles as getShadowClassesAndStyles,
} from '@wordpress/block-editor';
import clsx from 'clsx';

export default function Save( props ) {
	…
	const blockProps = useBlockProps().save();
	const borderProps = getBorderClassesAndStyles( props.attributes );
	const colorProps = getColorClassesAndStyles( props.attributes );
	const shadowProps = getShadowClassesAndStyles( props.attributes );
	…
	return (
		<div { ...blockProps }>
			<span
				className={ clsx(
					borderProps.className,
					colorProps.className,
					shadowProps.className
				) }
				style={ {
					...borderProps.style,
					...colorProps.style,
					...shadowProps.style,
				} }
			/>
		</div>
	);
}Code language: JavaScript (javascript)

Conclusion

I hope that the selector you can set in the block.json will sooner or later (better sooner) also be used for non-global styles, as it wouldn’t require one to write identical boilerplate code for every block you want to be able to customize a different way. Until then, at least you can achieve it the way shown before. And it’s definitely easier than adding a custom color option. 🤯

Reposts

Leave a Reply

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

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Learn more about webmentions)