5 posts on Product Design

The best dark mode toggle is probably none

13 min read Report broken page

My post on two-state dark mode toggles sparked a lot of discussion about the optimal dark mode toggle design. But should you have a (persistent) dark mode toggle at all? I have since been convinced that for most websites, the answer is no.

About a month ago, I wrote an article recommending that if you are going to have an always visible control for switching between light and dark mode, it should be a two-state toggle that alternates between system and whatever the current opposite of system is, not a tri-state one (system, light, dark). If you are forced to include such a control (say, someone is pointing a gun at you and shouting “code dammit! now!”), I stand by that recommendation: use two states, as described in the article.

But the article explicitly doesn’t answer the question “should you have one at all?”. I was much more neutral on this at the time of writing. I am now firmly in the “no” camp. More on that below.

The two-state toggle design proposed in my article can actually express all three data model states.

What I didn’t mention was that I had been meaning to write this article for years, but had been putting it off. What finally pushed me to write it 1Unlike Devographics, surveys are not FA’s core business, so the Impact/Effort tradeoff simply wasn’t there for a custom UI, at least at this point in time. I ended up going with Tally, mainly due to the flexibility of its conditional logic and its support for code injection (which among other things, allowed me to use FA icons — a whopping 120 different ones!). was that Bramus argued that some Modern Web Guidance I had written on this was incorrect. He assumed it was an oversight, that I simply hadn’t thought of all the implications. On the contrary, my recommendation had been the result of some very careful consideration, combined with my HCI background. Surely, if I explained my reasoning well, he would see it!

I tried to convince him through discussion (in person, as we were both in Berlin at the time) to no avail. My conclusion was that I must be doing a poor job explaining my reasoning, and that a blog post was in order to explain it properly. Surely, after that he would be convinced!

And thus, one of my most successful blog posts was born.

Reactions

This article really made the rounds. It was shared by hundreds of folks, including people I really respect, such as:

and many others. A lot more who hearted it.

Some of the quotes really made me blush ☺️. Here is a small selection:

I wasn't sold on this until I got to the implementation. It's so smart I'm probably gonna spend my day redesigning at least one or two of the theme toggles I've built.

[image or embed]

— Josh Collinsworth (@collinsworth.dev) August 6, 2026 at 4:30 PM

This is one of the best articles I've seen about the difference between letting the underlying settings dictate the structure of your UI, and thinking about what actually makes sense to your users. Really, really insightful, and definitely worth ten minutes of your time.

[image or embed]

— Dylan Beattie (@dylanbeatt.ie) August 6, 2026 at 4:43 PM

Once upon a time web developers regularly wrote blog posts about UX design that were this good. Thank you to @lea.verou.me for keeping the art alive.

[image or embed]

— Sam Littlefair (@littlefair.ca) August 6, 2026 at 6:19 PM

OK, I'm persuaded. For a toggle in the header or footer, a toggle between 'system colour scheme' ↔️ 'the opposite' is better than system ↔️ light ↔️ dark.

Lea is a master of user experience.

[image or embed]

— Josh Tumath (@joshtumath.uk) August 7, 2026 at 2:19 AM

This is a great post to read, lots of useful UX and usability thoughts. I like this approach.

[image or embed]

— Ahmad Shadeed (@ishadeed.com) August 7, 2026 at 11:09 AM

Really, really appreciate the deep thinking about the user's _actual_ needs and intentions, irrespective of conventions and commonalities, in this brilliant piece. 👌

[image or embed]

— sylvia (@svillegas.com) August 12, 2026 at 9:12 PM

Articles were written, for and against it. This is a small sample (I couldn’t find most of them):

Unfortunately, I failed to convince Bramus, who two weeks later wrote a blog post of his own 😢

Bramus’ objections

Bramus’s central objection to the two-state toggle is this:

Consider this scenario:

  1. The user’s OS is set to auto-switch Light/Dark based on the time of day.
  2. They visit a website during the day, so they see the Light theme.
  3. Using the site’s two-state control, they try out the Dark theme. They decide they don’t like it, so they revert it back to Light.
  4. They visit the site again at night.

Because the two-state toggle maps one of its values back to “System” behind the scenes, the site is now dark, although they explicitly chose light the last time they interacted with the control. You may now expect an incoming bug report for the control not properly working …

His reasoning is that a tri-state control sidesteps this by letting users pin light or dark explicitly at all times, which he also considers clearer overall, since all three options are always visible.

An easily-misread framing: auto-switching by time of day works fine

In both of his posts, Bramus initially frames the disagreement as “this will not work for users that have their system set to automatically switch to dark mode at night”, which is false: it will work just fine. The control covers all three intents with a single click. Not a single click per session — a single click, ever. The variable is around when that click happens. In fact, I dedicated a whole section to this exact scenario in the original article, which he acknowledges but says he’s “not buying it”.

He does later explain what he sees as broken in more detail, but since most people do not read very carefully, there were a couple people who agreed thinking the two-state toggle I was proposing is somehow broken for auto-switching systems.

His poll asks the wrong population the wrong question

Bramus asked developers which control they build, then used the tally as evidence for which control is usable!

Those are different questions. Developer preference is confounded with convention and implementation convenience. If asking developers what they build gave us data on what UI is most usable, we wouldn’t need user testing, ever 😅

