1<!DOCTYPE html> 2<html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1"> 6 <meta name="color-scheme" content="light dark"> 7
7<script>(function(){try{var m=document.cookie.match(/(?:^|; )theme=(dark|light)/);if(m)document.documentElement.setAttribute('data-theme',m[1]);}catch(e){}})();</script>
7 8 <title>ignore the code: Toggles Considered Harmful</title> 9 <meta name="generator" content="Gorgon" /> 10 <link rel="apple-touch-icon" href="/blog_images/iphone.png"/> 11 <link rel="alternate" type="application/rss+xml" title="ignore the code RSS Feed" href="//ignorethecode.net/blog/rss/" /> 12
12<script src="/blog/js/footnotes.js" defer></script>
12 13
13<script src="/blog/js/dates.js" defer></script>
13 14
14<script src="/blog/js/theme.js" defer></script>
14 15 <link rel="stylesheet" href="/blog_images/fonts.css"> 16 <link rel="stylesheet" href="/blog_images/carbon.css" type="text/css"> 17 <link rel="stylesheet" href="/blog_images/blog.css" type="text/css"> 18 <link rel="shorturl" href="https://ignco.de/818" /> 19 <link rel="shortlink" href="https://ignco.de/818" /> 20 <link rev="canonical" type="text/html" href="https://ignco.de/818" /> 21 <link rel="canonical" href="https://ignorethecode.net/blog/2026/08/09/toggles_considered_harmful/" /> 22 <link rel="stylesheet" href="/blog_images/article.css" type="text/css" media="screen"> 23 </head> 24 <body> 25 <div id="content"> 26 <main id="posts"> 27 28 <div class="post" id="post_818"> 29 <div class="text target"> 30 <div class="date"><a href="/blog/2026/08/09/toggles_considered_harmful/">August 9, 2026</a></div> 31 <h1 class="posttitle"> 32 <a href="/blog/2026/08/09/toggles_considered_harmful/" rel="bookmark" title="Permanent Link to Toggles Considered Harmful">Toggles Considered Harmful</a> 33 </h1> 34 <p>I just read <a href="https://unsung.aresluna.org/seeing-like-a-state/">this post</a> from Marcin Wichary's Unsung, where he points out a peculiar macOS dialog box that shows boolean toggles in four different shades of grey:</p> 35 36<p><img src="/upload/818/toggles.png" alt="macOS's Link to Mac or iPad dialog box, showing four settings implemented as toggles, each in a different shade of grey" /></p> 37 38<p>Marcin offers some improvements, but the actual problem is fundamental to macOS: these types of toggles are bad UI controls and should simply not exist.</p> 39 40<p>I think toggles originated on iOS, where they replaced checkboxes. I suspect the reason is that they feel more tactile on a touchscreen, have a larger touch target, and resemble physical switches - Apple's original UI design approach for iOS valued this kind of skeuomorphism.</p> 41 42<p>Toggles make sense in the real, physical world because of their mechanical properties. But even there, they need additional affordances to work. For example, this power strip has a toggle switch to turn it on and off:</p> 43 44<p><img src="/upload/818/powerstrip.jpg" alt="Toggle on a power strip with "Reset" and "Off" labels" /></p> 45 46<p>Note that there are labels for each state, and a light to indicate the current state. That's because the toggle itself is symmetrical. There is no obvious way to tell whether it is on or off.</p> 47 48<p>Now let's go back to the digital toggle:</p> 49 50<p><img src="/upload/818/digital-toggle.png" alt="A digital toggle" /></p> 51 52<p>Is this toggle on or off? If you don't already know that "left" means "off" and "right" means "on", you have absolutely no way to tell.</p> 53 54<p>Apple's attempts to make toggle states more obvious ultimately created the confusing situation in the original screenshot. Therefore, the most expedient solution to the original UI problem is simply to use a control whose state is obvious.</p> 55 56<p><img src="/upload/818/checkboxes.png" alt="The same screen, toggles replaced with checkboxes, now makes the checked/unchecked and enabled/disabled states obvious" /></p> 57 58<p><em>Update:</em> <a href="https://lobste.rs/s/ulinck/toggles_considered_harmful">Discussion on lobste.rs</a>, including <a href="https://lobste.rs/s/ulinck/toggles_considered_harmful#c_ysqdgq">this point</a> I wasn't aware of:</p> 59 60<blockquote> 61 <p>There is an accessibility setting on macOS named "differentiate without color", which does help by showing little on/off indicators on the toggles.</p> 62</blockquote> 63 64<p>If your System Settings search field also doesn't work, it's under Display. Enabled.</p> 65 <div class="shorturl"> 66 <p>If you require a short url to link to this article, please use <b><a href="https://ignco.de/818">https://ignco.de/818</a></b></p> 67 </div> 68 </div> 69 </div> 70 <img class="swirly" src="/blog_images/swirly.png" alt="" width="255" height="78" loading="lazy" decoding="async"> 71 <a href="https://pragprog.com/book/lmuse2/designed-for-use-second-edition"><img style="float:left;display:block;margin-right:10px;margin-bottom:200px;margin-top:20px;" src="/blog_images/designed_for_use_second_edition.jpg" alt="designed for use cover" width="200" height="183" /></a><p><b>But wait, there's more!</b></p><p>Want to read more like this? Buy my book's second edition! <i>Designed for Use: Create Usable Interfaces for Applications and the Web</i> is now available DRM-free directly from <a href="https://pragprog.com/book/lmuse2/designed-for-use
71-second-edition">The Pragmatic Programmers</a>. Or you can get it <a href="http://www.amazon.com/gp/product/1680501607/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1680501607&linkCode=as2&tag=wisegamersch-20&linkId=74A2IPF6GRYBDDTA">on Amazon</a>, where it's also available in <a href="http://amzn.to/WMI37B">Chinese</a> and <a href="http://www.amazon.jp/dp/4873116082">Japanese</a>.</main><!--posts--> 72<aside id="sidebar"> 73 <div class="title"> 74 <a href="/" id="titleignore">ignore<br></a> 75 <a href="/" id="titlethe">the<br></a> 76 <a href="/" id="titlecode">code</a> 77 </div> 78 <div class="byline"> 79 written by<br> 80 Lukas Mathis 81 </div> 82 83 <div class="info"> 84 <a class="img" href="/"><img src="/blog_images/lukas.jpg" style="border-style:none;width:56px;height:95px;"></a><br><span 85 style="line-height:1.7;text-align:left;">Hi. My name is Lukas Mathis. <a 86 href="https://pragprog.com/titles/lmuse2/designed-for-use-second-edition/">I've written a book about usability</a>. It's been translated to <a 87 href="https://amzn.to/WMI37B">Chinese</a> and <a 88 href="https://www.amazon.jp/dp/4873116082">Japanese</a>. I make <a href="https://goodvantage.ch">software for NGOs at Goodvantage</a>. You can reach me at
88<script 89 type="text/javascript"> 90 //<!-- 91 document.write("<" + "a" + " hr" + "ef=\"" + "ma" + "il" + "to:" + "LKM" + "@" + "lkmc.ch" + "\">" + "LKM" + "@" + "lkmc.ch" + "<" + "/" + "a>") 92 // --> 93 </script>
93.</span><br><br> 94 95 <div><a style="border-style:none;" href="/blog/rss/"><img style="border-style:none;" src="/blog_images/rss.png"></a> 96 <a href="/blog/rss/">Subscribe via RSS</a></div> 97 </div><!--info--> 98 99 <div class="search"> 100 <form action="/blog/" method="get" accept-charset="utf-8"> 101 <label for="blogsearch">Search:</label><br> 102 <input type="search" id="blogsearch" value="" name="query" results="5" placeholder="Search" 103 autosave="ch.ignorethecode.blog.search"> 104 </form> 105 </div><!--search--> 106 <div>or <a href="/blog/browse/">browse the archives</a>.</div> 107 <div> 108 <button class="theme-toggle" type="button" aria-label="Toggle dark mode"><span class="icon" aria-hidden="true">â¾ï¸</span><span 109 class="lbl">Dark mode</span></button> 110 </div> 111</aside><!--sidebar--> 112</div><!--content-->
113<script defer src="https://analytics.pyramid-deliveries.ch/sa.js" data-domain="ignorethecode.net"></script>
113</body> 114</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.