How to change color of custom toolbar button in mozilla firefox extension
Categories:
Customizing Toolbar Button Colors in Firefox Extensions

Learn how to dynamically change the color of your custom toolbar button in Mozilla Firefox extensions using JavaScript and CSS, enhancing user feedback and interface aesthetics.
Customizing the appearance of your Firefox extension's toolbar button can significantly improve user experience. Whether you want to indicate a change in state, provide visual feedback, or simply match your extension's branding, changing the button's color is a common requirement. This article will guide you through the process of dynamically altering the color of a custom toolbar button using modern WebExtension APIs, focusing on JavaScript and CSS techniques.
Understanding Firefox Toolbar Buttons
Firefox WebExtensions use browser_action
or page_action
to define toolbar buttons. These buttons are essentially small HTML documents (popups) or simple icons that can be manipulated programmatically. The icon itself is typically defined in the manifest.json
and can be an image file (PNG, SVG) or a Web-based icon font. To change its color, we usually target the icon's styling or swap the icon itself.
flowchart TD A[Extension Manifest] --> B{Define browser_action/page_action} B --> C[Specify default_icon] C --> D{Icon is SVG or PNG?} D -- SVG --> E[Inject CSS/Manipulate SVG DOM] D -- PNG --> F[Swap PNG icon dynamically] E --> G[Color Changed] F --> G[Color Changed]
Flowchart illustrating methods for changing toolbar button color.
Method 1: Using SVG Icons and CSS Manipulation
The most flexible way to change a toolbar button's color is by using an SVG icon. SVG (Scalable Vector Graphics) icons are XML-based and can be styled directly with CSS or manipulated via JavaScript. This allows for dynamic color changes without needing multiple image files.
{
"manifest_version": 2,
"name": "Colorable Button",
"version": "1.0",
"browser_action": {
"default_icon": {
"16": "icons/my-icon.svg",
"32": "icons/my-icon.svg"
},
"default_title": "My Custom Button"
},
"permissions": ["activeTab"]
}
Example manifest.json
defining an SVG icon for the browser action.
Your my-icon.svg
file should be structured to allow CSS styling. A common approach is to use a <path>
element and set its fill
property. For example:
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="currentColor" d="M8 0a8 8 0 100 16A8 8 0 008 0z"/>
</svg>
Example my-icon.svg
using currentColor
for dynamic styling.
By setting fill="currentColor"
, the SVG will inherit the color
property from its parent element. We can then use browser.browserAction.setIcon()
with a data URI containing the modified SVG, or, more simply, use browser.browserAction.setIcon()
with a dynamically generated SVG string.
// background.js
function updateButtonColor(color) {
const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="${color}" d="M8 0a8 8 0 100 16A8 8 0 008 0z"/></svg>`;
const svgDataUri = `data:image/svg+xml;base64,${btoa(svgString)}`;
browser.browserAction.setIcon({
path: svgDataUri
});
}
// Example usage: change to red
updateButtonColor('red');
// Example usage: change to green after 3 seconds
setTimeout(() => {
updateButtonColor('green');
}, 3000);
JavaScript code to dynamically change the SVG icon's fill color.
currentColor
in your SVG and then manipulating the color
property of the icon's parent element (if accessible) is an elegant solution. However, directly generating the SVG string with the desired fill
color and setting it via setIcon
is often more straightforward for toolbar buttons.Method 2: Swapping PNG Icons
If you are using PNG icons, direct color manipulation is not possible. Instead, you'll need to prepare multiple versions of your icon, each with a different color, and then swap them out programmatically. This method is less flexible but works well for a limited number of distinct states.
{
"manifest_version": 2,
"name": "PNG Button",
"version": "1.0",
"browser_action": {
"default_icon": {
"16": "icons/default-16.png",
"32": "icons/default-32.png"
},
"default_title": "My PNG Button"
},
"permissions": ["activeTab"]
}
Example manifest.json
defining PNG icons.
You would then have icons/default-16.png
, icons/red-16.png
, icons/green-16.png
, etc., in your extension directory.
// background.js
function updateButtonIcon(iconName) {
browser.browserAction.setIcon({
path: {
"16": `icons/${iconName}-16.png`,
"32": `icons/${iconName}-32.png`
}
});
}
// Example usage: change to red icon
updateButtonIcon('red');
// Example usage: change back to default after 3 seconds
setTimeout(() => {
updateButtonIcon('default');
}, 3000);
JavaScript code to swap PNG icons based on state.
Considerations and Best Practices
When changing button colors, keep the following in mind:
- User Experience: Ensure color changes are meaningful and provide clear feedback to the user. Avoid arbitrary or confusing color shifts.
- Accessibility: Choose colors with sufficient contrast, especially if the color indicates an important state. Consider users with color blindness.
- Performance: While icon changes are generally fast, avoid excessively frequent updates that might consume resources.
- Manifest V3: The examples provided are compatible with Manifest V2. For Manifest V3, the core
browser.browserAction.setIcon
API remains the same, but background script execution contexts might differ (e.g., service workers instead of persistent background pages).
1. Define your icon in manifest.json
Choose between SVG (recommended for dynamic coloring) or PNG. Specify the default_icon
property under browser_action
.
2. Prepare your icon files
For SVG, ensure it uses fill="currentColor"
or is structured to accept dynamic fill
values. For PNG, create different color versions.
3. Implement color change logic in background.js
Use browser.browserAction.setIcon()
to update the icon. For SVG, generate a data URI with the desired color. For PNG, provide the path to the new icon file.
4. Trigger the color change
Call your update function based on extension logic, user interaction, or specific events.