We optimize UIs around user goals, not around developer preferences. In fact, more often than not there is a tension between what is easiest to build and what is optimal for usability, because usability is all about abstracting the underlying model (which is closer to the machine), and exposing a model that is closer to how the user thinks.

“Local feedback” doesn’t solve the gulf of evaluation

Responding to the objection that two of the three options produce the same visual result, Bramus writes that

“the selected option does change so there is local visual feedback.”

Sure, the button highlights, and that’s better than if nothing happened at all. But the button is the means, not the end. The user clicked it to change the page, not the button!

When the control changes and the page doesn’t, the user acted and the world didn’t respond — that’s Norman’s gulf of evaluation. Widget feedback with an unchanged outcome is the failure, not a mitigation of it. It’s also why NN/g’s toggle guidelines insist a toggle has an immediate, visible effect.

Implementation simplicity != cognitive load

Bramus says:

“there is nothing complex about a tri-state control” […] it’s “the Dumbest Approach™ one could possibly take.”

Yes, it is — that was exactly my point when I wrote that tri-state toggles are implementation-driven UI. The actual user goal in the moment is not abstract (“system” is a variable, not a value), it is concrete (light or dark). Using a tri-state control involves a mental translation from the three states to the actual user goal. It’s of course very short, almost imperceptible to users — but avoiding this type of unnecessary mental processing was exactly the point of Don’t Make Me Think — which ironically Bramus cites to support his argument.

“Clarity over brevity” is one of these platitudes that everyone agrees with 2I even did an entire talk about it at Web Unleashed, with a lot more technical detail than what I have included here. , but people use it to support even entirely contradictory positions. Whenever I see one of these, my tendency is to prod deeper; clarity about what? Clarity about the implementation’s state machine is not clarity about outcome. The tri-state is optimized for people who already hold the system model — which is, again, developers.

The failure scenario is rare, and recovery is cheap

Bramus’ central objection is that with a two-state control, forcing a mode “shouldn’t be dependent on the time of the day.” The scenario he gives requires OS auto-switching, plus toggling and reverting within a session, plus revisiting after the switch, plus remembering the earlier interaction.

Usability problems are prioritized by frequency × impact × persistence, and this scenario scores low on all three. The tri-state, by contrast, taxes every interaction with a state most users never need. Optimizing the common path over a rare, cheaply recoverable edge case is not an antipattern, it’s precisely how usability engineering is supposed to work!

“Once a user has interacted with a control, they have mentally set it to the specific state”

People don’t remember settings on sites they rarely visit. For them, a site that tracks the OS matches expectations; a stale override fighting the OS is the actual surprise (“why is this site light at night?”). And in practice no user devotes nearly as many cycles contemplating why the theme of a website they visited to accomplish a task matches or doesn’t match their OS, at most they just toggle and move on. It’s not even System 2 thinking. If there is a recurring problem, sure, they may think about it more consciously, a few may even report a bug. But something that’s fixed with a single click, in a very obvious way? It might not even surface to the conscious mind.

Bramus himself admits that his scenario is purely theoretical; he has never experienced it himself nor seen anyone else experience it.

Once you’ve spent a lot of time and effort on something, you overestimate how much it matters to everyone else. This is true not just in UI design, but in all aspects of life, from any areas you’re an expert in to even your kids 4Originally dubbed “Lea’s proposal”, and later “Non-letter start proposal”, but became known as Option 3 from its position among the five options considered (including the original syntax). . Developers have spent days on this control, users will spend half a second at most. It’s the IKEA effect meeting the false-consensus effect: you overvalue what you built, then assume users do too.

Alternative designs

My favorite part of the debate was that it spawned a number of alternative designs.

Some people were divided. They agreed with the reasoning, but still thought a tri-state toggle added clarity. So naturally, they did what UI designers do best: they designed, and the results are quite clever.

Others took a different, hilarious tack on the problem, and attempted to imagine the worst possible dark mode toggles.

Lawful Good 😇

Vale’s 3-in-2 toggle

The alternative that made the rounds most is Vale’s innovative design:

System Light Dark

The core premise is quite clever: Three states with the real estate of two icons (33% saving over the typical tri-state control — though still double that of a two-state control), and clarity about whether you’re selecting system or pinning a mode that happens to coincide with your current system setting.

However:

  • As Vale themselves admit, some users did not realize they could revert the option they had selected, simply because that’s not a common interaction pattern. Vale does say this was a minority of users, and that it was “immediately understood by the great majority of people [they] tested it with”, however I have doubts on whether this would hold true in the wild, when you haven’t already primed users to pay extra attention to the dark mode toggle.
  • Vale claims that “It only takes up the space of a two-state toggle”, but that’s not true. A two-state dark mode toggle only needs the real estate of one icon, not two. It’s possible to implement one that shows both icons simultaneously, but that’s rare.
  • In its default state, nothing communicates “system”. It is two icons with no indication of which is currently active. We understand that it’s a dark mode toggle, because it’s presented in isolation, in the context of an article about dark mode toggles. But used on an actual website, I wouldn’t be surprised if users had no idea how to use it and only figured it out by trial and error. Subtly highlighting what System currently resolves to could help here, but then we’re back distinguishing whether “light” means “System (light)” or “Light, always”.

