Building dark mode on Stack Overflow
On March 30, 2020, we enabled folks to opt into a beta dark mode on Stack Overflow. Let’s talk about the work that went into it.

I’m Aaron Shekey, Stack Overflow’s principal product designer on design systems. I help design all the interface components that get assembled into new features.
First, a bit of irony. I don’t actually prefer dark user interfaces.
I often find the usable contrast to be way too low. It’s hard to use the full spectrum of colors to express your interface. It’s even harder to introduce depth with shadows and other visual cues. Light text on dark backgrounds is fatiguing to my eyes. Things that are hard to manage on light screens like simultaneous contrast is even harder to manage against dark backgrounds.
But here I am, the guy who finally shipped dark mode on Stack Overflow.
The work I’m about to talk about was never about dark mode specifically, even though countless users asked for it. By solving everything along the way to dark mode, Stack Overflow would modernize its front-end codebase, enable accessibility-conscious theming, and push for adoption of our design system. We could give our users dark mode and offer future accessibility modes for free?
Let’s do it!
Color exploration
When building our product’s original color scales, we—perhaps naively—took a single color value and modified it using Less color transformations. For example, we’d define a Less variable, @red
and darken it by 10% a few times using darken(@red, 10%)
. Then we’d tint to lighten a few times tint(@red, 10%)
at the other end of the spectrum. This would lead us to a color scale represented by @red-050
through @red-900
with 10% steps in between.
In my first explorations of what Stack Overflow would look like in dark mode, I wanted to simply test swapping the white background for black, and reversing the color scales. With this approach, @red-050
became @red-900
with the values in the middle staying pretty much the same.

This approach made everything have unusable contrast, and fell into the traps of what I dislike about dark modes in general. Pay close attention to the darkest value of red against the black background. It’s nearly indistinguishable. More on that later.

Starting with the mockup
After just diving in technically proved to be a false start, I instead chose colors by hand in my design tool of choice Figma. I could design what Stack Overflow ought to look like without concern for how the original color values would map. Reducing the overall contrast was key to preserving depth in our interface, allowing elements to cast shadows, and displaying the full spectrum of colors.

Choosing a better algorithm
After picking a lighter background for dark mode, I could then explore the color scale in a deeper manner. First, I needed to solve some of the color issues the design system inherited in light mode. At the light end of the spectrum our reds and yellows weren’t as usable as I’d liked. With some colors, the lightest value was too close to white, while others the lightest value was much too dark.

We had trouble at the darker end of the spectrum for each color. When applying @red-900
and @blue-900
to a background, these colors were indistinguishable from black and each other. We needed an algorithm that would provide colors that still read as their primary hue at the lightest and darkest values, allowing us to build components from these color values.

When creating our notices component, we couldn’t use colors from our design system. Instead, we had to eyeball custom colors.

I used Lyft’s amazing Colorbox to help normalize our colors. Instead of a naive linear scale at 10% increments, I used bezier curves—a vast improvement at the more extreme ends of the scale.

Dark versions
Once I polished our light versions, I could now explore these colors against the dark background. I would ultimately end up hand-tuning the algorithm’s output to preserve long-used brand colors at certain values. This would allow me to drop the new colors into production without too jarring a shift.

