I rolled my own slide deck. Wasn't the best plan, it's really quite janky!
Click to toggle the or hover your cursor down to the bottom-left and click the Slideshow button there.
There's another hoverable button bottom-right for toggling light, dark and auto modes.
Otherwise browse around with your arrow keys and enjoy the jank!
It was made to look best at a 16:9 aspect ratio.
hello! 👋

Sara here. I'm both:
- an old hand 👌
(built websites as a teen from 1999) - and a newbie 🤯
(switched career from small-company
general engineering into web dev in 2022)
a warning
There'll some movement, animation, and abrupt changes between dark and light modes in this presentation.
If you suffer from migraines, epilepsy, or strong astigmatism
- I'm really sorry! 😓
My hope is that with the information I'm about to present, browsing the web will get ever more comfortable for everyone.
dark mode vs. light mode
We all love a good polarising argument!
But there are physical reasons to prefer one over the other.
Also, you're allowed to like light or dark themed websites better, for no good or logical reason!
Your eyes, your choice! 👀
why dark mode?
Pupils constrict when coming across a bright page.
Too much contrast with dark surroundings.
Floaters appearing and distorting or blocking vision.



why light mode?
Pupils constrict when coming across a bright page!
It's easier to focus when your pupil is smaller.
Astigmatism makes light text on dark backgrounds hard to read.
Astigmatism makes light text on dark backgrounds hard to read.







why not both?
Both!
Both.
Both is good.
*nods*

this talk's scope
Includes:
- Having your site react to
prefers-color-scheme
.- Usually the operating system's setting.
- Allowing manual toggling of
colour-scheme
.- Ignoring the OS' setting for the website.
starting from scratch
No styles, no problem!
However...
Building this into a mature site or design system may be tricky.
Harder still if everything already has specific colours assigned.
Keep it in mind for the next time that you start a new project 🌱
default HTML themes
Website name
Blog title
Blog post title
Blog post content
Comments
Website name
Blog title
Blog post title
Blog post content
Comments
color-scheme
You don't even need CSS for this!
<!-- in HTML -->
<head>
<meta name="color-scheme" content="light dark">
</head>
/* In CSS: */ :root /* or html */ { color-scheme: light dark; }
color-scheme
demo
system colors
You can apply color-scheme
to most elements.
But - they need to be assigned both a color
and background-color
first.
other system colors 🙄
How are you?
Could be worse!
It's lovely! Storm tomorrow though.

contrast too high?
Those implementing WCAG for accessibility may find it unlikely.
But some migraineurs do have trouble with this!
Alongside prefers-color-scheme
there is also
prefers-contrast
.
The simplest way to bring contrast down is with
filter: contrast()
.
bringing down contrast
Ahh thanks, this calms my eyes and brain.
color-mix()
and transparency
How are you?
Yeah good, you?
Could be worse!
Nice weather, innit?
It's lovely! Storm tomorrow.
Ooh I love a good storm!
prefers-color-scheme
This follows OS preference,
not color-scheme
property.
How are you?
Yeah good, you?
Could be worse!
Nice weather, innit?
light-dark()
Recently in all browsers,
at ~80% coverage - exciting!
How are you?
Yeah good, you?
Could be worse!
Nice weather, innit?
allow manual switching
You may not want to view a site in your OS' color scheme.
When using prefers-color-scheme
, this was a pain.
We had to override it, or double up CSS color declarations.
This is easier now! 🎉
Can we do it with CSS only? 🤔
:has()
rocks!
limitations
You get limited pretty fast by avoiding JavaScript.
Using :has()
is magical, but only per-page.
The preference doesn't get saved while browsing the site.
You can't use <buttons>
if you prefer those!
So what JavaScript do we need?
Jeremy Keith's maxim
"JavaScript should only do what only JavaScript can do."

simple functions
woo-hoo, buttons!
OK great, so now we can use buttons, but this still only works per-page, and is lost when the page is reloaded ♻️
So we need to store the preference for the user.
For this we can use sessionStorage
or localStorage
.
sessionStorage
lasts per visit to a domain. localStorage
is kept between visits until the user clears their browsing data.
saving to localStorage
show state in buttons
The three buttons are neat, but what is the current mode? 🤔
It's not too difficult to set a class with JS on the 'active' button.
Let's use the existing aria-pressed
attribute!
This is exactly what it's for, and has the benefit that a screen reader will also announce which option is currently active.
using aria-pressed
for buttons
in summary
Use color-scheme: light dark;
Use color-mix()
with Canvas & CanvasText
Start using light-dark()
!
Support user contrast preferences
Experiment and play :)
takeaway: offer choice
light mode | dark mode | |
---|---|---|
more contrast | Hi! | Hi! |
less contrast | Hi! | Hi! |
further reading
Do you know color-scheme? by me
Improved dark mode default styling with the color-scheme CSS property and the corresponding meta tag by Thomas Steiner
What I've learned about CSS color-scheme
and friends.
by Apple Annie
Color-scheme Tinkering on codepen, by me again
CSS color-scheme-dependent colors with light-dark() by Bramus
thank you!
I'm so happy to be taking part in the Hamburger DevFest!
🙏💖⚓
🏠 sarajoy.dev
👋 @sarajw@front-end.social
🛝 (slides) devfest2024hh.sarajoy.dev