But most importantly, this is adding significant implementation and UI complexity for something that the vast majority of users don’t devote nearly as much thought to as we think they do. In my opinion, this is admirable effort that is ultimately solving a non-problem.

Toni’s undoable two-state toggle

This is also quite interesting:

i feel this is a good trade off if you want to give users the most control, even though i see your point that this is possibly too niche of an edge case to justify.

did i do the UX version of premature optimization, or does this just suck too?

[image or embed]

— toni / link (@sarcevic.dev) August 9, 2026 at 2:49 AM

It’s a two-state toggle that pins light/dark when interacted with, but provides a clear button. This is similar to Bramus’ idea but with more polish.

As I said on bsky, I don’t think this particular design works because:

  • Spacing makes it look like these are separate controls, not one clearing the other’s selection
  • The clear button has nothing associating it with the color scheme toggle (not proximity, nor its icon).

But none of these are core to the idea, and could be fixed with a little more UI design massaging. If someone really wanted to have three states visible at all times, a reworked version of this would probably be the best way (and can be designed to occupy similar screen real estate as a two-state toggle).

Should anyone spend the time to do this rework? Like I wrote in the previous section, my opinion is that these efforts are pouring a great amount of brilliant creative energy into solving a non-problem, so I would not recommend it.

Chaotic Evil 😈

The Big Dark Mode Toggle Debate™ raged on for weeks, and I think my favorite part of it was the side thread of people taking the piss and coming up with the worst possible dark mode toggle designs imaginable 😅, possibly as a tribute or reprise of The Worst volume control UI.

I reject your two-state toggle and submit my own 4-state toggle. Pray that I do not increase it to 5.

[image or embed]

— Michael Ficarra (@michael.ficarra.me) August 6, 2026 at 5:02 PM



[image or embed]

— Michael Ficarra (@michael.ficarra.me) August 6, 2026 at 5:13 PM



[image or embed]

— Michael Ficarra (@michael.ficarra.me) August 6, 2026 at 5:18 PM

Of course, I had to participate:

Oh but why stop there? 🤣

[image or embed]

— Lea Verou, PhD (@lea.verou.me) August 6, 2026 at 5:25 PM

I actually strive for perfect clarity with my color theme pickers.

codepen.io/editor/chris

[image or embed]

— Chris Coyier (@chriscoyier.net) August 23, 2026 at 5:51 PM

Did anyone already mention "Dark mode with spotLight"? No!? That's the only valid way.

Demo: codepen.io/t_afif/pen/Y… via @codepen.io

Debating about toggles? Well, I don't understand …

[image or embed]

— CSS by T. Afif (@css-only.dev) August 24, 2026 at 1:36 PM

Anything below 4 is unacceptable. right @svenning.io

[image or embed]

— Andreas Møller (@andreasmoller.dk) August 22, 2026 at 12:05 PM

This may be my favorite:

The current debate between 2 vs 3 state theme switchers is ridiculous. Everyone knows that the right answer is 100

#css #a11y

[image or embed]

— Andreas Møller (@andreasmoller.dk) August 22, 2026 at 11:59 AM

Two-state, tri-state, four-state...why should we concern ourselves with this anyway? I say users should not get this for free at all; therefore, I introduced a new mode in this article called capitalism mode ✅

codepen.io/editor/sunka

#css

[image or embed]

— Sunkanmi Fafowora (@sunkanmifafowora.bsky.social) August 26, 2026 at 1:33 AM

Could the best dark mode toggle be …none?

However, my biggest insight from all of this is that while I stand by my original recommendation that in most cases, if you are going to have a dark mode toggle that is visible at all times, it should only have two states (system and opposite), I now think that for the vast majority of websites, you should not have such a toggle at all.

Follow system as the default, and if need be have a separate settings panel (even if it’s not actually implemented as a separate page but just an overlay) and put it there. It simply doesn’t warrant permanent screen real estate for the vast majority of users.

The eye-opening moment was when I sent my post to a colleague who is also an HCI PhD, to get their feedback on whether my reasoning was sound, or whether I had any blind spots. For background, this was someone who was much less immersed in the technical weeds of the Web — their work centers more around humans than around deep technical details.

I expected either agreement or constructive criticism, but what I got was much more eye-opening: It turned out that they had no idea what control the article was talking about! Folks, …they had never seen a dark mode toggle!5or — perhaps more likely — never paid attention to one

And then it dawned on me: all these persistent dark mode toggles I had seen, literally all of them have been on developer-facing sites!

I could not think of a single well-known consumer-facing site with a persistent dark mode toggle. All consumer-facing websites that supported this functionality displayed it in a separate settings panel (which is a different use case). Even those which people spend hours a day using, like Gmail, Facebook, BlueSky, etc. None of them see this as a use case that deserves precious header real estate.

Wikipedia with the settings panel expanded

Wikipedia does show this sidebar by default on large enough viewports, but this is not an exception — just an auto-expanded settings panel.

Now, this alone is not evidence that dark mode toggles are a bad idea. A pattern can be widespread and still suffer from poor usability. And every UX innovation started off not being popular, so the reverse doesn’t hold either: a pattern can be unpopular and still be good. But in this case, I think they’re right. It suddenly all made sense to me: this doesn’t matter nearly as much to the average user as it does to us developers.

