WordPress.org

WordPress Developer Blog

Customizing core block style variations via theme.json

With every release, the Global Styles feature in WordPress keeps letting you do more and more, faster and more easily. Since WordPress 6.2, you can set, change, and tweak core block style variations (block styles) in theme.json—or directly from the Styles interface in the Site Editor.

That means you can build themes with less CSS than ever.

Even creating and editing custom block styles from the Styles interface in the Site Editor may be on the slate for WordPress 6.3. But let’s focus on what’s possible today and not get too far ahead of ourselves just yet.

The theme.json code shown in this post refers to block styles as “variations” (short for “block style variations”), but this feature should not be confused with block variations or Global Styles variations. This is an unfortunate naming convention in WordPress. This post will refer to these as “block styles” to avoid confusion.

Customizing a core block style

Let’s start with an example of this built-in Button block style: Outline. It will look something like this, assuming you’re just about to design the buttons for your theme:

The core Outline style has its own distinctive design, sporting a 2px solid border, rounded corners, and a heavy dose of padding. But that’s not the look you’re after right now.

Suppose you wanted a thicker border, square corners, and tighter spacing. Maybe you’re even feeling whimsical and decide to throw in a fun box-shadow, as you see below:

Before WordPress 6.2, you would have needed to write some CSS, maybe in a block-specific stylesheet, to make the changes you want. 

As of 6.2, though, you can edit the style attributes for it in theme.json—the same place you’d change the Button block’s default styles.

This example theme.json code specifically targets the Outline style—with custom border, shadow, and spacing styles:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"styles": {
		"blocks": {
			"core/button": {
				"variations": {
					"outline": {
						"border": {
							"color": "var( --wp--preset--color--black )",
							"radius": "0",
							"style": "solid",
							"width": "3px"
						},
						"shadow": "var( --wp--preset--shadow--outlined )",
						"spacing": {
							"padding": {
								"top": "0.5rem",
								"bottom": "0.5rem",
								"left": "1.5rem",
								"right": "1.5rem"
							}
						}
					}
				}
			}
		}
	}
}

The outlined shadow preset is registered by WordPress and available to any theme. You can also use natural, deep, sharp, crisp, or a custom shadow preset.

For the most part, block styles support should let you keep more of your custom code in the theme.json file. While there are certainly different schools of thought on where styles should live, one compelling benefit to housing them in the standard theme.json file is user customizations.

The screenshot below confirms that the customizations you made to the Outline block style also appear in the Styles interface:

Your theme users can see where the style is coming from and make adjustments as needed. This benefit is lost when you put your style rules in a custom CSS file.

Available core block styles

Because this feature is available only for core block styles in WordPress 6.2, you are limited to customizing these blocks and their styles:

  • core/button : outline
  • core/image: rounded
  • core/quote: plain
  • core/site-logo: rounded
  • core/separator: wide, dots
  • core/social-links: logos-only, pill-shape
  • core/table: stripes
  • core/tag-cloud: outline

More to come

If you’re thinking this all feels limiting for you to use right now, there is good news. More is on the way! And block styles seem, finally, to be getting the attention they deserve.

For now, keep your eye on these two potential enhancements, as the WordPress 6.3 development cycle moves forward:

Custom CSS and element style support

One current downside to customizing block styles in theme.json is that you can only add the design tools that the block supports. 

Generally that’s typography, color, border, shadow, and spacing. Anything else, and you’re back in a custom stylesheet—at least until this enhancement for CSS lands in WordPress. That pull request also adds support for styling nested elements.

Even so, you can still take block styles pretty far with the core design tools—just don’t expect them to handle every scenario yet.

Custom block style support

To round out the feature, WordPress needs to support custom block styles. Here’s an open ticket proposing support, but it needs a patch. If interested folks can merge a pull request for this, you’ll be able to cut out even more custom CSS. 

The ticket also proposes registering block styles in theme.json, so you could even cut back on PHP or JavaScript (depending on how you like to register your block styles).

Props to @marybaum, @welcher, and @mburridge for feedback and review.

Categories:

