Opened 4 months ago
Last modified 5 weeks ago
#65089 new enhancement
Administration: Replace Dashicons icon font with @wordpress/icons SVG components in wp-admin
| Reported by: | lucasmdo | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | Administration | Version: | |
| Severity: | normal | Keywords: | needs-design needs-design-feedback has-patch has-unit-tests |
| Cc: | Focuses: | ui, accessibility, javascript, css, administration, performance |
Description
Problem / Current Behavior
The WordPress admin area (wp-admin) still relies on Dashicons, an icon font introduced in WordPress 3.8 (released December 12, 2013 — over 12 years ago). While Dashicons served WordPress well, the icon font approach has significant limitations:
- Inconsistency: The block editor and Site Editor already use
@wordpress/icons(SVG-based React components), while the rest of wp-admin uses the legacy Dashicons font. This creates a visual and technical split within the same application. - Performance: The entire icon font (~300+ glyphs) is loaded, regardless of how many icons a page actually uses. This adds unnecessary weight to every admin page load.
- Accessibility:
- Screen readers: Icons may be read as nonsense or ignored entirely, confusing users who rely on assistive technology.
- Font overrides: Users who change fonts for readability can break all icons, turning them into empty squares.
- Copy-paste: Copying text that includes icons produces random, meaningless characters.
- High-contrast mode: Icons can vanish when users enable high-contrast or forced-colors settings in their OS.
- No built-in meaning: Icon fonts are just styled characters with no inherent description — accessibility has to be added manually.5.5. No new icons can be added.
Proposed Enhancement
Replace Dashicons icon font usage in wp-admin with @wordpress/icons SVG components (or inline SVGs derived from the same library). This would:
- Unify the icon system across all of WordPress, block editor, Site Editor, and classic admin screens would all use the same modern icon library.
- Enable tree-shaking so that only the icons actually used on a given page are loaded.
- Improve accessibility: inline SVGs support
aria-labelfor example. - Allow new icons to be added as needed without growing a monolithic font file.
Rationale
This is not a new idea, it has been the stated direction of the WordPress project since 2020:
- The Make/Design blog post (April 2020) confirmed Dashicons was closed to new requests and that future efforts would focus on the new Icon component.
- 49913 explicitly states: "This update is the final planned update of the Dashicons font. Moving forward, the more modern approach of using SVG icons directly (as the block editor currently does) will be explored."
- 47498 comments reference "a long standing plan to remove all font icons from core in favor of SVGs."
Six years have passed since this direction was set, and no formal ticket tracks the actual migration work. This ticket aims to formalize the effort and track progress.
Backward Compatibility
This is a critical consideration. Many plugins and themes use dashicons-* CSS classes for admin menus, meta boxes, and custom UI. A migration plan should:
- Maintain the
dashiconsstylesheet as a deprecated fallback for a defined transition period (multiple major releases). - Provide a compatibility layer so that existing
dashicons-*class references continue to render correctly, perhaps by mapping them to their SVG equivalents. - Document the migration path for plugin and theme developers with clear timelines.
Related Tickets / References
- 49913 — Final Dashicons update (WordPress 5.5)
- 47498 — Checkbox/radio SVG migration, discusses removing font icons from Core
- 41074 — Dashicons 4.9–5.2, discusses SVG direction for the admin
- Next steps for Dashicons — Make/Design official post
- Dashicons in WordPress 5.5: The Final Update — Dev note
- @wordpress/icons package on GitHub
Change History (29)
This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.
3 months ago
#4
@
2 months ago
This ticket will serve as an umbrella ticket. I'll split this ticket into two: sidebar and admin bar (toolbar).
#5
@
2 months ago
Please note that we are developing public APIs to centrally manage and appropriately output SVG icons.
This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.
2 months ago
#8
@
7 weeks ago
This ticket will serve as an umbrella ticket. I'll split this ticket into two: sidebar and admin bar (toolbar).
So I tried updating only the admin bar, but it looks jarring/unbalanced with the sidebar if it still shows the old dashicons. So I took a stab on implementing it for both admin bar and sidebar. I'll link the PR below.
This ticket was mentioned in PR #12270 on WordPress/wordpress-develop by @fushar.
7 weeks ago
#9
- Keywords has-patch has-unit-tests added; needs-patch removed
Trac ticket: https://core.trac.wordpress.org/ticket/65089
[!WARNING]
This PR is stacked on top of #12010. Please only review my commit: 6ec651a52b
Also, some icons were not already public, so they need to be made public, maybe as separate Gutenberg PR. See related: https://github.com/WordPress/gutenberg/pull/79102.
This PR replaces the dashicons usage in admin bar and menu (sidebar) with @wordpress/icons, via the newly-introduced wp_get_icon() function, which outputs an inline SVG to be rendered.
## New icon mapping
### Admin bar
| Item | Old dashicon | New wp/icons | Public? |
|---|---|---|---|
| WordPress logo | dashicons-wordpress | core/wordpress | |
| Sidebar menu toggle (mobile) | dashicons-menu-alt | core/menu | |
| My Sites | dashicons-admin-multisite | core/grid | ❌ |
| Site Name — frontend | dashicons-dashboard | core/dashboard | |
| Site Name — wp-admin | dashicons-admin-home | core/home | |
| Edit Site<br>Customize | dashicons-admin-appearance<br>dashicons-admin-customizer | core/brush | ❌ |
| Edit (post/page/etc.) | dashicons-edit | core/pencil | |
| + New | dashicons-plus | core/plus | |
| Comments | dashicons-admin-comments | core/comment | |
| Updates | dashicons-update | core/update | |
| Search<br>Command Palette | dashicons-search | core/search | |
| My Account (no-avatar fallback) | dashicons-admin-users | core/people |
### Admin menu (left sidebar)
For simplicity, only showing new items not present in the admin bar above.
| Menu item | Old dashicon | New wp/icons | Public? |
|---|---|---|---|
| Dashboard | dashicons-dashboard | core/dashboard | |
| Posts | dashicons-admin-post | core/post | ❌ |
| Media | dashicons-admin-media | core/media | ❌ |
| Links | dashicons-admin-links | core/link | ❌ |
| Pages | dashicons-admin-page | core/page | ❌ |
| Plugins | dashicons-admin-plugins | core/plugins | ❌ |
| Users | dashicons-admin-users | core/people | |
| Tools | dashicons-admin-tools | core/tool | ❌ |
| Settings | dashicons-admin-settings | core/settings | |
| Collapse menu button | dashicons-admin-collapse | core/chevron-left |
## Open questions
- I'm not sure about
My Sitesicon. The closest thing that I think fits is thecore/gridicon (see screenshot below). Open to alternatives. - The search/magnifier icon is facing the opposite direction from the old dashicon. Should we do something about it? My vote is to do nothing; if we want to reverse the direction, we should update the icon instead.
## Screenshots
### WP Admin
| Before | After |
|---|---|
| | |
### WP Admin - Multisite
| Before | After |
|---|---|
| | |
### Frontend
Before
After
### Mobile
Before
After
## Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 4.8
Used for: code generation, with my supervision.
@JeffPaul commented on PR #12270:
7 weeks ago
#10
These all appear to be solid like-for-like replacements, though I feel least supportive of the Sites icon replacement on multisite. Perhaps a new icon could/should be generated there or review other icons for something besides a 2x2 table sort of icon? Of the existing icons, the one that feels like what I'd recommend otherwise is one that looks like a "two child node branched to the right" (_sorry GitHub is giving me problems trying to upload a screenshot from my cell connection_).
@fushar commented on PR #12270:
7 weeks ago
#11
@jeffpaul Thanks for checking!
I feel least supportive of the Sites icon replacement on multisite.
Yep, as noted in the PR description, I'm not sure about this as well.
Of the existing icons, the one that feels like what I'd recommend otherwise is one that looks like a "two child node branched to the right"
You mean core/blockMeta? Indeed this looks more fitting. 😄
But my worry is that the icon slug is not related to "site" at all. I would expect there is something like core/sites icon. Perhaps it's better if we create a new such icon. cc: @jasmussen, @lucasmendes-design (I know you're all on vacation, feel free to respond when you're back.)
Another idea is to use this icon, to represent a "site switcher":
@tyxla commented on PR #12270:
7 weeks ago
#12
A few things from my end as I'm looking at this work:
- This is exciting and a much-awaited overhaul of icons, love it!
- It has the potential to have an impact on many plugins, plugin infrastructures and products that rely on the current icon set - something to be mindful about
- I don't see enough feedback from @WordPress/gutenberg-design on this, and I believe this is a hard requirement
- I believe it's a bit late in the 7.1 cycle for this to move forward, but it makes sense to get it to the finish line on time for landing early in the 7.2 cycle. It's paramount to give plugins and extenders enough time for testing and adopting the necessary changes.
- An angle that doesn't seem explored is trying this out as a Gutenberg experiment - not only to allow for safe iteration, but also as yet another way to get useful feedback.
@JeffPaul commented on PR #12270:
7 weeks ago
#13
@fushar yes the blockMeta was the icon I was trying to reference, though I'm not quite as concerned with the slug for it (not certain that the slug is referenced or rendered anywhere in the UI and if not then there's no end user confusion that could happen). I'm not much in favor of the chevronUpDown option for Sites, in that case would just stick with the 2x2 table-looking icon I suppose but in any case would like a better one for that icon if possible (and if as @tyxla notes this is too late for 7.1 then we've got some time to iterate on the Sites icon).
@fushar commented on PR #12270:
7 weeks ago
#14
An angle that doesn't seem explored is trying this out as a Gutenberg experiment
Thanks for the suggestion. I spent a good chunk of my day today trying to make this as a Gutenberg experiment.
With the help of Claude, I (we) came up with this PR: https://github.com/WordPress/gutenberg/pull/79588. Now, I understand that the changes are complicated, but I can't simplify it any further. Reasons:
- I need to render the icons that are not yet public.
wp_get_icon()won't allow me to render such icons, so I need to replicate the implementation for now. - There's no way to hook into admin menu icon. Basically I really need this new logic in Core, which can't be extended via hooks. Hence the experiment needs to hijack the output of the admin menu HTML and replace dashicons with SVG before it gets rendered.
- The CSS needs to duplicate the admin color scheme to achieve hover effect in the admin bar. In this Core change, I can just update the
_admin.scssdirectly, which can't be replicated in experiments.
Am I approaching this correctly? Or do you have better idea for a cleaner approach? Thanks!
@fcoveram commented on PR #12270:
7 weeks ago
#15
It looks great ✨ I noticed a few things that I'm not fully sure belong to the PR scope.
### Icon size
In most cases, the icon size is 22px, but the W symbol is 24px.
| 22px | 24px |
|---|---|
| | |
Not sure if this is intentional or not.
### Color on the frontend
On the frontend, the color at 0.6 looks slightly lighter. I know it is consistent, but at 0.85 looks visually more similar to the current. This is not a blocker but sharing it for thoughts.
### "Sites" icon
Regarding the icon for Sites, I agree that blockMeta works well until having a dedicated icon.
---
I've been testing it on Arc, Chrome, and Safari and on multiple viewports. And they all look good ⭐
@tyxla commented on PR #12270:
7 weeks ago
#16
Am I approaching this correctly? Or do you have better idea for a cleaner approach?
Hmm, this seems correct to me. There are side ways for achieving some of the things you mentioned, but not for others, unless we want to be super hacky. A bummer that this part of the menu is not as extensible as usual. Thank you for trying, though.
Another way to get more attention on this would be to post a call for testing on the https://make.wordpress.org/core blog.
@mcsf commented on PR #12270:
7 weeks ago
#17
Am I approaching this correctly? Or do you have better idea for a cleaner approach? Thanks!
I'd say so, at least for the purposes of a Gutenberg experiment. I left a comment or two in that PR.
@fushar commented on PR #12270:
6 weeks ago
#18
@fushar commented on PR #12270:
6 weeks ago
#19
@fcoveram: Thanks for the thorough testing!
In most cases, the icon size is 22px, but the W symbol is 24px.
Not sure if this is intentional or not.
Yeah, it is intentional. I'm not sure if it's the best way though. It's to achieve the same look and feel with the existing W dashicon. See the above image comparison, pasted here again:
Right now, if we use 22px, then the W logo is too small, because there's outer gap in the SVG. Maybe we need to fill the entire SVG box without any outer gap.
On the frontend, the color at 0.6 looks slightly lighter. I know it is consistent, but at 0.85 looks visually more similar to the current.
Yeah agree that 0.85 looks better. But I'm not sure if we can just update it only for the SVG icon. It's part of the Fresh color scheme; maybe we should do a separate PR to update the scheme 😄
@fushar commented on PR #12270:
6 weeks ago
#20
All right everyone, thanks for taking a look. I want to summarize where we're at with this PR:
- To use currently non-public icons, we need the
public: falseflag as discussed in https://github.com/WordPress/gutenberg/pull/79451#issuecomment-4797981729.- @t-hamano, is this something that you're currently pursuing? How confident are we with the solution?
- This PR adds support to use registered icons in left sidebar menu items. See this diff. To move forward, I need a review on this as it's modifying a public hook (
admin_menu).- Also, maybe we should at least ship this part first in 7.1 so that plugins can start using it?
- If we do that, it will be beneficial to ship the CSS changes for rending SVG icons in admin bar / menu.
- We need to iterate on My Sites icon. I can ask for help for this. @jasmussen / @lucasmendes-design should be interested.
- As suggested, we should publish a public Make post as a heads-up to the community and plugin developers. In the post, we should suggest the default (core) icon set for the admin, and how plugins can use SVG icons in the admin menu (the public API change I mentioned above).
It feels like there's interest to push at least some parts of it in 7.1, and we're not that sure if we can achieve everything by 7.1. @t-hamano, what's your opinion on this? It seems you have the most context for all this icon API discussion 😄
cc: @tyxla, @mcsf, @scruffian.
@wildworks commented on PR #12270:
6 weeks ago
#21
It feels like there's interest to push at least some parts of it in 7.1, and we're not that sure if we can achieve everything by 7.1. @t-hamano, what's your opinion on this? It seems you have the most context for all this icon API discussion 😄
Leveraging the icon API for the dashboard icons is a great idea, and introducing a public:false flag shouldn't be difficult. However, I noticed that core icons might be unregistered by consumers.
add_action( 'init', function () { wp_unregister_icon_collection( 'core' ); }, 20 );
add_action( 'init', function () { wp_unregister_icon( 'core/info' ); }, 20 );
In this case, what happens to the core menu icons registered by the icon API? This is my biggest concern. Here are the ideas I can come up with at the moment:
- Allow file paths for
menu_icon. This ensures that icons are rendered even if they are unregistered from the icon registry, as the file itself will still exist within the core. - Allow SVG strings for menu_icon. This might be a larger undertaking, requiring a proper SVG processing pipeline.
- Introduce a "built-in" collection to house icons used in dashboards and protect the unregisteredion of this collection or its icons would enhance robustness.
Do you have any other ideas?
@fushar commented on PR #12270:
6 weeks ago
#22
Thanks for taking a look.
I noticed that core icons might be unregistered by consumers.
Hmm interesting question. I would say, the last option (consider core/* as built-in icon set which can't be unregistered) looks the most sensible to me. It's like having a fixed set of dashicons-* slugs that consumers can always use currently.
Otherwise, we will also need another way to get the SVG string for the admin bar icons as well, because in this PR I also use wp_get_icon() to prepend the icon to the title 🤔
@mcsf commented on PR #12270:
6 weeks ago
#23
However, I noticed that core icons might be unregistered by consumers.
This is a good point.
- Allow file paths for
menu_icon. This ensures that icons are rendered even if they are unregistered from the icon registry, as the file itself will still exist within the core.
One of the problems here is that it makes it more difficult to iterate on icon designs in Gutenberg, since those icons will no longer override those in wp-includes.
It also may or may not add some work for certain WP installations that rely on CDNs for core assets...? This is unfamiliar territory for me.
- Allow SVG strings for menu_icon. This might be a larger undertaking, requiring a proper SVG processing pipeline.
Sounds risky and heavy-handed, as you point out yourself.
- Introduce a "built-in" collection to house icons used in dashboards and protect the unregisteredion of this collection or its icons would enhance robustness.
Maybe, but it could make things frustrating for certain admins. For example, if — say, for editorial purposes — they'd like to keep a very narrow set of available icons for the Icon block. I don't think it's unheard of to prevent deregistering a core provision, but we almost always allow it (e.g. wp_deregister_script, unregister_block_type...). (Side note: we can always explore a separate mechanism for the Icon block so that third parties can filter its list of available icons.)
There's a fourth option, loosely in response to the one above:
Allowing core icons (and core collection) to be deregistered, so that they will not show up in listings, but embedding a fallback somewhere (WP_Icons_Registry::get_registered_icon? wp_get_icon?) so that certain core icons will still render.
I don't exactly like the idea, but I thought I'd share it anyway.
Another option is to honour admins' decision to deregister things, and have a fallback "no-icon" icon. In other words, make admins and extenders responsible for the questionable decision to deregister core icons: they can do it, but the admin will look weird with placeholder icons.
@wildworks commented on PR #12270:
6 weeks ago
#24
Another option is to honour admins' decision to deregister things, and have a fallback "no-icon" icon. In other words, make admins and extenders responsible for the questionable decision to deregister core icons: they can do it, but the admin will look weird with placeholder icons.
Is it possible to extend this idea further and display the relevant dashicon as a fallback if the SVG icon is not registered?
@keoshi commented on PR #12270:
6 weeks ago
#25
One point to add to @fcoveram comment here:
In most cases, the icon size is 22px, but the W symbol is 24px.
All @wordpress/icons icons were designed with a 24×24px area in mind and all/most are optimized to be visualized at that size. Certainly in non-retina displays. Not sure if a deal breaker or not, so pinging @jasmussen to get your thoughts.
@tyxla commented on PR #12270:
6 weeks ago
#26
Hmm interesting question. I would say, the last option (consider
core/*as built-in icon set which can't be unregistered) looks the most sensible to me. It's like having a fixed set ofdashicons-*slugs that consumers can always use currently.
This might make sense since this is how post types work - you can't unregister_post_type() a built-in post type. But for that to work, post types also maintain a _builtin flag.
@tyxla commented on PR #12270:
6 weeks ago
#27
A high-level flag from me: the fact that we are still asking and answering fundamental API/design questions (registration/unregistration/compatibility) less than a couple of weeks before beta is a clear sign that a feature might need more time to get feature-complete, thoroughly thought out, and polished enough for a WordPress release. For some of that work, we might want to get broader feedback through a Make post, too, and that, on its own, will require some time to get meaningful feedback.
@Joen commented on PR #12270:
5 weeks ago
#28
Noting that I designed a "Sites" icon here: https://github.com/WordPress/gutenberg/pull/80094
@mcsf commented on PR #12270:
5 weeks ago
#29
Is it possible to extend this idea further and display the relevant dashicon as a fallback if the SVG icon is not registered?
I think this would defeat the purpose of introducing SVG icons to finally move away from Dashicons! Then we'd have to support both systems forever.
I like Marin's argument below. Currently it seems like the wisest choice to me:
This might make sense since this is how post types work - you can't
unregister_post_type()a built-in post type. But for that to work, post types also maintain a_builtinflag. Seems like this is yet another "flag" to consider for icons.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
This could have some benefits for accessibility, although issues like screen reader announcements are largely irrelevant, now that generated content allows for alt attributes in CSS (which is already implemented in the WordPress CSS.)
Support for
aria-labelis also relatively irrelevant, as that's just an implementation detail which can also be done with font-icons, just in a different way.However, the performance implementations and the need to continue to extend the icon set are definitely important considerations that should drive this forward.
For accessibility, the font replacement issue is probably the largest benefit.