Three ways to customize the accordion block icon

Gutenberg finally has an accordion block as of WordPress 6.9. Yay! Cue the happy dance! I hadn’t tinkered with it until I was chatting with another WordPresser, and a question came up. One that I spotted other WordPress peeps also asking in threads. I couldn’t find an answer for it in the WordPress Docs or through a Google search.

It ended up being one of those rare mysteries that excited me. The kind of mystery that had me digging into WordPress core late at night, sleep be damned, until the answer was revealed.

How do we customize the accordion block’s icon?

It feels like a reasonable feature to expect in Gutenberg, right? At the time of writing this, the accordion block has a plus icon for each accordion item. The block editor offers options to hide this icon, or to position it. By default, there are no options to swap out the icon with something else.

How about custom implementation? From what I’ve found, there are three ways we can customize the accordion block’s icon, with pros and cons to each method. Before we get into what each of these are, let’s first clarify something that tripped me up when I was experimenting with the accordion block.

The accordion block is several blocks

When I was digging into core, there was some confusion at first because I was focusing solely on looking for anything related to the core/accordion block. But this is just the parent wrapper block with others nested within it:

  • core/accordion: This is the parent block.
  • core/accordion-item: The individual item within the accordion.
  • core/accordion-heading: The clickable heading within the accordion item. This is what expands and collapses the hidden content.
  • core/accordion-panel: The panel that contains the hidden content beneath the heading.

If you’ve noticed that I didn’t provide a link to the core/accordion-heading block, it’s because the documentation does not exist (yet) for it. This is where the heading and icon is rendered from. Here is what the markup looks like out of the box on the front-end:

Now that we have that understanding, let’s go over solutions.

The solutions

Using the render_block filter

We can use the render_block filter and a preg_replace to target the core/accordion-heading block, and change markup. This works if you just want to swap one standard text character, the + sign, for another. In my example, I’ve used an arrow.

Pros: PHP. Familiar to classic WordPress devs. Will apply to all core accordion blocks site-wide without the need to interact with custom options in the block editor. May require minor CSS tweaking due to the icon rotation, but this solution leans more back-end than it does front-end. This also keeps the existing accessibility intact so long as you’re replacing the content within the “wp-block-accordion-heading__toggle-icon” span tag.

Cons: If you don’t want this to apply to all core accordion blocks by default, then this is not the solution for you.

The CSS only way

If diving into PHP feels like jumping into Pandora’s box, or you need a quick solution, you can also change icons with just CSS. Since the existing + icon isn’t a pseudo element, we’ll have to add one ourselves, and hide the existing one. We’ll also need to remove the transform: rotate() on the original icon, to customize it for our new pseudo element replacement.

Pros: Front-end dev friendly. With CSS, you have more options as far as what kind of icon it is. For example, maybe you want to use an SVG background image instead of the default plus sign that is a standard text character. You can also style based on specific pages or other factors rather than applying the style globally.

Cons: The icon lives in the styles. There is no control over it from the block editor, so it’s not FSE site friendly. This could be a good or bad thing depending on your intentions.

Note: When styling with a :before or :after pseudo element, you want to keep it inside the existing “wp-block-accordion-heading__toggle-icon” span tag. That’s because it already has an ARIA attribute to hide it from screen readers and will keep accessibility intact.

A combination of CSS and the register_block_style function

The third method is a combination of styling and using the register_block_style function. If you haven’t used this function before, it’s a way to define a custom style option in the block editor for a specific block. All it does is add a class based on what you’ve named it.

An example in this WordPress theme

(Skip if you’d rather stick to the accordion topic.)

As an example, in my RachieVee-2025 WordPress theme, I’ve registered a custom style for the paragraph block that changes the link styling. Here’s what it looks like on the front-end (this link goes nowhere, but for the sake of examples):

Check out this arrow style

And this is what it looks like in the block editor options. There’s an option called “Link Right Arrow Style” which applies the class “is-style-arrow” to the block. This option gives me the freedom to apply a style from the editor.

An example in this WordPress theme

For the accordion block, you’d register a custom style that gets applied when the new option from the block editor is selected. You can use the custom class in your CSS to customize your icon.

Pros: A compromise between front and back-end. Gives your client the freedom to select an option to apply a custom pre-defined style.

Cons: Maybe you don’t want to provide that extra freedom or complexity for your client. It depends on the site and their needs. Decisions, not options.

The example below will apply an “is-accordion-arrow-style” class to the accordion block when the option is selected in the block editor:

Mystery Solved!

And there you have it! The documentation for how to customize the accordion block’s icon exists now. Which solution do you prefer? Do you have another solution to share? Let me know in the comments.


This will be my last post for the year! Wishing you all a wonderful holiday and a prosperous new year! See you in 2026!

Leave a Reply

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