Change the color of a webpage dynamically using JS and CSS
By Flavio Copes
Learn how to change a web page colors on the fly with JavaScript and the CSS filter property, switching between pastel, grayscale, and normal modes.
You can change the colors of an entire web page at runtime by setting the CSS filter property on the html element with JavaScript. One line of JS is enough to make the whole page grayscale, or to soften its colors into a pastel look.
The filter property applies visual effects like grayscale(), saturate(), brightness() and blur() to an element and everything inside it. Apply it to the root element, and the whole page changes.
Here’s a set of buttons that switch between three modes. Each click handler sets style.filter on the root element:
<button type="button" id="pastel">pastel</button>
<button type="button" id="grayscale">grayscale</button>
<button type="button" id="normal">normal</button>
const root = document.querySelector('html')
document.querySelector('#pastel').addEventListener('click', () => {
root.style.filter = 'saturate(60%) brightness(80%)'
})
document.querySelector('#grayscale').addEventListener('click', () => {
root.style.filter = 'grayscale(100%)'
})
document.querySelector('#normal').addEventListener('click', () => {
root.style.filter = ''
})
The pastel mode combines two filters. saturate(60%) reduces how vivid the colors are, and brightness(80%) darkens the page a bit. grayscale(100%) removes color entirely. An empty filter restores the page to normal.
Avoid javascript: URLs in links. They are awkward for accessibility, and a strict Content Security Policy blocks them (more on this in links used to run JavaScript). Also avoid replacing the whole style attribute with setAttribute('style', ...): that wipes any other inline styles on the element. Setting style.filter only touches the filter.
When is this useful?
I’ve used this trick to preview how a design reads without color, which is a quick accessibility check. It’s also a fast way to build a “reading mode” or a low-stimulation theme without touching every color in your stylesheet. Related: how to add a simple dark mode.
One thing to watch out for
Be careful with position: fixed elements. When an element has a filter applied, it becomes the containing block for its fixed-position descendants. A navbar that used to stick to the viewport now sticks to the filtered element instead.
If that happens, apply the filter to a wrapper div that contains your content but not the fixed elements, instead of applying it to html.
Want me to talk about your product? You can sponsor this site.
Related posts about js: