How to add hover and focus styles using theme.json

In this lesson

In the previous lesson you learnt how to use theme.json elements. In this lesson, I will show you examples of how to add hover and focus styles to link and buttons in theme.json.

Estimated reading time: 2 minutes

Last updated

How to add the CSS pseudo classes

The keys that you use to style link states in theme.json are the same as the CSS pseudo classes:

  • styles.elements.link.:hover
  • styles.elements.link.:focus
  • styles.elements.link.:active
  • styles.elements.link.:visited
  • styles.elements.link.:link (docs)
  • styles.elements.link.:any-link (docs)
  • styles.elements.link.:focus-visible -New in WordPress 6.8.

In addition, you can use styles.elements.link.outline.

As with most theme.json styles, you can use this method to add site wide styles or style individual block types.

Examples

Lets continue with the some basic code examples that you can copy paste and adapt to match the design of your own full site editing theme.

Replacing site wide link underlines with a bottom border:

{
	"version": 3,
	"styles": {
		"elements": {
			"link": {
				"typography": {
					"textDecoration": "none"
				},
				"border": {
					"bottom": {
						"width": "2px",
						"color": "currentColor",
						"style": "solid"
					}
				},
				":hover": {
					"typography": {
						"textDecoration": "none"
					},
					"border": {
						"bottom": {
							"width": "2px",
							"color": "#111",
							"style": "dotted"
						}
					}
				}
			}
		}
	}
}

Adding a border around the site title block on :hover:

{
	"version": 3,
	"styles": {
		"blocks": {
			"core/site-title": {
				"elements": {
					"link": {
						"spacing": {
							"padding": ".5rem"
						},
						"typography": {
							"textDecoration": "none"
						},
						"border": {
							"width": "2px",
							"color": "transparent",
							"style": "solid"
						},
						":hover": {
							"typography": {
								"textDecoration": "none"
							},
							"border": {
								"width": "2px",
								"color": "#111",
								"style": "solid"
							}
						}
					}
				}
			}
		}
	}
}

Outline supports width, style, color and offset. This example code adjusts the focus outline on all button elements:

{
	"version": 3,
	"styles": {
		"elements": {
			"button": {
				":focus": {
					"outline": {
						"offset": "3px",
						"width": "3px",
						"style": "solid",
						"color": "blue"
					}
				}
			}
		}
	}
}

Please see the lesson about modifying block style variations if you want to edit the Outline style variation for the button block.

Adding hover or focus styles to the navigation block

Styling the navigation block links is trickier. You can choose to style the navigation block, or style the inner navigation link, page list, home link and submenu blocks individually.

This example is for the navigation block, and only works if the text decoration setting and the “Submenus: Open on click” settings are not used.

  • The text decoration setting adds a class name that increases the specificity, and the styles from theme.json are overriden, that is why this option must not be enabled.
  • The “Open on click” setting uses an HTML button element, and not a link.
{
	"version": 3,
	"styles": {
		"blocks": {
			"core/navigation": {
				"elements": {
					"link": {
						"typography": {
							"textDecoration": "none"
						},
						"border": {
							"bottom": {
								"width": "4px",
								"color": "transparent",
								"style": "solid"
							}
						},
						":hover": {
							"typography": {
								"textDecoration": "none"
							},
							"border": {
								"bottom": {
									"width": "4px",
								"color": "currentColor",
									"style": "solid"
								}
							}
						}
					}
				}
			}
		}
	}
}

Editing hover colors in the interface

Since WordPress 6.3, every block that supports link color has a setting with two tabs:
one for the default link state, and one for hover. There is no interface for the focus, active, or visited link states. Buttons do not support link color and does not have a setting for hover styles.

The link option is selected in the color panel, and a modal with two tabs is open: One tab with color swatches and a color picker for the default state, and one for hover.