Auto-adaptive images [for dark / light theme]

I always want to have images that will adapt to the dark or white theme. But with JPEG files it is more the dream. Nevertheless I found one interesting hack that you can make something like that.

INPUT

The source images are JPG files white white background.

OUTPUT (Light | Dark theme)

HOW TO REPLICATE

“Adaptive inversion”

![[image.jpg#invert_B]] - use when image (mostly white) > fits for dark theme
![[image.jpg#invert_W]] - use when image (mostly black) > fits for light theme

“Adaptive inversion” + Contrast

![[image.jpg#invert_B_C]] - image (mostly white) > fits for dark theme + add contrast
![[image.jpg#invert_W_C]] - image (mostly black) > fits for light theme + add contrast

2. Add this CSS snippet

/* General and default image blending */

.theme-dark img {
    display: block;
    max-width: 80%;
    padding: 0 auto 0 auto;
    outline: none;
    margin-left: auto;
    margin-right: auto;
    mix-blend-mode: screen;
    filter: opacity(1);
}

.theme-light img {
    display: block;
    max-width: 80%;
    padding: 0 auto 0 auto;
    outline: none;
    margin-left: auto;
    margin-right: auto;
    mix-blend-mode: multiply;
    filter: opacity(0.95);
}

/*Emblemed images blending tweaks */

.theme-dark .popover.hover-popover .markdown-preview-view img {
    mix-blend-mode: screen;
    /*filter: opacity(1);*/
}

.theme-light .popover.hover-popover .markdown-preview-view img {
    mix-blend-mode: multiply;
    /*filter: opacity(0.95);*/
}

/* Image dynamic colors inversion */

.theme-dark span[src$="invert_B"] img{
  filter: invert(1) hue-rotate(180deg);
}

.theme-light span[src$="#invert_W"] img{
  filter: invert(1) hue-rotate(180deg);
}
.theme-dark span[src$="invert_B_C"] img{
  filter: invert(1) hue-rotate(180deg) contrast(1.5);
}

.theme-light span[src$="#invert_W_C"] img{
  filter: invert(1) hue-rotate(180deg) contrast(1.45);
}

  • The “Image dynamic colors inversion” part in CSS is doing the magic
  • You need to decide which images should be inverted -as for photos the result looks funny!
  • As extra I included the blending of the image into background but this im using as default for all images in my theme: Suddha theme v.1.2 [update for Obsidian v0.10.11+]
19 Likes

This is fantastic!
Great work :+1:

1 Like

Man, this is fantastic work Den.
You really are a life savior.
This should be one of the most talked about snippets.
Thanks a million sir. Keep up the good work. The blending of image background into the primary background of the theme is phenomenal.

Update:
Just found that Image zoom: click + hold to expand images is now completely broken with this snippet is there a way to fix it ?

Doesn’t work for ![](https://i.imgur.com/JWrTgs0.png) kind of image embeds.

1 Like

It works with transparent .svg file in light and dark mode too, thank you so much.

I just followed your instructions:

  1. copied your css code (above in this thread)
  2. pasted it into css-snippet
  3. placed a transparent .svg-file (diagram with black lines) in an obsidian note with a wiki-image-link: ![[image.svg#invert_B]]

Done!

Nor does it work in Live Preview or an embedded Excalidraw file (the hash makes it look for a section).

Any way to exchange # for something else here?

What about making it work with non-Wikilinked image references?

Also, images without desired modification come out washed, including my Dashboard banner image.
Had to disable the snippet, alas.

**bump**

I successfully got the solution: ![$caption#invert]($filepath), here is an example:
![StringBuilder#invert](StringBuilder.png)

1 Like

Great code. I noticed that this only works in reading mode and not in editing mode. I fiddled with it, and using the image alt instead of source makes the changes in both reading and editing mode.

Also, since spans are rendered in the reading mode, you’d have to refer directly to the img tag. The image alt is the source by default. So:

img[alt$="invert_B"]{

  filter: invert(1) hue-rotate(180deg);

}
2 Likes

I had to make an account just so I could upvote this. Works great!

Update - I noticed that this snippet interferes with the CSS in the Banner-plugin (filename became visible in the banner image). Solved (kind of ) by removing the mix-blend-mode for theme-dark and .theme-light

Anyone wanting this to work while not in reading view.
In the snippet add the same css for the div element and not just the span!

I adapted it into a minimal CSS snippet.
The original didn’t work in preview mode, and this does.

.theme-dark img[alt$="invert_dark"] {
  filter: invert(1);
}

.theme-light img[alt$="#invert_light"] {
  filter: invert(1);
}

Usage:

![[dark_image.png#invert_dark]]
![[light_image.png#invert_light]]
3 Likes