Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternate images based on users color preference without using JavaScript

Tags:

html

css

I have a simple static site built with HTML and CSS. Here's a snippet of the HTML code:

<body>
    <h1>My static site</h1>
    <p>This is a simplified example of my static site.</p>
    <p>I don't use PHP, JavaScript, or any other programming language</p>
    <img style="width: 40%;" src="image.png" />
</body>

In the CSS, I've set specific rules using prefers-color-scheme: dark for users who have configured their devices for dark mode:

body {
    color: #000;
    background-color: #fff;
    font-family: monospace;
    max-width: 130ex;
    margin-left:auto;
    margin-right:auto;
}

img {
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 80%;
}

@media (prefers-color-scheme: dark) {
    body {
        color: #fff;
        background-color: #000;
    }
} 

I usually aim to use images with transparencies to ensure they look good in both light and dark modes. However, for some images, this approach isn't sufficient, and they become difficult to discern in certain situations. In such cases, I resort to duplicating the image and using separate images for light and dark modes:

<img style="width: 40%;" src="image.png" />
<img style="width: 40%;" src="dark-image.png" />

light image dark image

Is there a method to specify which image to use without resorting to programming languages or cookies (perhaps through CSS)? Alternatively, is there a CSS-based approach to darken an image for dark mode without duplicating it?

Or is it necessary to implement a JavaScript solution?

like image 593
Francisco de Javier Avatar asked Dec 01 '25 07:12

Francisco de Javier


1 Answers

You can actually handle this pretty elegantly using the <picture> element with media queries. This approach works by specifying different image sources based of the user's color preference using prefers-color-scheme.

<picture>
  <!-- User prefers light mode: -->
  <source srcset="light.png" media="(prefers-color-scheme: light)"/>

  <!-- User prefers dark mode: -->
  <source srcset="dark.png"  media="(prefers-color-scheme: dark)"/>

  <!-- User has no color preference: -->
  <img src="light.png" alt="Description of what the image shows"/>
</picture>

In the snippet above, the first two <source> tags handle the switching based of the user's color preference, while the <img> tag serves as your (mandatory) fallback for browsers that don't support the color preference or when the user hasn't set one.

What's also nice about this approach, is that it's quite flexible and you can extend it to handle other media conditions like screen size or resolution, which comes in handy if you need different images for various screen sizes along with their color variants.

Another great benefit, as myf mentioned in the comments, is that it only downloads the image that's actually being used instead of downloading the hidden variants.

like image 200
Ere Männistö Avatar answered Dec 02 '25 19:12

Ere Männistö



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!