To be clear: “always light/dark, even against the OS” is a legitimate intent! But it is also a relatively rare one, and rare intents belong behind progressive disclosure — a settings surface — not in the one control every visitor sees.

In a textbook case of false-consensus bias, we have been so focused on our debugging needs that we convinced ourselves this is top of mind for the average user.

When is a persistent dark mode toggle a good idea?

A corollary from the reasoning above is that a dark mode toggle is a good idea when the website is developer-facing or developer-adjacent (e.g. a site for designers).

Experimental validation

Usability is a property of user outcomes, and no users were observed in any of this. Even my own article was derived from first principles and my experience observing users, but no actual observations of users interacting with dark mode toggles were made.

Per the previous section, I’m not convinced this is a problem worth solving. That said, if we do want to solve it, the best answer is obviously to get data from real user interactions.

However, there is a caveat here: qualitative user testing6The kind where you get a few users and observe them using the UI to accomplish a task — i.e. what most people refer to as just “user testing” is less useful for infrequent microinteractions like this one.

Think about it: how would you design a meaningful qualitative experiment? At best, each participant would only interact with the toggle once. Most wouldn’t click it at all, unless the experiment was designed to show a website where the OS default theme is awful, which generalizes poorly.

Another easy bias in a controlled experiment is that it’s easy to bias the results by drawing attention to things that users would otherwise pay much less attention to. E.g. Vale wrote that the 3-in-2 switch was “intuitive and immediately understood by the great majority of people [they’ve] tested it with”. I strongly suspect these users were aware that something around dark mode toggles was being tested, and were paying a lot more attention to the control than they organically would.

I think the best way to get data for something like this is to record how users actually interact with the control, at scale, then analyze the data quantitatively. The experiment could involve different toggle designs as separate conditions.

Then, we could look at the data to answer questions like:

  • How frequently do people interact with the control meaningfully (i.e. ending up with a different selection)? (to see if it’s worth permanent screen real estate)
  • On a tri-state control, how frequently do users actually select the option that matches system but isn’t system? (to see if you actually need three states)
  • For mouse users, how much time passes between hovering the control and making a final selection for each condition and how many clicks does it involve? (as a proxy for cognitive load)
  • etc

By select above, I’m not referring to clicking, but the actual, final selection, to avoid noise from people playing with the control just to see what it does.

The big picture: Question the problem first

It is easy to get deep into a rabbit hole of trying our hardest to solve a problem that shouldn’t exist in the first place.

Especially for those of us with an engineering background, problem-solving comes naturally and it’s very hard to resist a challenging problem.

I’ve seen this happen repeatedly in many types of technical debates. It’s very common in standards groups as well: someone proposes a feature and the group starts debating the details before deciding whether the feature should exist at all.

Before any significant problem-solving task, it’s always good practice to step back and ask ourselves “is this a real problem worth solving?”.

You’d be surprised how often the answer is no.


6 footnotes
  1. during a CSS WG meeting where I was presenting several topics no less! ↩︎

  2. It’s right up there with “simplicity”. I have seen developers happily shovel complexity downstream to users using “simplicity” as the justification. ↩︎

  3. I’m not talking about you Bob! ↩︎

  4. Most parents hugely overestimate how many people are interested in kidnapping their kids. In reality they struggle to even find someone to look after them for an evening, let alone take them forever 😅 ↩︎

  5. or — perhaps more likely — never paid attention to one ↩︎

  6. The kind where you get a few users and observe them using the UI to accomplish a task — i.e. what most people refer to as just “user testing” ↩︎


Dark mode toggles: two states are enough

10 min read Report broken page

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 toggle1Unlike Devographics, surveys are not FA’s core business, so the Impact/Effort tradeoff simply wasn’t there for a custom UI, at least at this point in time. I ended up going with Tally, mainly due to the flexibility of its conditional logic and its support for code injection (which among other things, allowed me to use FA icons — a whopping 120 different ones!). , you’d find three options: Light, Dark, and System.

Tailwind Red Hat Design System Ant Web Awesome Excalidraw Taiga Astro Hero UI

Examples of tri-state dark mode toggles. In (LTR) reading direction: Tailwind, Red Hat Design System, Ant Design, 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.

Vitepress Material Spectrum Radix Shadcn

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 2I even did an entire talk about it at Web Unleashed, with a lot more technical detail than what I have included here. . 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.

This article is about how to implement a good dark mode toggle, if you have already decided you need one. It does not prescribe whether one is necessary at all. If you decide to simply default to the system preference and not offer a toggle, I think that is a perfectly valid choice. And yes, I agree that eventually browsers should provide this as part of their chrome, instead of every website having to implement it themselves, but we’re not there yet.


2 footnotes
  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. ↩︎

  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. ↩︎

Continue reading


In the economy of user effort, be a bargain, not a scam

16 min read Report broken page

Treat user effort as a currency. To create a product users love, design the tradeoff curve of use case complexity to user effort with the same care you design your pricing scheme.

API Design, Product Design, Product Management, Product, Usability, User Centered Design, UX, Design Reviews, Design Principles
Edit post on GitHub

The Hovercar Framework for Deliberate Product Design

