Hacker News new | past | comments | ask | show | jobs | submit login
Inlining SVGs for Dark Mode (ahelwer.ca)
51 points by ahelwer on April 6, 2023 | hide | past | favorite | 16 comments



My approach is to use CSS for my SVG.

A D3 diagram uses:

   @media (prefers-color-scheme: light) {
      :root {
         --node-text: #444;
         --tree-buttons: darkred;
         --edge: #ddd;
         --edge-temp: red;
         --file-buttons: darkblue;
         --footer-labels: darkblue;
      }
   }

   .node text {
     font: 10px sans-serif;
     fill: var(--node-text);
   }

   .link {
     fill: none;
     stroke: var(--edge);
     stroke-width: 1px;
   }

For icons, I usually do this

   @media (prefers-color-scheme: light) {
     :root {

    /* 
      Styles for plus/minus in front of tree param nodes. 
      Note that currentColor doesn't work when using url(data:) so color is specified - copy of text-color with # escaped.
      TODO: figure out a way to share these 
    */
    --collapsed: url('data:image/svg+xml,<svg fill="red" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><g stroke="%23111" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></g></svg>');
    --expanded: url('data:image/svg+xml,<svg fill="red" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><g stroke="%23111" stroke-width="2"><line x1="5" y1="12" x2="19" y2="12"></line></g></svg>');*


SVGs and JS are a very good pairing, I have lots of fun drawing graphs & charts. What I enjoy most is with dynamic resizing, you can scale the SVG coordinate space to match the screen pixel space, so `stroke-width: 1px` is meaningful / accurate. Combine it with %-based coordinates and you get snappy perf + good looks


Recently undertook a similar effort on my blog[0], but I took a different route. Instead of using currentColor, I embedded an image-specific `<style>` declaration directly in the SVG file.

Upsides: the SVG is more portable, it's more self-contained, and I can be sure that, irrespective of how much I customize a given image for dark/light mode, those styles will always be declared in the same place -- right in the file.

Downsides: style declarations are repeated across SVG files, which, when I inevitably update the site's design, will mean that I'll have to do some manual editing. SVG debt.

0: Example here: https://ft.io/blog/shift-left/


> Downsides: style declarations are repeated across SVG files, which, when I inevitably update the site's design, will mean that I'll have to do some manual editing. SVG debt.

Seems like this should be possible to roll into a compile step, defining the style in one place and letting the SSG/bundler/etc copy it into your SVGs.


Sure would be nice if image elements passed down currentColor.


The article mentions it, but I've never known whether svg <title> attributes were screen-reader accessible, which is why I've always gone the poor-man's route and created a component (React or Web, depending on the project) that just swapped the color prop on an Image tag.

It generally works fine, despite the extra work, but I've always hated the extra work for being slightly more stupid than I want to put my name to.


Yes, for inline SVGs, putting its text alternative in its <title> element is well-supported. See Pattern #5 in this excellent article [0] by Carie Fisher.

That's a separate issue from ensuring an inline SVG is still visible regardless of a site's dark or light mode or visible when a user uses their device's Contrast theme (aka `forced-color`).

[0] https://www.smashingmagazine.com/2021/05/accessible-svg-patt...


Thank you


D2 is a text-to-diagram language that can do this out of the box for you:

https://d2lang.com/blog/dark-mode/


I know people say dark mode is an accessibility feature. Is the same true of light mode? Or should we just always use dark mode?


https://www.nngroup.com/articles/dark-mode/ is a literature review:

> Summary: In people with normal vision (or corrected-to-normal vision), visual performance tends to be better with light mode, whereas some people with cataract and related disorders may perform better with dark mode. On the flip side, long-term reading in light mode may be associated with myopia.

What is seldom discussed is the different types of dark modes, which are quite radically different in their appearance, purposes, pros and cons (unlike light mode, which is much less variable, and where there is marked variation it’s seldom for any particularly good reason). I wrote a bit about the three or four categories I’ve settled on a couple of years ago: https://news.ycombinator.com/item?id=28516862. It depends heavily on what you’re trying to achieve (æsthetics/low-contrast or accessibility), and the ambient lighting conditions and specific screen technology (both statically unknowable).

All up, dark mode is actually pretty risky, surprisingly so, because it can actually be at least three radically different and incompatible things. If you implement only one, go light.


100% this. I have severe issues personally reading dark-themed sites to the point where I just have to give up on many sites that are locked as dark only, or require a login or clicking an obscure button to change a theme preference which I can't locate.


Yes, the same is true for light mode, some people find dark mode sites harder to read.

Even for users who need light-on-dark, they may want individual sites light-on-dark if they have other sites or apps they have to use that don't have a dark mode so the user inverts the colors on the whole display.


People with astigmatism often find that light text against a dark background end up looking blurry. I don’t think that dark mode is any more beneficial than light mode. I don’t like living in a dim dark room just so that dark mode looks reasonable.


I chuckled at SVG being called human readable.


why do programmers prefer dark mode?

because light attracts bugs.

— chatgpt




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: