WordPress.org

WordPress Developer Blog

Using the box shadow feature for themes

Gutenberg 14.9 launched on January 4, 2023, and this release featured a long-needed design tool that theme authors have been missing: shadows. The first iteration of this feature, which should eventually land in WordPress 6.2, allows designers to create a set of custom shadows to apply to blocks and supported elements.

The box shadow component and the UI tools are still currently under development, so users cannot yet select or customize shadows via the WordPress admin. Therefore, this is a code-only feature until the other pieces land. However, theme authors can start testing shadows and applying them via theme.json.

The shadow feature works similarly to other presets that theme authors can define. When registered, they become custom CSS properties and are inlined in the site’s <head>. The property names for shadows also follow the same scheme as other presets: --wp--preset--shadow--{$slug}.

Registering custom shadows

You can add custom shadows via the settings.shadow.presets array in theme.json (note that presets was named palette in Gutenberg plugin versions earlier than 15.1). Each item in the array must be an object with the following properties:

  • name: a human-readable name for the shadow
  • slug: a unique slug that will be used to reference the shadow
  • shadow: a valid CSS value for the box-shadow property

Now, try adding some custom shadows to your theme.json file, as shown in the following code snippet:

{
	"version": 2,
	"settings": {
		"shadow": {
			"presets": [
				{
					"name": "Small",
					"slug": "sm",
					"shadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)"
				},
				{
					"name": "Medium",
					"slug": "md",
					"shadow": "0 4px  10px 0 rgba( 0, 0, 0, 0.3 )"
				},
				{
					"name": "Large",
					"slug": "lg",
					"shadow": "0 8px  15px 0 rgba( 0, 0, 0, 0.3 )"
				}
			]
		}
	}
}

The previous code adds three different shadows:

  • Small
  • Medium
  • Large

The following screenshot shows how each of these shadows might be applied to an Image block:

Now select a block or element that you want to apply a default shadow to. Then, choose one of your custom shadows to use.

The following code example, adds the “Large” shadow size to the Image block:

{
    "version": 2,
    "styles": {
        "blocks": {
            "core/image": {
                "shadow": "var( --wp--preset--shadow--lg )"
            }
        }
    }
}

Once saved, all Image blocks on the site should appear with this shadow, as shown in the following screenshot:

Remember that users do not yet have the ability to override these on the block or global level yet, at least not via the UI. However, they should be able to do so in the future.

Using the core shadows

By default, the Gutenberg plugin currently adds two custom shadows with the slugs natural and sharp. Theme authors can also use these to style blocks via theme.json, even if they have not registered their own.

The following code example shows how to use the natural shadow on an Image block:

{
    "version": 2,
    "styles": {
        "blocks": {
            "core/image": {
                "shadow": "var( --wp--preset--shadow--natural )"
            }
        }
    }
}

Note: The core shadows could change before they are officially added to WordPress 6.2.

Integrating the color palette with shadows

As theme.json becomes more robust, it also becomes easier for theme authors to reuse one set of design tools with another. It will often make sense to use colors defined via settings.color.presets as the shadow color. Theme authors can reference these via the --wp--preset--color--{$slug} variable.

To do this, define a custom “primary” color (or choose a name of your liking). Then, reference it via a custom shadow in theme.json.

The following code example creates a solid shadow color and adds it to Image blocks:

{
    "version": 2,
    "settings": {
        "color": {
            "palette": [
                {
                    "name": "Primary",
                    "slug": "primary",
                    "color": "#0693e3"
                }
            ]
        },
        "shadow": {
            "presets": [
                {
                    "name": "Primary",
                    "slug": "primary",
                    "shadow": "16px 16px var( --wp--preset--color--primary )"
                }
            ]
        }
    },
    "styles": {
        "blocks": {
            "core/image": {
                "shadow": "var( --wp--preset--shadow--primary )"
            }
        }
    }
}

The Image block and its shadow should look like the following screenshot:

Overall, shadow presets should allow theme authors to further reduce their stylesheet size by using the built-in design tools available in WordPress.

Props to @mburridge and @webcommsat for feedback and review.

3 responses to “Using the box shadow feature for themes”

  1. Mateus Machado Luna Avatar
    Mateus Machado Luna

    Really hoping for this to land! I was checking that Issue linked in the post (#46502), and while it is merged, it seems to be related to the global styles UI.

    Could anyone tell me which is the state of the component for individual blocks (for example, setting shadows in a Group block)? Will it make it to 6.3?

    And in case, am I able to define shadows via block html annotations in 6.2? Writing a pattern, for example? I know we can achieve this via Block Styles but I need to apply more styles and still set a shadow 🙁

    1. Justin Tadlock Avatar

      Keep an eye on this ticket for the shadow component. There’s still a bit of work to be done.

      If you just need shadows for block styles in patterns, I’d probably make a few helper classes like .has-{$shadow}-shadow that use the --wp--preset--shadow--{$slug} presets in your stylesheet. Then use those as classes within the pattern.

      1. Mateus Machado Luna Avatar
        Mateus Machado Luna

        Thanks Justin. That will be the way for now.

Leave a Reply

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