13 min read Report broken page

Many teams start with the MVP. But what if the key to shipping great products wasn’t starting small — but starting big? Could great products start at the finish line?

You may be familiar with this wonderful illustration and accompanying blog post by Henrik Kniberg about good MVPs:

Henrik Kniberg's MVP illustration

It’s a very visual way to illustrate the age-old concept that that a good MVP is not the one developed in isolation over months or years, grounded on assumptions about user needs and goals, but one that delivers value to users as early as possible, so that future iterations can take advantage of the lessons learned from real users.

From Hovercar to Skateboard

I love Henrik’s metaphor so much, I have been using a similar system to flesh out product requirements and shipping goals, especially early on. It can be immediately understood by anyone who has seen Henrik’s illustration, and I find it can be a lot more pragmatic and flexible than the usual simple two tiered system (core requirements and stretch goals). Additionally, I find this fits nicely into a fixed time, variable scope development process, such as Shape Up.

🛹 The Skateboard aka the Pessimist’s MVP
What is the absolute minimum we can ship, if need be? Utilitarian, bare-bones, and somewhat embarrassing, but shippable — barely. Anything that can be flintstoned gets flintstoned.
🛴 The Scooter aka the Realist’s MVP
The minimum product that delivers value. Usable, but no frills. This is the target.
🚲 The Bicycle aka the Optimist’s MVP
Stretch goals — UX polish, “sprinkles of delight”, nonessential but high I/E features. Great if we get here, fine if we don’t.
🏍️ The Motorcycle
Post-launch highest priority items.
🚗 The Car
Our ultimate vision, taking current constraints into account.
🏎️ The Hovercar aka the North Star UI
The ideal experience — unconstrained by time, resources, or backwards compatibility. Unlikely to ship, but a guiding light for all of the above.

Please note that the concept of a North Star UI has no relation to the North Star Metric. While both serve as a guiding light for product decisions, and both are important, the North Star UI guides you in designing the product, whereas the North Star Metric is about evaluating success. To avoid confusion, I’ll refer to it as “North Star UI”, although it’s not about the UI per se, but the product vision on a deeper level.

The first three stages are much more concrete and pragmatic, as they directly affect what is being worked on. The more we go down the list, the less fleshed out specs are, as they need to allow room for customer input. This also allows us to outline future vision, without having to invest in it prematurely.

The most controversial of these is the last one: the hovercar, i.e. the North Star UI. It is the very antithesis of the MVP. The MVP describes what we can ship ASAP, whereas the North Star describes the most idealized goal, one we may never be able to ship.

It is easy to dismiss that as a waste of time, a purely academic exercise. “We’re all about shipping. Why would we spend time on something that may not even be feasible?” I hear you cry in Agile.

Stay with me for a moment, and please try to keep an open mind. Paradoxical as it may sound, fleshing out your North Star can actually save you time. How? Start counting.

Core Idea

At its core, this framework is about breaking down tough product design problems into three more manageable components:

  1. North Star: What is the ideal solution?
  2. Constraints: What prevents us from getting there right now?
  3. Compromises: How close can we reasonably get given these constraints?

One way to frame it is is that 2 & 3 are the product version of tech debt.1Unlike Devographics, surveys are not FA’s core business, so the Impact/Effort tradeoff simply wasn’t there for a custom UI, at least at this point in time. I ended up going with Tally, mainly due to the flexibility of its conditional logic and its support for code injection (which among other things, allowed me to use FA icons — a whopping 120 different ones!).

It’s important to understand what constraints are fair game to ignore for 1 and which are not. I often call these ephemeral or situational constraints. They are constraints that are not fundamental to the product problem at hand, but relate to the environment in which the product is being built and could be lifted or change over time. Things like:

  • Engineering resources
  • Time
  • Technical limitations (within reason)
  • Performance
  • Backwards compatibility
  • Regulatory requirements

Unlike ephemeral constraints, certain requirements are part of the problem description and cannot be ignored. Some examples from the case studies below:

While these may be addressed differently in different solutions, it would be an oxymoron to have a North Star that did not take them into account.

Benefits

1. It makes hard product problems tractable

Nearly every domain of human endeavor has a version of divide and conquer: instead of solving a complex problem all at once, break it down into smaller, manageable components and solve them separately. Product design is no different.

This process really shines when you’re dealing with the kinds of tough product problems where at least two of these questions are hard, so breaking it down can do wonders for reducing complexity.

2. It makes the product design process robust and adaptable

By solving these components separately, our product design process becomes can more easily adapt to changes.

I have often seen “unimplementable” solutions become implementable down the line, due to changes in internal or external factors, or simply because someone had a lightbulb moment.

By addressing these components separately, when constraints get lifted all we need to reevaluate is our compromises. But without this modularization, our only solution is to go back to the drawing board. Unsurprisingly, companies often choose to simply miss out on the opportunity, because it’s cheaper (or seems cheaper) to do so.

3. It facilitates team alignment by making the implicit, explicit

Every shipping goal is derived from the North Star, like peeling layers off an onion. This is whether you realize it or not.

Whether you realize it or not, every shipping goal is always derived from the North Star, like peeling layers off an onion. In some contexts the process of breaking down a bigger shipping goal into milestones that can ship independently is even called layering.

