Dynamically Change PNG Icon Colours for Mouseover Effects
Tags: webdev, frontend, tutorial
Published: 2024-03-06 13:00:00

We previously looked at how we can dynamically change the colours within an SVG image in a Web app. This can be useful for several reasons, ranging from app theming to special effects to improving overall usability.

But what if you’re not using SVGs? If you’re using bitmap graphics – whether JPG, PNG, or something else – it’s not possible to update the colours of image elements in the same way. However, there are a few things we can do. In this week’s article, we’ll look at one possible option.

## Using One Image per State

### Hover States

Let’s say we have an app, and we want one of its buttons to have an icon of an arrow pointing leftwards. We want it to be grey, until the mouse pointer moves over it. When that happens, we want it to be blue – to show the button is clickable.

We can achieve this by creating two versions of the arrow and saving them as separate images – one where the arrow is grey (Image 1), and one where it’s blue (Image 2).

![A grey arrow pointing left](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/au462bl572li6tikq8qk.png)

<figcaption>
Image 1: A grey arrow pointing left
</figcaption>

![A blue arrow pointing left](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dlfexlk4jsqsisq3jqxd.png)

<figcaption>
Image 2: A blue version of the arrow shown in Image 1
</figcaption>

In our app, we can use CSS to show a different image depending on whether the mouse pointer is over the button or not. The following example creates a simple Web page with a single button. The button shows the grey arrow unless the mouse is hovered over it, at which point it shows the blue arrow.

``` html
<!doctype html>
<html lang="en-US">

<head>
  <title>Image Demo</title>
  <link rel="stylesheet" href="styles.css">
</head>

<body>
  <button>
    <img>
  </button>
</body>

</html>
```

``` css
button {
  img {
    content:url(../Images/arrow-grey.png);
  
    &:hover {
      content:url(../Images/arrow-blue.png);
    }
  }
}
```

### Theming
In addition to hover states, we can also use this technique (of having an image per state) for theming. Let’s say we have a light theme and a dark theme. The icons need to be visible when using either, so we want the light theme to use a set of dark-coloured icons against light backgrounds. Similarly, the dark theme should use a set of light icons against dark backgrounds.

If we have a separate stylesheet – or simply use different sections within the same one – for each theme, we can modify the paths to our icon files accordingly.

``` css
.dark {
  button {
    img {
      background-color: #222;
      content:url(../Images/arrow-light.png);
    }
  }
}

.light {
  button {
    img {
      background-color: #eee;
      content:url(../Images/arrow-dark.png);
    }
  }
}
```

### Pros and Cons
Having a different image for each icon variation comes with its disadvantages. Because each version needs its own image, it means our projects end up with more files. This can complicate both management and deployment:

* The app’s download size potentially increases. The change may be small, but the difference could be noticeable.

* A change in colour scheme means recreating and replacing an entire set of icons.

* The project becomes more difficult to navigate in source form.

* There are more files to keep track of.

However, capturing exactly how each icon should appear in each state means we have a bit more flexibility:

* We can then tweak their appearance until pixel perfect.

* We can apply advanced image-editing techniques and special effects.

* Effects are applied directly to and captured within the image: they’ll look the same in any browser.

## Summary

When building an app, you can’t selectively change colours in a bitmap in real time like you can with an SVG. One workaround is using different images.

With this approach, you can still use CSS to define themes and mouse-over states. But the downside is that you end up with more files to manage. This can make a project more difficult to navigate and create more work if you ever need to update any of its colours.

However, you gain some flexibility by doing so. You can edit and tweak each image until you’re happy with it, and you can be sure it’ll look the same in any browser.

---

Thanks for reading!

This article is from my [newsletter](https://webdeveloperdiary.substack.com/?sd=pf). If you found it useful, please consider subscribing. You’ll get more articles like this delivered straight to your inbox (once per week), plus bonus developer tips too!