book
book copied to clipboard
Images have a white background even with dark themes
/cc @Mark-Simulacrum
We might be able to just make the background transparent, but then the black text would be tough.
@azerupi is there even a way to switch images based on theme? That's another solution.
is there even a way to switch images based on theme?
It is feasible, but the real questions are: "is it worth it?" and "is it desirable?"
It would require a JavaScript code to run when the theme changes, scanning for images with a specific name pattern and replacing them. I guess it would add a little latency and be a pain on first load, but I don't think it's hard / complex to implement.
This would also require the writer to maintain an image for every theme.
I agree and share both concerns.
Something to consider is using SVG instead, since we could then change the styles via CSS instead of swapping images on theme change.
However, it would require redoing the current images in SVG, so that is an initial pain point.
I'm also unsure as to what browsers we are aiming to support, this site says that SVG is supported pretty much everywhere post IE 9.
Something to consider is using SVG instead, since we could then change the styles via CSS instead of swapping images on theme change.
That's interesting! But how complex would this become with images containing 3+ colors? Also, I guess this would require different CSS for every image?
The complexity factor wouldn't be too significant, but it would probably require copying a good portion of the styles for each theme/variant.
If we decide to try SVG, I can attempt to create alternatives to the current diagrams, but I have little to no experience with using it.
If we can come up with a few common elements, then we'd only need separate CSS for images that are composed not of those elements. Another thing to consider is that we can probably just do two variants of each image (light and dark) and classify the themes as such, so we wouldn't need separate styles for each theme.
I'm currently generating images with graphviz, which should be able to output SVG.
The sources are in a directory at the top-level if you want to try.
Opened #77 with the SVG output.
Ok so we have SVGs now, the next step is figuring out how to get them into the HTML in such a way as to style them with CSS and then actually style them.
From #77:
The current state is as such: In order to get the graphs looking good in both light and dark themes, I need to insert the SVG directly into the generated (HTML) file, whether by way of script or manually.
Ideally, we'd just include the generated SVG with some form of HTML
or
Hey I stumbled upon this issue and would like to work on it a bit.
One problem with styling SVG images with CSS is the fact that styles don't persist across document boundaries. Therefore it is close to impossible to style these from outside. Currently I can think of three possibilities.
-
Remove the background and just invert the image if a dark theme is selected. This would be easy for the graphviz images, but a bit more complicated if we would also want to style the screenshots from chapter 14 and 20. A more primitive solution would be to just invert the image without further modification but I would rather have a few pretty inverted image than all inverted badly.
-
Create multiple different version for each image and include the matching one using CSS or JS. This would add the burden of maintaining multiple different versions of each image and probably increase load time.
-
Embed the svg files as objects and dynamically style them. This is probably the most powerful but would require tweaks to the markdown parser etc.
Personally I would prefer the first approach as it is the easiest to maintain/implement and yields good results...
I think the third approach, but with JavaScript, would be better until there is a new web standard to allow styling/tweaking SVG from <img> tags.
- Performance impact only on users using the dark theme
- Fallback to the original SVG
- Single hack blob that can break without causing readability issues
Experiments with the approach I suggested above: https://github.com/rust-lang/book/compare/d34ea0538f9eeb7457f480fa432ff91075e0b8cf...serverwentdown:experimental-svg-inliner
I've been collaborating on a short introduction to Rust, also using mdBook, and we've reached the same issue, which I have addressed.
- As stated here, formatting SVGs with CSS cannot cross document borders.
- As with https://github.com/rust-lang/mdBook/issues/773 ,
#include-ing SVGs is a bit problematic if there are blank lines or comments. This can be addressed by removing both of these from the SVG source. - Once the SVGs can be included in the resulting HTML, it is just a matter of styling them.
- mdBook themes happily enough provide a
--bgand--fgCSS variables to match the background and foreground (text) colours - So by replacing black and white with
--fgand--bg, the SVGs can adapt to the theme.
This method requires no JS, but inlining the SVGs will lengthen initial page loading fractionally. I'm going to create a PR to this effect shortly.
I have found a very compact solution to enable SVG images to be rendered nicely with a dark theme that doesn't rely on #include or preprocessors: a small extra CSS file that sets img { color-scheme: light | dark; } appropriately, with one rule per theme, and a small modification to the SVG files that looks like this (the exact rules depend on the SVG file contents but can usually be discovered easily):
<defs>
<style>
:root { color: #1e1e1e; }
@media (prefers-color-scheme: dark) {
:root { color: #d3d3d3; }
}
</style>
</defs>
While decidedly not perfect, it's flexible and leaves the <img> tags in the source Markdown so that they can be rendered by GitHub. (And yes, the GitHub Markdown preview is legible too!)
You can see it in action in https://github.com/amaranth-lang/rfcs/commit/43f8f04e2a563381573c9e6cc9b12a67ac8f71fb.