The process is so ingrained, so automatic, that most product designers don’t realize they are doing it. They go from hovercar to car so quickly they barely realize the hovercar was there to begin with. Thinking about the North Star is taboo — who has time for daydreaming? We must ship, yesterday!

But the hovercar is fundamental. Without it, there is no skateboard — you can’t reduce the unknown. When designing it is not an explicit part of the process, the result is that the main driver of all product design decisions is something that can never be explicitly discussed and debated like any other design decision. In what universe is that efficient?

A skateboard might be a good MVP if your ultimate vision is a hovercar, but it would be a terrible minimum viable cruise ship — you might want to try a wooden raft for that.

A wooden raft, then a simple sailboat, then a speedboat, then a yacht, and finally a ship.

A skateboard may be a great MVP for a car, but a terrible MVP for a cruise ship.

Making the North Star taboo doesn’t make it disappear (when did that ever work?).

It just means that everyone is following a different version of it. And since MVPs are products of the North Star, this will manifest as difficulty reaching consensus at every step of the way.

The product team will disagree on whether to ship a skateboard or a wooden raft, then on whether to build a scooter or a simple sailboat, then on whether to work on a speedboat or a yacht, and so on. It will seem like there is so much disconnect that every decision is hard, but there is actually only one root disconnect that manifests as multiple because it is never addressed head on.

Two people arguing. One has a speech bubble with a skateboard, the other a speech bubble with a wooden raft. The first also has a thought bubble with a car, the second a thought bubble with a ship.

When the North Star is not clearly articulated, everyone has their own.

Here is a story that will sound familiar to many readers:

A product team is trying to design a feature to address a specific user pain point. Alice has designed an elegant solution that addresses not just the problem at hand, but several prevalent longstanding user pain points at once — an eigensolution. She is aware it would be a little trickier to implement than other potential solutions, but the increase in implementation effort is very modest, and easily offset by the tremendous improvement in user experience. She has even outlined a staged deployment strategy that allows it to ship incrementally, adding value and getting customer feedback earlier.

Excited, she presents her idea to the product team, only to hear engineering manager Bob dismiss it with “this is scope creep and way too much work, it’s not worth doing”. However, what Bob is actually thinking is “this is a bad idea; any amount of work towards it is a waste”. The design session is now derailed; instead of debating Alice’s idea on its merits, the discussion has shifted towards costing and/or reducing effort. But this is a dead end because the amount of work was never the real problem. In the end, Alice wants to be seen as a team player, so she backs off and concedes to Bob’s “simpler” idea, despite her worries that it is overfit to the very specific use case being discussed, and the product is now worse.

Arguing over effort feels safer and less confrontational than debating vision — but is often a proxy war. Additionally, it is not productive. If the idea is poor, effort is irrelevant. And once we know an idea is good and believe it to our core, we have more incentive to figure out implementation, which often proves to be easier than expected once properly investigated. Explicitly fleshing out the Hovercar strips away the noise and brings clarity.

When we answer the questions above in order and reach consensus on the North Star before moving on to the compromises, we know what is an actual design decision and what is a compromise driven by practical constraints. Articulating these separately, allows us to discuss them separately. It is very hard to evaluate tradeoffs collaboratively if you are not on the same page about what we are trading off and how much it’s worth. You need both the cost and the benefit to do a cost-benefit analysis!

Additionally, fleshing the North Star out separately ensures that everyone is on the same page about what is being discussed. All too often have I seen early design sessions where one person is discussing the skateboard, another the bicycle, and a third one the hovercar, no-one realizing that the reason they can’t reach consensus is that they are designing different things.

4. It can improve the MVP via user testing

Conventional wisdom is that we strip down the North Star to an MVP, ship that, then iterate based on user input. With that process, our actual vision never really gets evaluated and by the time we get to it, it has already changed tremendously.

But did you know you can actually get input from real users without writing a single line of code?

alt text

Believe it or not, you don’t need to wait until a UI is prototyped to user test it. You can even user test a low-fi paper prototype or even a wireframe. This is widely known in usability circles, yet somehow entirely unheard of outside the field. The user tells you where they would click or tap on every step, and you mock the UI’s response by physically manipulating the prototype or showing them a wireframe of the next stage.

Obviously, this works better for some types of products than others. It is notably hard to mock rich interactions or UIs with too many possible responses. But when it does work, its Impact/Effort ratio is very high; you get to see whether your core vision is on the right track, and adjust your MVP accordingly.

It can be especially useful when there are different perspectives within a team about what the North Star might be, or when the problem is so novel that every potential solution is low-confidence. No-one’s product intuition is always right, and there is no point in evaluating compromises if it turns out that even the “perfect” solution was not actually all that great.

5. It paves the way for future evolution

So far, we have discussed the merits of designing our North Star, assuming we will never be able to ship it. However, in many cases, simply articulating what the North Star is can bring it within reach. It’s not magic, just human psychology.

Once we have a North Star, we can use it to evaluate proposed solutions: How do they relate to it? Are they a milestone along a path that ends at the North Star? Do they actively prevent us from ever getting there? Prioritizing solutions that get us closer to the North Star can be a powerful momentum building tool.

