WordPress 5.3 introduced Block Styles — a mechanism for registering named visual variants of any block without creating a separate block from scratch. When a style is registered for a block, a button for that style appears in the Styles panel of the Gutenberg sidebar. Clicking it adds a CSS class of the form is-style-{name} to the block’s wrapper element. For example, registering an outline style for the Button block adds is-style-outline to the button, and your theme’s CSS targets that class to produce a different visual. Core WordPress ships with a handful of default styles for Button, Image, and Separator — but theme developers can add any number of custom styles to any block, and can also unregister defaults they don’t want cluttering the editor sidebar. This is one of the most practical Gutenberg extension points for theme developers: no JavaScript bundling required, just PHP and CSS.
Problem: You want to offer editors a "Rounded" image variant and a "Ghost" button variant in the block editor, without building custom blocks from scratch or adding JavaScript.
Solution: Register custom block styles with register_block_style() in PHP, add CSS for the .is-style-{name} class in your theme stylesheet, and unregister default styles you don't need with unregister_block_style().
<?php
add_action( 'init', 'register_custom_block_styles' );
function register_custom_block_styles() {
// Register a "Rounded" style for the core Image block
register_block_style( 'core/image', [
'name' => 'rounded',
'label' => __( 'Rounded', 'textdomain' ),
] );
// Register a "Ghost" (outline) style for the core Button block
register_block_style( 'core/button', [
'name' => 'ghost',
'label' => __( 'Ghost', 'textdomain' ),
] );
// Register a style with inline CSS (useful for simple cases — larger themes should use a stylesheet)
register_block_style( 'core/quote', [
'name' => 'callout',
'label' => __( 'Callout Box', 'textdomain' ),
'inline_style' => '.wp-block-quote.is-style-callout {
background: #f0f4ff;
border-left: 4px solid #0066cc;
padding: 1.5rem 2rem;
}',
] );
// Unregister core Button styles that you don't want in this theme
unregister_block_style( 'core/button', 'outline' ); // removes core "Outline" style
unregister_block_style( 'core/image', 'default' ); // removes core "Default" (no-op)
}
The corresponding CSS for the registered styles (in your theme's style.css or via wp_enqueue_style):
/* Rounded image style */
.wp-block-image.is-style-rounded img {
border-radius: 50%;
}
/* Ghost button style — transparent background, colored border */
.wp-block-button.is-style-ghost .wp-block-button__link {
background: transparent;
border: 2px solid currentColor;
color: inherit;
}
.wp-block-button.is-style-ghost .wp-block-button__link:hover {
background: currentColor;
color: #fff;
}
NOTE: unregister_block_style() must be called on the init hook at priority 20 or later — after register_block_style() calls that register the defaults (which run at priority 10). Calling it earlier will fail silently. Also, block styles registered in PHP via register_block_style() apply to both the front end and the editor — but you must separately enqueue editor styles with add_theme_support( 'editor-styles' ) and add_editor_style() for the styles to appear correctly in the Gutenberg canvas.