Adding the colors to Stacks
If I had any hope of shipping dark mode to Stack Overflow, I’d first need to solve dark mode using Stacks, our design system, as a sandbox.
Variables
I needed to convert static, Less-compiled hex values to runtime custom CSS properties. This meant storing our color values as var(--red-500)
instead of a static @red-500
. This was an interesting problem in our design system, and the site in general. We routinely take a single color value like @red-500
and lighten or darken for hover and focus states and things like backgrounds and border colors.
Each of our many buttons and their individual states were based on a set of transformations of a single compiled color value. It reminded me of this scene in The Big Short. “We can transform an original 10 million dollar investment into billions of dollars,” and of course the whole thing explodes.
The problem with native CSS variables is you can’t apply any type of Less transformation to them. darken(var(--red-500), 5%)
breaks the compiler since CSS variables are only evaluated at runtime.
This meant I’d need to refactor how all of our buttons were created. I’d move from:
.s-btn { color: @white; background-color: @blue-600; border: 1px solid darken(@blue-600, 5%); &:hover { background-color: darken(@blue-600, 5%); border-color: darken(@blue-600, 10%); } }
I needed to translate these to their more explicit color values as defined by our color system. Instead, it ended up looking like this:
.s-btn { color: var(--white); background-color: var(--blue-600); border: 1px solid var(--blue-700); &:hover { background-color: var(--blue-700); border-color: var(--blue-800); } }
I needed to do this across all of our Stacks components, not just the buttons. These same concepts applied across notices, popovers, modals, buttons, and links to name a few.
Browser compatibility
Oh, but wait a second. CSS variables aren’t supported by Internet Explorer 11, a browser we very much supported at the time of this exploration. Ultimately, we made the decision to drop support for IE11, ripping out all the CSS hacks we’d added over the years to get it to behave, and then shipping deprecation notices to users on IE11 urging them to install a new browser. This was not a decision we took lightly, and this prerequisite alone took weeks of refactor.
Conditional classes
With IE11 no longer holding us back, I was able to work with our colors within Stacks. I chose to enable adding the class .theme-system
to the body
element. In doing so, we’d swap our light colors for their dark equivalents behind the dark mode media query. Additionally, we could skip that media query entirely and just force the dark colors by adding .theme-dark
instead to the body
. This would allow users to see dark mode regardless of their system’s settings. My approach ended up looking like this:
body { --red-600: #c02d2e; } body.theme-system { @media (prefers-color-scheme: dark) { --red-600: #d25d5d; } } body.theme-dark { --red-600: #d25d5d; }
To offer complete flexibility, Stacks provides atomic color classes that are only applied when dark mode is enabled. You can read about Stacks CSS design choices at length at my personal portfolio. By adding .d:bg-green-100
to an element, our engineers and designers can say “In dark mode, apply a background of green 100.” Additional conditional classes allow us to drop borders, swap backgrounds, or change text colors in dark mode. Steve Schoger’s got a really great tweet demonstrating the customizations that are sometimes required for dark modes. I’ve taken lots of inspiration from Tailwind.
Documenting it
Once Stacks was in a place to ship its own dark mode, we opted to add a button on the top of the site to quickly toggle between them. Folks from Design and Engineering need to be able to switch between both views as quickly as possible.

Adding the colors to Stack Overflow
I solved all these color issues on the design system side with relative ease. Our design system’s inherited fewer mistakes from our past, making it easier to refactor with the new future in mind. In order to ship to Stack Overflow, I needed to maintain our original Less variables for backwards compatibility. This allowed us to enable dark mode on certain parts of our interface incrementally.
Since the majority of our interfaces built after 2018 use Stacks, they get dark mode and responsive layouts for free. The majority of our site, however? Not so much.
Site chrome
First, I’d need to make the largest changes I could without disrupting Stack Overflow’s default light mode. These tasks were mostly just replacing static Less variables with their CSS variable equivalents throughout the site. I first applied background-color: var(--white)
to the background of the site, replacing background-color: @white
. This would now flip most of the page appropriately. I then did this for font colors. Rinse and repeat. Mostly, this actually meant deleting a lot of CSS, since we often were over-specifying font colors on child elements when we could just inherit from the parent.
Staff shipping
Once I got the broad strokes down, I leaned on engineers Adam Lear and Nick Craver to provide a method to ship a preview of dark mode to Stack Overflow employees. This would allow our staff to opt into a woefully broken dark mode, allowing folks see how much conversion was left, but hopefully motivate them to help fix the portions of our site with the most traffic. This would let me fix the biggest barriers of the site—our existing codebase.
Buttons
If the view you’re working on is already built with Stacks, there really isn’t a ton you have to do to fix things for dark mode. You might decide we don’t actually need a border, or you want to select a slightly different shade of gray for the background. Unfortunately, for the widest majority of the site, we still weren’t relying on Stacks.
This was most obvious when it came to our buttons. Over the years, we had various implementations of buttons. The last was the most frustrating since we targeted the button element itself for styling. This means that any button
or input type="button"
on the site would get default, super specific styling from a deprecated set of styles.
This kicked off a large refactor that’s still ongoing to delete element-level references to button
in CSS, instead replacing them with their Stacks equivalent. For example, hundreds of input type="submit"
would need to be replaced with <button type="submit" class="s-btn s-btn__primary">
. To complicate things, we were often wiring up JavaScript interactivity to these visual selectors. If we changed the visual classes, it often broke what the button actually did. Across thousands of buttons, I needed to first add js-
specific classes, wire them up, and then rip out the old visuals.
This eventually got me to the point of deleting a majority of the legacy button classes, allowing our buttons to switch colors properly when dark mode was enabled—all with few regressions to the light mode of our site.
The site header
Complicating things even further, our site-wide header has several modes. Light, dark, and themed. Both Teams and our network sites force a dark appearance of the header. Additionally, our Teams have a colored bar that’s established by the Team’s avatar color. Like a lot of our components, the site header’s CSS took a single color, measured if it was light or dark, and then mutated that color through a complex set of Less functions. However, we couldn’t just rip this out and replace it with pre-baked CSS variables as we did on the design system. Our Enterprise clients actually theme their headers entirely, using a single color to generate all the custom overrides.



For the light header that we ship to Stack Overflow, we needed to find a solution to measure if our color was a CSS variable, or a static hex value. If it was a CSS variable, we’d skip the Less transformations entirely, building a header that would swap colors based on dark mode. If you passed a static Less variable instead, it’d then measure that color for lightness or darkness, and build the appropriate header.
Our approach ended up looking like this:
& when ( iscolor(@theme-topbar-background-color) ) { @theme-topbar-style: if(luma(@theme-topbar-background-color) >= 50%, light, dark); } & when not ( iscolor(@theme-topbar-background-color) ) { @theme-topbar-style: automatic; }
I’d then build the header appropriately based on automatic
, light
, or dark
.
Tags
If there’s one bit of advice I could give when designing a component—don’t add layout to your component. In other words, your context should be defining how much space is between them. Don’t bake it into your component. In Stack Overflow’s earliest iterations, it was decided that our post-tag
component would have outside margins applied to it. Like our buttons, tags ran into the same JS-targeting issue. To complicate things further, most tags were generated using a single helper method in our application.
Refactoring tags would mean swapping post-tag
for our new theme-aware s-tag
component. I’d also need to refactor our JS to target js-tag
where appropriate. I’d also need to change our tag generator method to accept arbitrary layout classes, since, in certain contexts we may want to wrap our tags in a flex layout instead of relying on (or fighting against) pre-baked margins.
Post styling
The majority of Stack Overflow is user-generated posts. These posts display Markdown as the original question body as well as answers and comments. At the time of Stack Overflow’s launch, Markdown was relatively new.
Over the years, the industry has coalesced on some standard ways of displaying things like headers and blockquotes. Dark mode was a perfect time to reconsider how we handled some of our post formatting—the most controversial being blockquotes.
We originally implemented blockquotes with an overpowering yellow background that reduced the contrast of the quote itself. The yellow was also problematic when displayed against a dark background. Ultimately, we switched to the industry-standard single gray bar to represent block quotes.
Code styling
For Stack Overflow, we very clearly have a lot of code to display. Our syntax highlighting colors used completely unbranded colors I’m pretty sure we inherited from the original syntax highlighting library we hacked in. Ultimately, I punted on a heavier redesign of syntax highlighting. Instead, I ended up shifting the existing syntax highlighting toward colors from our design system’s values, finding dark mode equivalents that didn’t make too big a change too soon.
The results

With these refactors in place, we can make larger changes with fewer regressions. We can far more easily consider extending our color palette to include high contrast accessibility modes.
Building a feature like dark mode is the result of a fundamental shift toward designing systemically at Stack Overflow. I’ve been pushing adoption of our design system over the last year, using dark mode as an opportunity to rebuild many parts of our products. This is the first of many projects to bring more accessibility to our users.
Not counting the deprecation of Internet Explorer 11, work on dark mode started in earnest in July 2019 with an exploratory pull request. Prior to that, you can see some public discussion of what it might take to build a dark mode in April 2019. A proof of concept in the production codebase was hacked together in October 2019. After at least 60 follow-up pull requests, the dark mode beta went live on March 30, 2020.
A huge thanks to the help from various folks across the organization, Adam Lear, Des Darilek, Nick Craver, Kevin Montrose, Brian Nickel, Catija, Ben Popper, Joy Liuzzo, Sara Chipps, Kristina Lustig, Jon Chan, and Ben Kelly. ✌️
Tags: bulletin, dark mode, engineering, stackoverflow
84 Comments
that’s awesome. the website seems a lot better in dark mode.
😀
It’s a tendence the darks color in design.. but is it possible to keep to white and orange?.. I think is the most representative color from stack overflow from the beginning and I remember in that time stack overflow mark tendece in design by the use of light colors 🙂
It’s amazing for having dark mode!
Any plans for all other Stack Exchange sites?
https://github.com/StylishThemes/StackOverflow-Dark
This better not be April fools
Ok, Thank you
Thanks for your nice work. It’s a pity that only Stack Overflow gets this dark mode, and not other SE network sites.
Now to an issue. For some reason, on my Chromium 79 on Xubuntu 19.04, the Stack Overflow logo in the icons of the links to Meta have too low contrast on the dark background, unlike the dark frame of your “Dark mode beta’s debut on March 30, 2020” animation. See the screenshot: https://i.imgur.com/ONNJKJT.png . This issue is easy to reproduce on Xubuntu 19.04 Live image.
I found a small bug in the User Developer Story when the description of a Position or Education is long and it gets truncated. The truncate style shows as a degrade and it doesn´t look good. It happens on Edge.
I don´t know if this is the right place to post this.
Please make it darker.
Nooooooooooooooooooooooooooooo
Sorry mods please approve thx, this is just so sentimental for me OMFG
Go to your Profile, there’s an “Ultra Dark Mode” available as well.
Just until march 5th. That “darker mode” is indeed an april´s fool joke as they stated. After that date we only have this “darker mode” that is not dark enough…
I’m already used to it. The animated gifs hurt my eyes when they flip to white.
I like dark mode, so much that in fact I always run with WHOLE system in inverted colour…!
No dark mode for mobile bah.
I want to converted my phone to dark mode .
Me too pal. Love high contrast XD
How do I turn off the dark mode and go back to the old mode?
Go to your Profile > Click on “Edit Profile and Settings” tab > Under “Site Settings” select “Preference” and you will find the theme option.
It’s in the settings, in the same spot you turn it on from.
https://stackoverflow.com/users/preferences/current
Visit your preferences page: https://stackoverflow.com/users/preferences/current. The theme options are at the top there.
https://stackoverflow.com/users/preferences/current
You can do that from user preference
https://stackoverflow.com/users/preferences/7033673
https://stackoverflow.com/users/preferences/
Edit profile and settings -> Site Settings -> Preferences
You can change the preference anytime on your user profile
Click on your profile > Edit profile and settings ( Last Tab ) > (See on the Left ) Site Settings > Preference
or
https://stackoverflow.com/users/preferences/{youruserid}
I’m that is useful, but how to switch between Dark mode to Light mode?
There’s a preference in the settings, in the same spot you turn it on from.
You need an account, then loggin , then go into the tab Edit profile and settings, finally below site settings clic on preferences
https://stackoverflow.com/users/preferences/current
Visit your preferences page: https://stackoverflow.com/users/preferences/current. The theme options are at the top there.
You can do that from user preference
https://stackoverflow.com/users/preferences/7033673
You can do so in the edit profile and settings page. Under site settings you will find the tab Preferences, where you can switch themes.
Go to your profile -> Edit profile and settings -> Preferences
Thought it was an April Fools joke, guess not :p
Few years back, I used to write an extension which could run on stackoverflow site to hide right and left feeds to get focused reading on the questions and answer. Not it’s really cool to see such features along with dark mode.
Speechless ! Kudos team !
Nice! If you have a link I’d love to see it, I naively wrote my first extension to do just that. I found the hot network questions to be too distracting.
https://addons.mozilla.org/en-US/firefox/addon/stackblocker/?src=search
This is awesome! Looks great, and I love it when engineers on other sites document what happens behind the scenes
The specific blue used in links seem a bit hard to read though. Maybe it would be better if the blue links were turned into orange instead?
Finally!
Please test this article in the dark mode 🙂 some colors sample work well only in light mode
please make it darker – this is more like gray mode.. that makes me pref. the “dark reader” extension version
To switch between Dark and Light themes go to your profile -> “Edit Profile and Setting” -> “Site Settings” group -> “Preferences” item -> There you can select the theme to use.
Link: https://stackoverflow.com/users/preferences
Loving it 😍
Very nice Blog also 👍
First feedback what could be improved: “Watched Tags” background color seems to swap my focus 🤔
This should be more highlighted
a bug: hovering over the reputation time series under profile ‘Activity’ tab shows white text on an almost white background, this is obviously difficult to read.
How to change dark mode to normal mode?
You’re going to want to check the contrast ratio of the links in the footer of this page because they’re currently failing WCAG 1.4.3 on hover.
I really hope that the light mode will also be available. Dark mode gives me headache!
Is there an URL query parameter to force dark mode on/off?
Select your dark/light mode here: https://stackoverflow.com/users/preferences
Found a bug on developer story page when I tried to edit “Manage your readings” section
here is the screenshot : https://imgur.com/knnHrCy
Love the Dark Mode! Keep up the good work! Mobile apps next, please (Android).
I need more dark :))
Looking good!
As you mentioned, there is a lot of code on stackoverflow, but the dark mode seems to have had a negative effect on the visibility of this code. Would be nice to see some improvement on this front.
It’s beatiful and useful! Tanks for your time and dedication!
The “Looking For a Job” section seems like not having applied those though.
Oh, so the indistinguishable blockquotes are YOUR fault. Good to know.
Though why you had to go ruining blockquotes on sites like English Language and Usage, which will probably never have any use for dark theming, I don’t quite understand.
I have “low-vision”, where I need high contrast to use a computer. I’m also sensitive to bright lights and even bright computer screens. An occupational nurse recommended that I try a dark-blue background with white text. I don’t know why, but for me and many others with low-vision, white text with a dark-blue background is significantly better than white text with a black background.
There is a W3C page that describes the various needs of persons with low-vision. The page is available at: w3.org/TR/low-vision-needs/
I have found that in general low-vision is consider to be low acuity, but there are other forms, such as light and contrast sensitivity, which I have difficulties with.
Great technical outline of the process for approach to UI/UX, methodical and factual.
I like dark modes in general, but not this theme.
“Reducing the overall contrast was key to preserving depth in our interface, allowing elements to cast shadows, and displaying the full spectrum of colors”
In my opinion the wrong approach. Why not throw away the shadows and instead use slightly lighter frames only? Why still wanting to go with the full spectrum of colors? These assumptions must be put in question. In my opinion, dark mode and full colors is the wrong way to approach it. It’s a failure to begin with. If you go dark mode than go for a very reduced color scheme. Gold, silver, bronze badges, why no just use one color and vary their brightness?
Red should be replaced by “super bright”. The olive box creates way too much attention to just being a box and the bright orange top that was not barely noticeable is now jumping into everyone’s face. Sorry! It’s a try, but it’s not there yet.
I want to point out a problem with mathematical expressions in PNG. Since they are black on a transparent background, they appear almost invisible. I think PNGs need to be inverted as well.
https://stackoverflow.com/tour Dark Mode on.
Text on examples are white on white background. Little glitch there.
Otherwise Dark Mode seems to work very well, and I always prefer it over Light Mode.
Thank you for it.
For me this is too bright and has not enough contrast. This may work when sitting in an office in front of a super bright retina screen but not when working mobile on a laptop. It’s a step in the right direction but I totally prefer what the Firefox Dark Reader plugin does to the site.
I can’t use dark mode on anything, no matter how pretty it looks – it gives me major eye strain and headaches. But yours does look lovely!
Dark mode is a crime against every designer in the world.
Looks ok.
But i think peoples, who want to see dark version already edited with plugins long time ago.. :X
Great job guys ! really enjoying the DARK MODE, and also love the DOOM font.
Nicely done! Very interesting to read all the work and careful consideration that went into this update.
“Looking For a Job” still in light mode + 1
Please make it darker…
Really nice job. I like the combination of dark and orange. Now I can use DarkMode on nearly every site and software I use.
What about a purple mode?
I still prefer SO in light mode, but the dark mode is nice at night. Thanks for the great write up!
Nice job, but I think your team need to take a look on this: https://twitter.com/cleitontortato/status/1245823934454550529. Look likes some kind of issue
Great job Aaron and the rest of the team!
Just a heads-up, the “Welcome back! If you found this question useful..” message still appears light.
The “we can do better” is so much better than the final result. All of the frills you desperately want to preserve actively hurt readability. I don’t care about “preserving depth in our interface, allowing elements to cast shadows,”.
How can I change dark theme to light theme?
I like old light theme
you can find it in the header of Stackoverflow, it provides 3 modes for u to switch among them
Awesome ! this feature is what i’m looking forward, it will be a nightmare when coding and read solutions on Stackoverflow with light mode at night
Its awesome. Just amazing
Hi, thanks for your nice work. is the final/alpha version of the dark mode is released? I didn’t apply the Beta version still. I guess stackoverflow is looking cool with light theme version. Gif compression between light & dark shows the dark is looking good hope we have an option in our stackoverflow account where we can toggle both modes.
It’s been about two years, have you considered adding a dark mode button to the homepage?
> “Once Stacks was in a place to ship its own dark mode, we opted to add a button on the top of the site to quickly toggle between them. Folks from Design and Engineering need to be able to switch between both views as quickly as possible .”