Humans find it a lot easier to make one more step along a path they are already on, than to make the first step on an entirely new path. This is well-established in psychology and often used as a technique for managing depression or executive dysfunction. However, it applies on anything that involves humans — and that includes product design.

Once we’re partway there, it naturally begs the question: can we get closer? How much closer? Even if we can’t get all the way there, maybe we can close enough that the remaining distance won’t matter. And often, the closer you get, the more achievable the finish line gets.

In fact, sometimes simply reframing the North Star as a sequence of milestones rather than a binary goal can be all that is needed to make it feasible. For an example of this, check out the CSS Nesting case study below.

Case studies

In my 20 years of product design, I have seen ephemeral constraints melt away so many times I have learned to interpret “unimplementable” as “kinda hard; right now”. Two examples from my own experience that I find particularly relevant below, one around Survey UI, and one around a CSS language feature.

Context Chips and the Power of Engineering Momentum

Illustration of context chips

The case study is described at length in Context Chips in Survey Design: “Okay, but how does it feel?”. In a nutshell, the relevant bits are:

  • Originally, I needed to aggressively prioritize due to minimal engineering resources, which led me to design an extremely low-effort solution which still satisfied requirements.
  • The engineer hated the low-effort idea so much, he prototyped a much higher-effort solution in a day, backend and all. Previously, this would have been entirely out of the question.
  • Once I took the ephemeral constraints out of the question, I was able to design a much better, novel solution, but it got pushback on the basis of effort.
  • Prototyping it allowed us to user test it, which revealed it performed way better than alternatives.
  • Once user testing built engineering momentum and the implementation was more deeply looked into, it turned out it did not actually require as much effort as initially thought.

Here is a dirty little secret about software engineering (and possibly any creative pursuit): neither feasibility nor effort are fixed for a given task. Engineers are not automatons that will implement everything with the same energy and enthusiasm. They may implement product vision they disagree with, but you will be getting very poor ROI out of their time.

Investing the time and energy to get engineers excited can really pay dividends. When good engineers are excited, they become miracle workers.

In fact, engineering momentum is often, all that is needed to make the infeasible, feasible. It may seem hard to fit this into the crunch of OKRs and KPIs but it’s worth it; the difference is not small, it is orders of magnitude. Things that were impossible or insurmountable become feasible, and things that would normally take weeks or months get done in days.

One way to build engineering momentum is to demonstrate the value and utility of what is being built. All too often, product decisions are made in a vacuum, based on gut feelings and assumptions about user needs. Backing them up with data, such as usability testing sessions is an excellent way to demonstrate (and test!) their basis. When possible, having engineers observe user testing sessions firsthand can be much more powerful than secondhand reports.

Relaxed CSS Nesting and the Power of Evolution

Sometimes high effort things just take a lot of hard work and there is no way around it. Other times, feasibility is just one good idea away.

One of my favorite examples, and something I’m proud to have helped drive is the relaxed CSS Nesting syntax, now shipped in every browser. It is such an amazing case study on the importance of having an explicit and consensus-backed North Star UI 2I even did an entire talk about it at Web Unleashed, with a lot more technical detail than what I have included here. .

In a nutshell, CSS nesting was a (then new) CSS syntax that let developers better organize their code through reducing repetition.

table.browser-support {
	border-collapse: collapse;
}
table.browser-support th,
table.browser-support td {
	border: 1px solid silver;
}
@media (width < 600px) {
	table.browser-support,
	table.browser-support tr,
	table.browser-support th,
	table.browser-support td {
		display: block;
	}
}
table.browser-support th {
	border: 0;
}
table.browser-support td {
	background: yellowgreen;
}
table.browser-support td:empty {
	background: red;
}
table.browser-support td > a {
	color: inherit;
}

table.browser-support {
	border-collapse: collapse;

@media (width < 600px) { &, tr, th, td { display: block; } }

th, td { border: 1px solid silver; } th { border: 0; } td { background: yellowgreen;

&:empty { background: red; }

> a { color: inherit; } } }

Example of CSS code, with (right) and without (left) nesting. Which one is easier to read?

This is one of the rare cases where the North Star was well known in advance, since the syntax was already well established in developer tooling (CSS preprocessors). Instead, the big challenge was navigating the practical constraints, since CSS implemented in browsers has different performance characteristics, so a syntax that is feasible for tooling may be out of reach for a browser. In this case, the North Star syntax had been ruled out by browser engineers due to prohibitive parsing performance 3for any Compilers geeks out there that want all the deets: it required potentially unbounded lookahead since there is no fixed number of tokens a parser can read and be able to tell the difference between a selector and a declaration. , so we had to design a different, more explicit syntax that could be parsed more efficiently.

At this point, it is important to note that CSS Nesting is a feature that is very heavily used once available. Conciseness and readability are paramount, especially when conciseness is the sole purpose of the feature in the first place!

Initial attempts for a syntax that satisfied these technical requirements introduced a lot of noise, making the syntax tedious to write and noisy to read. Even worse, these attempts were actively incompatible with the North Star syntax, as well as other parts of the language (namely, the @scope rule). This meant that even if the North Star syntax became feasible later, CSS would need to forever support syntax that would then have no purpose, and would only exist as a wart from the past, just like HTML doctypes.

