For a visual alternative to a Gutenberg block, use a block style variation: register a style slug, then define that slug under styles.blocks.{block}.variations in theme.json. WordPress adds the corresponding .is-style-{slug} class to the block wrapper. Use a JavaScript block variation instead when the change affects insertion, attributes, or the block’s inner structure.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
What a Gutenberg block style variation actually is
A block style variation is a presentation option attached to an existing block. It does not create a new block type and it does not change the block’s content model. When a user selects the style in the editor, WordPress adds a class to the block’s wrapping element. A style named boxed therefore produces a selector such as .is-style-boxed.
As an Amazon Associate I earn from qualifying purchases.
That class is the connection between registration, the editor’s Styles UI, generated styles from theme.json, and any additional CSS you enqueue. The style name is a machine-facing slug; the label shown in the editor is a separate, translatable value.
This distinction matters because “variation” is used for two related but different Gutenberg features. A block style variation is primarily visual. A JavaScript block variation changes how a block is inserted or configured. Styling the wrong feature is a common reason that a perfectly valid theme.json rule appears to do nothing.
Block style or JavaScript block variation?
| Requirement | Use a block style variation | Use a JavaScript block variation |
|---|---|---|
| Change colors, borders, spacing, shadows, typography, or other presentation settings | Yes. Express the design with theme.json and, where necessary, CSS. |
Usually unnecessary. |
| Insert the block with different attributes already selected | No. | Yes. |
| Provide a different InnerBlocks template | No. | Yes. |
| Change the block’s setup or editing behavior | No. | Yes. |
| Offer several visual treatments for the same block | Yes. Each treatment gets its own registered style slug. | Only if insertion behavior also differs. |
WordPress describes block styles as CSS classes added to the wrapper, while JavaScript variations are intended for blocks that should be set up differently when inserted. Keeping those jobs separate makes the editor UI predictable and avoids trying to solve structural problems with selectors.
Requirements and version differences
- Registered style: The slug must already be registered by the block itself or by your theme/plugin. WordPress ignores
theme.jsonstyles for unregistered style variations. - WordPress 6.2 or newer: Core block style variations can be customized through
theme.jsonand the Styles interface from WordPress 6.2 onward. - WordPress 6.6 and theme.json version 3: Version 3 adds variation-level custom CSS, nested element and nested block styling, responsive rules, and supported pseudo-selectors. Older WordPress versions need the Gutenberg plugin for these version-3 capabilities.
- A block theme or a compatible classic-theme setup: The exact loading path for
theme.jsonand CSS depends on the theme architecture. Test both the editor and the public page.
Set the schema URL to https://schemas.wp.org/trunk/theme.json in your editor if you want validation and completion while authoring the file. The schema helps catch malformed properties, but it cannot register a style that does not exist.
Free tools Windows power users keep installed
One-click scans. No signup required.
Style an existing core variation with theme.json
Use this route when the block already exposes the style you want. The key is the block’s registered style slug, not the label visible in the editor. For the core Button block’s built-in outline style, the relevant path is styles.blocks.core/button.variations.outline.
- Open the active theme’s
theme.json. - Confirm the file declares
"version": 3if you need version-3 features. Version 2 is sufficient for the basic variation path. - Under
styles, openblocks, then the block name, thenvariations. - Add a property whose key exactly matches the registered style slug.
- Save the file, reload the editor, insert the block, and choose the style from the block’s Styles panel.
{
"version": 3,
"styles": {
"blocks": {
"core/button": {
"variations": {
"outline": {
"border": {
"color": "currentColor",
"style": "solid",
"width": "3px"
},
"shadow": "var:preset|shadow|outlined",
"spacing": {
"padding": {
"top": "0.5rem",
"bottom": "0.5rem",
"left": "1.5rem",
"right": "1.5rem"
}
}
}
}
}
}
}
}
The values in this example use supported design tools: a current-color border, a preset shadow, and explicit padding. If your theme defines spacing or shadow presets, reference them with the corresponding var:preset|... token instead of hard-coding a duplicate value.
Rank #2
How to find the correct slug
Look at the block’s registration data or the source that registers its styles. The slug is the value assigned to name, such as outline or boxed. The human-readable label can be “Outline” or “Boxed”; using that label as the theme.json key will not work if the slug differs.
Register your own style in PHP
If the style is not already registered, add it during the init hook. A theme or plugin can register one style for a single block or pass an array of block names when the same style is appropriate for several blocks.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →<?php
add_action( 'init', 'mytheme_register_block_styles' );
function mytheme_register_block_styles() {
register_block_style( 'core/pullquote', array(
'name' => 'boxed',
'label' => __( 'Boxed', 'mytheme' ),
) );
}
The function signature is register_block_style( string|string[] $block_name, array $style_properties ): bool. Besides name and label, the registration API accepts inline_style, style_handle, and style_data. Use a unique, lowercase slug that will remain stable after content has been published; changing it later changes the class stored on existing blocks.
Once the registration exists, style the same slug in theme.json. The following example gives the new Pullquote style a six-pixel border and preset-based padding:
Rank #3
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"styles": {
"blocks": {
"core/pullquote": {
"variations": {
"boxed": {
"border": {
"color": "currentColor",
"style": "solid",
"width": "6px"
},
"spacing": {
"padding": {
"top": "var:preset|spacing|60",
"bottom": "var:preset|spacing|60",
"left": "var:preset|spacing|60",
"right": "var:preset|spacing|60"
}
}
}
}
}
}
}
}
After saving both files, clear any page or object cache, open a fresh editor session, and verify that “Boxed” appears in the Pullquote Styles panel. If it does not appear, the problem is registration or loading, not the border declaration.
Use CSS for design details theme.json cannot express
Block styles are implemented as wrapper classes, so the basic selector is always .is-style-{name}. Keep the PHP registration even when CSS supplies the visual treatment; registration is what exposes the option in the editor and gives WordPress a stable style identity.
Recommended Free Tools
.wp-block-pullquote.is-style-boxed {
position: relative;
isolation: isolate;
}
.wp-block-pullquote.is-style-boxed::before {
content: '';
position: absolute;
inset: 0.75rem;
border: 1px solid currentColor;
pointer-events: none;
}
Use the block’s full class together with the style class when possible. A selector such as .is-style-boxed alone can unintentionally affect unrelated blocks that happen to reuse the same style slug. CSS is the appropriate layer for pseudo-elements, complex combinators, decorative backgrounds, and other rules not represented by supported theme.json settings.
If you attach a stylesheet through register_block_style(), understand how the selected style_handle is loaded in the editor and on the front end. A style that appears in the editor but disappears on the public page usually indicates that the stylesheet was not enqueued for the front end or that its handle is not available in that context. Theme-generated styles from theme.json avoid much of this bookkeeping.
Rank #4
Use theme.json version 3 for nested content
Version 3 makes a style variation useful when the block contains links, metadata, or nested blocks that need coordinated treatment. Instead of writing a broad global selector, scope the rule to the variation’s elements or blocks object.
{
"version": 3,
"styles": {
"blocks": {
"core/post-terms": {
"variations": {
"with-divider": {
"elements": {
"link": {
"color": {
"text": "#1f2937"
},
"typography": {
"textDecoration": "none"
}
}
},
"css": "& a + a { margin-left: 0.5rem; }"
}
}
}
}
}
}
Here, the link settings apply only inside the with-divider variation, and the custom CSS targets adjacent links within that same scope. Version-3 support also covers nested block rules, responsive declarations, and supported pseudo-selectors. Confirm the minimum WordPress version before distributing a theme that relies on these properties.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitchesShare one named style across several block types
When the same design language should be available on multiple block types, create a block-style variation partial in the theme’s /styles directory. Its blockTypes array identifies the blocks to which the partial applies. This is useful for a consistent “boxed,” “soft,” or “accent” treatment that should look related on headings, pullquotes, and other supported blocks.
Do not use a shared partial merely to avoid writing a few lines of CSS. A shared style still needs a coherent visual meaning for every listed block, and each target must support the settings you place in the partial. Test every block type in both the editor and the front end.
Best Value
A reliable implementation workflow
- Define the job. Decide whether the request is visual or structural. If inserting the block should set attributes or an InnerBlocks template, start with a JavaScript variation instead of a style.
- Choose a permanent slug. Use a unique slug such as
boxedorwith-divider. Treat it as content data because WordPress stores the resulting class in post content. - Register the style. Use an existing core slug or register a custom one with
register_block_style(). Confirm the label is translated and the registration runs oninit. - Put supported settings in theme.json. Add the rule under the exact block name and variation slug. Prefer theme presets for shared spacing, color, typography, and shadow values.
- Add narrowly scoped CSS. Use the block class plus
.is-style-{slug}for unsupported effects. Keep decorative rules and pseudo-elements out of broad global selectors. - Test registration first. Before tuning visual values, verify that the style appears in the Styles panel and that selecting it adds the expected class in the editor markup.
- Test both outputs. Check the editor canvas, a saved post, and the public page at the responsive widths your theme supports. A style can be present in one context and missing in another if its stylesheet is not loaded.
- Validate on the oldest supported WordPress version. If the theme uses version-3 variation CSS or nested rules, ensure that the target installation supports WordPress 6.6 or the required Gutenberg plugin version.
Why a variation style appears to do nothing
| Symptom | Likely cause | Fix |
|---|---|---|
| The style is absent from the Styles panel | The slug was never registered, registration did not run, or the block name is wrong. | Check the block’s registration or the register_block_style() call, confirm it runs on init, and use the exact namespace/block name. |
| The style is visible but theme.json values have no effect | The variation key does not match the registered slug, or the rule is nested at the wrong path. | Use styles.blocks.{block}.variations.{slug} and copy the machine slug, not the translated label. |
| The rule works in the editor but not on the front end | The stylesheet containing the CSS was not loaded publicly, or a style handle is unavailable in that context. | Inspect the public page, enqueue the stylesheet correctly, or move supported properties into theme.json so WordPress generates them. |
| Nested links or child blocks remain unchanged | A global selector targets the wrong element. | Use version-3 elements or blocks scopes where supported, or write a selector that starts with the variation’s wrapper class. |
| Version-3 CSS is ignored | The site runs an older WordPress or an older theme.json version. |
Use WordPress 6.6 or newer for the documented version-3 capabilities, or provide a compatible fallback. |
| A JavaScript variation is being styled as if it were a style variation | The two APIs were conflated. | Decide whether the feature changes presentation or insertion behavior, then implement it with the matching API. |
How to inspect the result in the browser
Insert the block, select the style, save the post, and inspect the rendered wrapper. You should see the block’s normal class plus the style class, for example wp-block-pullquote is-style-boxed. If the class is missing, no amount of CSS adjustment will help; fix registration or the selected style first.
If the class exists but the declaration is crossed out, inspect specificity and source order. A theme, plugin, or block stylesheet may be overriding the rule. Increase specificity narrowly by including the block class, or adjust the loading order rather than appending an unrestricted !important rule.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11When the declaration is present but the visual result is unchanged, check whether the property is supported for that block and whether a child element owns the visible styling. For example, changing a wrapper’s text color will not necessarily override a link color declared on the link itself; use the variation’s element scope or a properly targeted selector.
Design and maintenance decisions
Keep slugs stable
Labels can be translated or revised without affecting saved content. Slugs should be treated as an API: changing boxed to card can leave older posts with a class that no longer has styles. If a rename is unavoidable, retain the old selector as a compatibility alias while exposing the new label for future use.
Prefer settings for portable themes
Border, spacing, color, shadow, and typography settings expressed through theme.json integrate with presets and the Styles UI. They are easier for users to override and less dependent on stylesheet load order. Reserve custom CSS for effects that the settings model cannot represent.
Keep structural changes out of CSS
CSS can hide, reorder, or decorate content, but it cannot provide a dependable insertion template or set block attributes at creation time. If users need a different starting layout, use a JavaScript block variation and let the style variation handle the appearance separately.
Practical checklist
- The requested change is visual rather than a new insertion template.
- The style slug is registered and unique.
- The
theme.jsonpath uses the exact block name and slug. - Supported design settings are in
theme.json. - Custom selectors begin with the relevant block and
.is-style-{slug}class. - Version-3 features are used only on supported WordPress installations.
- The style is tested in the editor, in saved markup, and on the public page.
- Any front-end stylesheet is enqueued in the context where the block renders.
The dependable pattern is therefore: register the style, style its slug under the block’s variations object, and use the generated .is-style-{slug} wrapper for anything the settings model cannot express. When the requirement changes how the block is inserted or structured, switch to a JavaScript block variation rather than forcing a visual API to perform a structural job.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

