As a WordPress developer, I often find myself wanting to extend the functionality of the Block Editor (Gutenberg) to better suit my needs. One such need was the ability to add hover effects—specifically hover colors—to blocks. While the Block Editor provides robust support for colors, it doesn’t natively support hover states. To solve this, I built the “Enable Hover Color” plugin. In this blog post, I’ll walk you through how I built it and share the final code.
Code Source: https://github.com/qarayahya/enable-hover-color

Learning Resources
Building this plugin was a challenging but rewarding experience, and I couldn’t have done it without some excellent resources. Here are the two that helped me the most:
- The Gutenberg Project on GitHub: The official Gutenberg repository is a treasure trove of examples and documentation. I spent a lot of time exploring the
block-library
package to understand how core blocks are built and extended. You can find it here: Gutenberg Block Library on GitHub. - Nick Diego’s Blog: Nick Diego’s blog post, “Useful Resources for Extending WordPress Blocks”, was incredibly helpful. It provided clear explanations and practical examples for extending the Block Editor. If you’re looking to dive deeper into block development, I highly recommend checking it out: Nick Diego’s Blog Post.
The Problem
When working on this plugin, I quickly encountered a challenge: you cannot add a :hover
effect using only inline CSS. In traditional CSS, hover states are handled using stylesheets, but in Gutenberg blocks, inline styles are often the most flexible way to apply styles dynamically.
This raised a key question: How can I pass a color value to CSS for use in a :hover
effect when inline styles don’t directly support pseudo-classes?
The Solution
The solution I came up with uses inline CSS to add color variables and then applies those variables to the :hover
effect. This approach allows for dynamic hover colors without requiring custom CSS for each block. Here’s how it works:
- Inline CSS Variables: The plugin adds inline styles to the block’s wrapper element, defining CSS variables like “–hover-background-color”. These variables are set based on the user’s selections in the Block Editor.
<div class="has-hover__background" style="--hover-background-color: #f3f4f6;">
Hello?
</div>
- Hover Effects: The plugin uses these CSS variables in the block’s stylesheet to apply hover effects. For example:
.has-hover__background:hover {
background-color: var(--hover-background-color);
}
- Transition Controls: The plugin also allows users to define the duration and timing function for hover transitions, ensuring smooth and customizable hover effects.
Checking for Text Color Support
One of the key parts of the plugin is ensuring that hover color controls are only added to blocks that support text color. This is important because not all blocks in the Block Editor have color support, and adding unnecessary controls could clutter the interface or cause errors. Here’s a breakdown of the code that handles this:
// Check if the block supports text color.
const hasTextColorSupport = () => {
const colorSupport = getBlockSupport(settings, "color");
return colorSupport && colorSupport.text !== false;
};
if (!hasTextColorSupport()) {
return settings;
}
Reference: WordPress Color Support Check
What This Code Does
- getBlockSupport(settings, “color”):
- This function checks if the block supports the
color
feature. Thesettings
parameter contains the block’s configuration, and"color"
specifies the feature we’re checking for. - The
color
feature typically includes support for text color, background color, and sometimes gradient colors.
- This function checks if the block supports the
- colorSupport && colorSupport.text !== false:
- The
colorSupport
object returned bygetBlockSupport
contains details about the block’s color support. Specifically, it includes atext
property that indicates whether the block supports text color. - The condition checks if
colorSupport
exists and if thetext
property is not explicitly set tofalse
. If both conditions are true, the block supports text color.
- The
- if (!hasTextColorSupport()) { return settings; }:
- If the block does not support text color, the function returns the original
settings
object without making any modifications. This ensures that only blocks with text color support receive the hover color attributes and controls.
- If the block does not support text color, the function returns the original
Why This Matters
- Selective Enhancement: By checking for text color support, the plugin ensures that hover color controls are only added to blocks where they make sense (e.g., buttons, headings, paragraphs). This keeps the Block Editor clean and user-friendly.
- Avoiding Errors: Adding hover color attributes to blocks that don’t support text color could lead to unexpected behavior or errors. This check prevents such issues.
- Future-Proofing: If new blocks are added to the Block Editor, this code will automatically determine whether they should have hover color support based on their configuration.
This approach is a great example of how to extend the Block Editor responsibly, ensuring compatibility and a smooth user experience.
Step 1: Adding Attributes to Blocks
First, I needed to add custom attributes to blocks to store the hover color values. This is done using the blocks.registerBlockType
filter. The plugin checks if a block supports text color and, if it does, adds the following attributes:
- hoverTextColor
- customHoverTextColor
- hoverBackgroundColor
- customHoverBackgroundColor
- hoverBorderColor
- customHoverBorderColor
- hoverTransitionDuration
- hoverTransitionTiming
Here’s the code:
addFilter(
"blocks.registerBlockType",
"enable-hover-color/add-attributes",
function (settings, name) {
// Check if the block supports text color.
const hasTextColorSupport = () => {
const colorSupport = getBlockSupport(settings, "color");
return colorSupport && colorSupport.text !== false;
};
if (!hasTextColorSupport()) {
return settings;
}
return {
...settings,
attributes: {
...settings.attributes,
hoverTextColor: { type: "string" },
customHoverTextColor: { type: "string" },
hoverBackgroundColor: { type: "string" },
customHoverBackgroundColor: { type: "string" },
hoverBorderColor: { type: "string" },
customHoverBorderColor: { type: "string" },
hoverTransitionDuration: { type: "number", default: 200 },
hoverTransitionTiming: { type: "string", default: "ease" },
},
};
}
);
Step 2: Adding Controls to the Block Editor
Next, I added controls to the Block Editor sidebar using the editor.BlockEdit
filter. These controls allow users to set hover colors and transition properties. The controls are conditionally rendered only for blocks that support text color.
The <InspectorControls>
component allows you to integrate your custom controls into existing groups like color or typography. This is particularly useful for maintaining a consistent user experience. For instance, in the “Enable Hover Color” plugin, I added hover color and transition controls to the color
group:
<InspectorControls group="color">
<HoverColorsControls {...props} />
<HoverTransitionControls {...props} />
</InspectorControls>
This ensures that all color-related settings, including hover effects, are located in one place. It’s a great way to enhance functionality without cluttering the sidebar with additional panels.
addFilter(
"editor.BlockEdit",
"enable-hover-color/add-inspector-controls",
createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { name, attributes, setAttributes, clientId } = props;
const hasTextColorSupport = () => {
const blockType = getBlockType(name);
const colorSupport = getBlockSupport(blockType, "color");
return colorSupport && colorSupport.text !== false;
};
if (!hasTextColorSupport()) {
return <BlockEdit {...props} />;
}
return (
<>
<BlockEdit {...props} />
<InspectorControls group="color">
<HoverColorsControls
attributes={attributes}
setAttributes={setAttributes}
clientId={clientId}
/>
<HoverTransitionControls
attributes={attributes}
setAttributes={setAttributes}
clientId={clientId}
/>
</InspectorControls>
</>
);
};
})
);
Step 3: Applying Hover Styles in the Editor
To apply the hover styles in the editor, I used the editor.BlockListBlock
filter. This filter allows me to modify the block’s wrapper props and add inline styles and classes dynamically.
The plugin uses CSS variables to apply the hover colors and transitions. Here’s how it works:
addFilter(
"editor.BlockListBlock",
"enable-hover-color/add-styles",
createHigherOrderComponent((BlockListBlock) => {
return (props) => {
const { name, attributes } = props;
const hasTextColorSupport = () => {
const blockType = getBlockType(name);
const colorSupport = getBlockSupport(blockType, "color");
return colorSupport && colorSupport.text !== false;
};
if (!hasTextColorSupport()) {
return <BlockListBlock {...props} />;
}
const {
hoverTextColor,
customHoverTextColor,
hoverBackgroundColor,
customHoverBackgroundColor,
hoverBorderColor,
customHoverBorderColor,
hoverTransitionDuration,
hoverTransitionTiming,
} = attributes;
const getColorValue = (presetColor, customColor) => {
return presetColor
? `var(--wp--preset--color--${presetColor})`
: customColor || "";
};
const inlineStyle = {
"--hover-color": getColorValue(hoverTextColor, customHoverTextColor),
"--hover-background-color": getColorValue(
hoverBackgroundColor,
customHoverBackgroundColor
),
"--hover-border-color": getColorValue(
hoverBorderColor,
customHoverBorderColor
),
"--hover-transition-duration": attributes.hoverTransitionDuration + "ms",
"--hover-transition-timing": attributes.hoverTransitionTiming,
};
return (
<BlockListBlock
{...props}
wrapperProps={{ style: inlineStyle }}
className={classnames(props.className, {
"has-hover__color": hoverTextColor || customHoverTextColor,
"has-hover__background-color": hoverBackgroundColor || customHoverBackgroundColor,
"has-hover__border-color": hoverBorderColor || customHoverBorderColor,
})}
/>
);
};
})
);
This dynamically updates the block’s appearance inside the editor, giving a real-time preview of hover effects.
The Color Controls Component
The “HoverColorsControls” component is responsible for rendering the color pickers in the sidebar. It uses WordPress’s “ColorGradientSettingsDropdown” component to provide a user-friendly interface for selecting colors.
const HoverColorsControls = ({
clientId,
hoverTextColor,
hoverBackgroundColor,
hoverBorderColor,
setHoverTextColor,
setHoverBackgroundColor,
setHoverBorderColor,
}) => {
const colorSettings = [
{
value: hoverTextColor?.color,
onChange: setHoverTextColor,
label: __("Hover Text"),
resetAllFilter: () => ({
hoverTextColor: undefined,
customHoverTextColor: undefined,
}),
},
// Similar settings for background and border colors
];
const colorGradientSettings = useMultipleOriginColorsAndGradients();
return (
<>
{colorSettings.map(({ onChange, label, value, resetAllFilter }) => (
<ColorGradientSettingsDropdown
key={`hover-color-${label}`}
settings={[
{
colorValue: value,
label,
onColorChange: onChange,
resetAllFilter,
enableAlpha: true,
clearable: true,
},
]}
panelId={clientId}
{...colorGradientSettings}
/>
))}
</>
);
};
Final Thoughts
Building the “Enable Hover Color” plugin was a great learning experience. It allowed me to dive deep into WordPress’s Block Editor APIs and explore how to extend the editor’s functionality. The plugin is now a valuable tool in my workflow, and I hope it can be useful to others as well.
Let me know what you think!
Leave a Reply