Once Google became very keen to ship Nesting (driven by State of CSS 2022, which showed it as the top missing CSS feature), a small subset of the CSS Working Group, led by Elika Etemad and myself met to explore alternatives, and produced four competing proposals. The one that the group voted to adopt 4Originally dubbed “Lea’s proposal”, and later “Non-letter start proposal”, but became known as Option 3 from its position among the five options considered (including the original syntax). was the one I designed explicitly to answer the question: If the North Star syntax is out of the question right now, what is the largest subset of it that is feasible?

Once we got consensus on this intermediate syntax, I started exploring whether we could get any closer to the 🌟, even proposing an algorithm that would reduce the number of cases that required the slower parsing to essentially an edge case. A few other WG members joined me, with my co-TAG member Peter Linss being most vocal.

This is a big advantage of North Star compatible designs: it is much easier to convince people to move a little further along on the path they are already on, than to move to a completely different path. With a bit of luck, you may even find yourself implementing an “infeasible” North Star without even realizing it, one little step at a time.

We initially faced a lot of resistance from browser engineers, until eventually a brilliant Google engineer, Anders Ruud and his team experimented with variations of my proposed algorithm and actually closed in on a way to implement the North Star syntax in Chrome. The rest, as they say, is history. 🌟

Conclusion

Hopefully by now you’re convinced about the value of investing time in reaching alignment on an explicit North Star that has buy-in from the entire product team.

A common misconception is that the North Star is a static goal that prevents you from adapting to new data, such as customer feedback. But often, your North Star will change a lot over time, and that’s okay. Having an initial destination does not take away your ability to course correct. That’s not giving up, it’s adapting.

And yes, it’s true that many product teams do use a vision-led approach — they just start from the car, not the hovercar. While that confers some of the benefits above, there is still an implicit reduction happening, because the hovercar is still there in the back of their mind.

Note that for this framework to be beneficial, it is important that everyone is on the same page and understands the steps, benefits, and goals of this approach. Co-designing a North Star with a team that sees the process as a pointless thought experiment will only add friction and will not confer any of these benefits. Also, this is a mindset that can only work when applied top-down. If you are not a decision-maker at your place of work and leadership is not on board, you will have a very hard time if you try to push this ad hoc, without first getting leadership buy-in. You can try sending them a link to this blog post!

If this post resonated, please share your own case studies in the comments. Or, if you decide to give this framework a try, I’d love to hear how it went!


4 footnotes
  1. Indeed, looks like I’m not the first to draw a parallel between the two! ↩︎

  2. I even did an entire talk about it at Web Unleashed, with a lot more technical detail than what I have included here. ↩︎

  3. for any Compilers geeks out there that want all the deets: it required potentially unbounded lookahead since there is no fixed number of tokens a parser can read and be able to tell the difference between a selector and a declaration. ↩︎

  4. Originally dubbed “Lea’s proposal”, and later “Non-letter start proposal”, but became known as Option 3 from its position among the five options considered (including the original syntax). ↩︎

Product, Product Design, Product Management, User Centered Design, Product-Led Growth, North Star UI, Collaboration, Case Studies
Edit post on GitHub

Context Chips in Survey Design: “Okay, but how does it feel?”

15 min read Report broken page

The story of how a weird little UI to collect sentiment alongside survey responses defied constraints and triumphed over skepticism through usability testing.

Minimalistic skeleton diagram showing the concept presented in this article

One would think that we’ve more or less figured survey UI out by now. Multiple choice questions, checkbox questions, matrix questions, dropdown questions, freeform textfields, numerical scales, what more could one possibly need?!

And yet, every time Google sponsored me to lead one of the State Of … surveys, and especially the inaugural State of HTML 2023 Survey, I kept hitting the same wall; I kept feeling that the established options for answering UIs were woefully inadequate for balancing the collection good insights with minimal friction for end-users.

The State Of surveys used a completely custom survey infrastructure, so I could often (but not always) convince engineering to implement new question UIs. After joining Font Awesome, I somehow found myself leading yet another survey, despite swearing never to do this again. 🥲 Alas, building a custom survey UI was simply not an option in this case; I had to make do with the existing options out there 1Unlike Devographics, surveys are not FA’s core business, so the Impact/Effort tradeoff simply wasn’t there for a custom UI, at least at this point in time. I ended up going with Tally, mainly due to the flexibility of its conditional logic and its support for code injection (which among other things, allowed me to use FA icons — a whopping 120 different ones!). , so I felt this kind of pain to my core once again.

So what are these cases where the existing answering UIs are inadequate, and how could better ones help? I’m hoping this case study to be Part 1 of a series around how survey UI innovations can help balance tradeoffs between user experience and data quality, though this is definitely the one I’m most proud of, as it was such a bumpy ride, but it was all worth it in the end.


1 footnote
  1. Unlike Devographics, surveys are not FA’s core business, so the Impact/Effort tradeoff simply wasn’t there for a custom UI, at least at this point in time. I ended up going with Tally, mainly due to the flexibility of its conditional logic and its support for code injection (which among other things, allowed me to use FA icons — a whopping 120 different ones!). ↩︎

Continue reading

Survey Design, Product, Product Design, Design Thinking, Case Studies, UX, Usability, North Star UI
Edit post on GitHub