14 responses to “Customizing core block style variations via theme.json”

  1. Mehedy Avatar

    I appreciate the valuable insights shared about customizing core block style variations via theme.json. It’s fantastic to see how this feature enhances the flexibility and customization options for WordPress themes. The step-by-step explanations and examples provided make it easier to understand and implement. Thank you for sharing this informative and practical guide. It’s definitely a valuable resource for WordPress developers looking to leverage the power of theme.json.

  2. Phil Hoyt Avatar

    While this is a great addition it feels awkward that we are unable to target any style, registered or otherwise. We still have core opinionated markup that we are unable to target with theme.json such as navigation items (current-menu-item, has-children)
    Reading issues on this https://github.com/WordPress/gutenberg/issues/42299
    Gives some insights into possible solutions, but seemingly cheery picking what classes we can target seems arbitrary to some moving target ideals. Lets open the floodgates and target classes per element.

    1. Justin Tadlock Avatar

      You can overwrite any core style via theme.json by adding arbitrary CSS to the styles.css property. Here’s an example of changing the current menu item’s color:

      "css": ".wp-block-navigation .current-menu-item { color: red; }",

      It’s not ideal, and the Navigation block probably needs more work than any other in this regard, but it’s still possible to do via theme.json.

      You can also use stylesheets. Or, even better, tie your settings.custom properties back into your stylesheet. I personally lean toward this method since I can edit those properties in style variations or child themes.

      The big thing is building out the UI piece of this. At the end of the day, if there’s no UI support, it doesn’t really matter to the end-user where the styles are coming from (core or the theme) because they don’t have nice controls to customize those styles. I’m usually an “open the floodgates” kind of guy, but I think a slow and methodical approach will carry the least amount of legacy baggage in the long run.

  3. Juan Pablo Muñoz Upegui Avatar
    Juan Pablo Muñoz Upegui

    Hi, thanks for this post, just one question.
    How can I style hover state in variations?

    1. Justin Tadlock Avatar

      As far as I know, you can’t do this using the :hover property in theme.json yet. You’d need to target the .is-style-{name} class in the css field or in a custom stylesheet.

      1. MarcGuay Avatar

        Unfortunately you can’t target the `.is-style-{name}` class in the `css` field because the styles are applied to the inner `.wp-block-button__link` and not the parent `.wp-block-button`.

        1. Justin Tadlock Avatar

          You can use the global styles.css property, which isn’t prefixed, if you need to do it via theme.json. I personally prefer to use a stylesheet for writing CSS where possible, though.

          1. MarcGuay Avatar

            Gotcha, thanks. I decided to use the method described below with wp_enqueue_block_style.

    2. Ivan Avatar
      Ivan

      you can create an additional button-outline.css file and use wp_enqueue_block_style() function allows you to enqueue a stylesheet for a specific block. These will only get loaded when the block is rendered (both in the editor and on the front end).

      wp_enqueue_block_style(
      'core/button',
      array(
      'handle' => button-style-outline',
      'src' => get_parent_theme_file_uri( 'assets/css/button-outline.css' ),
      'ver' => wp_get_theme( get_template() )->get( 'Version' ),
      'path' => get_parent_theme_file_path( 'assets/css/button-outline.css' ),
      )
      );

  4. Taylor Wilkinson Avatar

    I have the same question as Juan. Is there no way to add hover and focus styles to variations using theme.json?

  5. Adam Holsten Avatar
    Adam Holsten

    Are there any plans to control a variation’s settings in a future release?

  6. astralbath Avatar

    I would love the option to load custom separator images— not emoticons but graphic ornaments as .png or .svg (for scalability) in addition to the default line, wide line, and dots. Right now it seems to require coding way above my current skill level. I mean, sure, I could just insert and image, but I think the separator tag is important for such as screen-readers.

    1. Justin Tadlock Avatar

      You can definitely do this with the Block Styles API (tutorial here on the Dev Blog). All you need to do is write the CSS for it, and there are tons of resources around the web for doing this.

      1. astralbath Avatar

        Thank you for pointing me in the right direction. Guess it’s time to brush up on my code.

Leave a Reply

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