Introduction
By day 96 of any WordPress development journey, you've likely built custom blocks and wrestled with how to let editors use them flexibly without creating dozens of separate block types. Block variations and styles: a practical WordPress guide offers a mature solution that balances editorial power with design consistency. This approach keeps your block library clean while giving your content team the presets and visual options they need to work efficiently.
We've seen this pattern work across e-commerce product pages, CRM dashboards, and SaaS onboarding flows. The key is understanding when to reach for registerBlockVariation versus registerBlockStyle, and knowing which options to hide from your editors to maintain brand integrity.
Understanding block variations with registerBlockVariation
Block variations let you create preconfigured instances of an existing block. Think of them as blueprints: an editor picks a variation, and WordPress populates the block with specific attributes, inner blocks, or default content. This is more powerful than it sounds.
The registerBlockVariation function accepts a block name and a configuration object. Each variation can set default attributes, define which attributes to expose in the UI, and even insert inner content. A concrete example: you have a custom "Card" block used across your marketing site. Rather than asking editors to configure alignment, background color, and padding each time, you create variations for "Feature Card," "Testimonial Card," and "Call-to-Action Card."
register_block_type( 'myapp/card', array(
'attributes' => array(
'backgroundColor' => array(
'type' => 'string',
'default' => '#ffffff',
),
'padding' => array(
'type' => 'string',
'default' => '16px',
),
'borderRadius' => array(
'type' => 'string',
'default' => '4px',
),
'align' => array(
'type' => 'string',
'default' => 'center',
),
),
) );Then register variations in JavaScript (typically in your block's registration script):
wp.blocks.registerBlockVariation( 'myapp/card', {
name: 'feature-card',
title: 'Feature Card',
description: 'A card highlighting product features',
attributes: {
backgroundColor: '#f5f5f5',
padding: '24px',
borderRadius: '8px',
align: 'center',
},
scope: [ 'inserter' ],
} );
wp.blocks.registerBlockVariation( 'myapp/card', {
name: 'testimonial-card',
title: 'Testimonial Card',
description: 'Display customer testimonials',
attributes: {
backgroundColor: '#ffffff',
padding: '20px',
borderRadius: '0px',
align: 'left',
},
scope: [ 'inserter' ],
} );When an editor clicks "Insert Block," they see these variations as distinct options rather than a generic "Card" block. They select "Feature Card," and the block appears with your predefined styling. This reduces friction and ensures consistency across the site.
Variations can also include inner blocks. If your card always needs a heading and paragraph, you can pre-populate those:
wp.blocks.registerBlockVariation( 'myapp/card', {
name: 'feature-card-with-content',
title: 'Feature Card (with content)',
description: 'A styled card with placeholder content',
attributes: {
backgroundColor: '#f5f5f5',
},
innerBlocks: [
[ 'core/heading', { content: 'Feature Name', level: 3 } ],
[ 'core/paragraph', { content: 'Add your feature description here.' } ],
],
scope: [ 'inserter' ],
} );This approach shines in larger organizations where design systems matter. Product teams can define variations upfront, and content editors simply choose from approved templates.
Adding visual options with registerBlockStyle
Block styles are different from variations. A style is a visual theme applied to an existing block instance; it doesn't change the block's structure or attributes. Use registerBlockStyle when you want editors to pick from predefined CSS class names without touching the block's configuration.
Imagine your "Button" block. The default appearance works fine, but your brand guidelines call for three visual styles: primary, secondary, and outline. Rather than creating three separate button blocks, register three styles:
wp.blocks.registerBlockStyle( 'core/button', {
name: 'primary',
label: 'Primary',
} );
wp.blocks.registerBlockStyle( 'core/button', {
name: 'secondary',
label: 'Secondary',
} );
wp.blocks.registerBlockStyle( 'core/button', {
name: 'outline',
label: 'Outline',
} );WordPress applies a class to the block's wrapper element: .is-style-primary, .is-style-secondary, or .is-style-outline. In your theme's CSS, you define those classes:
.wp-block-button.is-style-primary .wp-block-button__link {
background-color: #0073aa;
color: #ffffff;
border: none;
}
.wp-block-button.is-style-secondary .wp-block-button__link {
background-color: #e0e0e0;
color: #333333;
border: 1px solid #999999;
}
.wp-block-button.is-style-outline .wp-block-button__link {
background-color: transparent;
color: #0073aa;
border: 2px solid #0073aa;
}An editor inserts a button, types the text, sets the link, then selects "Secondary" from the style dropdown in the inspector. The button instantly updates to match your secondary brand style. No block duplication, no confusion about which button block to use.
Styles work well for variations in tone, size, or color within a single block concept. They're lightweight and maintainable. When you need to change all secondary buttons sitewide, you edit one CSS class.
Hiding variations and styles you don't need
WordPress ships with many blocks and styles by default. Your brand may not use all of them. Hiding unnecessary variations keeps your editor experience clean and reduces decision fatigue.
To unregister a variation, use wp.blocks.unregisterBlockVariation:
wp.blocks.unregisterBlockVariation( 'core/button', 'outline' );
wp.blocks.unregisterBlockVariation( 'core/button', 'fill' );This removes the "Outline" and "Fill" variations from the button inserter. Your editorial team only sees the variations you've intentionally kept or created.
Similarly, hide default block styles with wp.blocks.unregisterBlockStyle:
wp.blocks.unregisterBlockStyle( 'core/separator', 'dots' );
wp.blocks.unregisterBlockStyle( 'core/separator', 'wide' );We've found this practice essential in mature WordPress installations. When you curate the block library, editors make faster decisions and your frontend stays on-brand. It's especially valuable for e-commerce and SaaS where design consistency affects user trust.
Perform these unregistrations in a custom JavaScript module, enqueued in the editor:
add_action( 'enqueue_block_editor_assets', function() {
wp_enqueue_script(
'myapp-editor-config',
get_template_directory_uri() . '/assets/editor-config.js',
array( 'wp-blocks' ),
filemtime( get_template_directory() . '/assets/editor-config.js' )
);
} );In editor-config.js, unregister variations and styles when the editor initializes. This happens early enough that editors never see the unwanted options.
Block variations and styles for design systems
Design systems benefit tremendously from this approach. A design system codifies your brand's visual language: spacing, typography, color, and interaction patterns. Variations and styles let you encode those rules directly into WordPress.
Consider a typical e-commerce flow. Your design system specifies a "Card" component with four approved variants: product, category, promotion, and related-item. Each has specific padding, border, shadow, and content layout. Instead of asking developers to build four separate blocks, you register one Card block with four variations:
const cardVariants = [
{
name: 'product',
title: 'Product Card',
attributes: { variant: 'product', padding: '16px' },
},
{
name: 'category',
title: 'Category Card',
attributes: { variant: 'category', padding: '20px' },
},
{
name: 'promotion',
title: 'Promotion Card',
attributes: { variant: 'promotion', padding: '24px' },
},
{
name: 'related-item',
title: 'Related Item Card',
attributes: { variant: 'related-item', padding: '12px' },
},
];
cardVariants.forEach( ( variant ) => {
wp.blocks.registerBlockVariation( 'myapp/card', {
name: variant.name,
title: variant.title,
attributes: variant.attributes,
scope: [ 'inserter' ],
} );
} );Your design team owns the CSS that implements each variant. Your content team never worries about spacing or alignment; they pick the right card type and focus on content. Developers modify behavior in one place. This scales well across teams and time.
We've applied this pattern in travel booking flows, ride-hailing dashboards, and SaaS dashboards. The pattern holds: variations and styles let teams collaborate without friction, and design remains coherent as the site grows.
Common mistakes
- Confusing variations with styles. Variations change block structure and attributes; styles only change CSS. If you need different inner blocks or data handling, use variations. If it's purely visual, use styles.
- Creating too many variations. If you have more than five variations for a single block, reconsider. You may be overcomplicating the design. Sometimes separate blocks are clearer.
- Forgetting to unregister defaults. WordPress includes many default styles and variations. If you don't hide them, editors see clutter. Always audit and remove what you don't support.
- Not scoping variations to the inserter. If you set
scope: [ 'inserter' ], variations appear as separate items in the block picker but also populate the transform menu when editing. Be intentional about scope. - Hardcoding CSS instead of using theme.json. Modern WordPress supports block styles in
theme.json. Use that for consistency and theme flexibility rather than inline editor styles.
Key takeaways
- Use
registerBlockVariationto create preconfigured block templates with specific attributes and inner blocks. Variations reduce editor decision-making and enforce consistency. - Use
registerBlockStylefor visual themes that don't change block structure. Styles are CSS-based and lightweight, ideal for brand color or layout tweaks. - Unregister default variations and styles to keep your editor clean. Hide options you don't support to avoid confusion and off-brand content.
- Variations and styles are foundational to WordPress design systems. They let you encode brand guidelines into the editor, so teams collaborate without friction.
- Audit your block library regularly. As your site grows, new variations and styles may accumulate. Keep the editor focused on your actual needs.






Comments
Loading comments…