Dark mode toggles: two states are enough
Yes, the underlying model must have three states, but one is always irrelevant to the actual user goal. Users do not seek out solutions to problems they don’t currently have. A lot of the hate towards two-state toggles is based on poor implementations.
A good two-state toggle can actually express all three data model states.
Until recently, if you looked at most websites with a theme toggle[1]Unless otherwise noted, this refers to a permanently visible toggle in the header or (rarely) footer, not a theme setting in a separate settings panel. , you’d find three options: Light, Dark, and System.

Examples of tri-state dark mode toggles. In (LTR) reading direction: Ant Design, Red Hat Design System, Web Awesome, Excalidraw, Taiga, Astro, Hero UI.
Thankfully, these days the trend has shifted towards a simpler two-state toggle, but tri-state ones are still incredibly common.

Examples of two-state dark mode toggles. In (LTR) reading direction: Vitepress, Material Design, Adobe Spectrum, Radix, ShadCN.
The rationale sounds plausible: “System” is a different intent than “Light” or “Dark”! One is a policy (whatever my OS says, do that) The other is a value (dark, forever, I don’t care what my OS says.) Surely, users should be able to express that intent!
Except, real users don’t generally seek out dark mode toggles to express intent for things to stay as they are, they seek them out when things need to change.
Think of the user goal when browsing a website (as opposed to a separate Settings page, where three states are fine).
E.g. on a documentation site, they may be there to look something up.
On a landing page, they may be trying to evaluate whether the product is suitable for their needs.
On a media site, they may be there to read the news.
On a graphics app, they want to draw something.
One thing is for certain: tweaking the theme is not their primary goal [2]This is about users. Yes, the developers of the site may have a goal of testing the theme, but we optimize UIs for being used, not getting debugged. . To get in the mindset of tweaking the theme, something needs to be off. When things look right, users just move on with their actual goal instead of thinking about the theme.
The tri-state control is solving a largely imaginary user goal that is extremely rare among real users, and does not justify the additional complication and UX friction of a three-state toggle.
Worse, it forces the user to decide between choices that produce no visible difference, breaking the principle of feedback.
Yes, tri-state toggles are common. That doesn’t make them good. This essay explains why, and how to do better.
2 footnotes
Unless otherwise noted, this refers to a permanently visible toggle in the header or (rarely) footer, not a theme setting in a separate settings panel. ↩︎
This is about users. Yes, the developers of the site may have a goal of testing the theme, but we optimize UIs for being used, not getting debugged. ↩︎