{"id":7422,"date":"2025-10-21T18:16:01","date_gmt":"2025-10-21T23:16:01","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=7422"},"modified":"2025-10-21T18:16:02","modified_gmt":"2025-10-21T23:16:02","slug":"the-two-button-problem","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/the-two-button-problem\/","title":{"rendered":"The Two Button Problem"},"content":{"rendered":"\n<p>I see this UI\/UX issue all the time: there are two buttons, and it&#8217;s not clear which one of them is in the active state. Here&#8217;s an example from my TV:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368.jpeg?resize=768%2C1024&#038;ssl=1\" alt=\"\" class=\"wp-image-7449\" style=\"width:449px;height:auto\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368-scaled.jpeg?resize=768%2C1024&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368-scaled.jpeg?resize=225%2C300&amp;ssl=1 225w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368-scaled.jpeg?resize=1152%2C1536&amp;ssl=1 1152w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368-scaled.jpeg?resize=1536%2C2048&amp;ssl=1 1536w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/IMG_6368-scaled.jpeg?w=1920&amp;ssl=1 1920w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/figure>\n\n\n\n<p>Which one of those two buttons above is active? Like if I press the enter\/select button on my remote, am I selecting &#8220;Try it free&#8221; or &#8220;Sign in&#8221;? It&#8217;s entirely unclear to me based on the design. Those two design styles are ambiguous. Just two random selections from today&#8217;s trends of button design.<\/p>\n\n\n\n<p>If I press the up (or down) arrows on my remote, the styles of the buttons just reverses, so even interacting with the interface doesn&#8217;t inform the choice.<\/p>\n\n\n\n<p>This is a problem that can be solved at multiple levels. If the buttons are toggles that affect on-page content, the accessibility angle is partially solved by <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/Accessibility\/ARIA\/Reference\/Attributes\/aria-selected\">the <code>aria-selected<\/code> attribute<\/a>, for example. It&#8217;s also slightly less of an issue on devices with a cursor, as you likely just click on the one that you want. This is mostly a problem with remote control and keyboard usage where the <code>active<\/code> state is unclear or ambiguous. <\/p>\n\n\n\n<p>I call it the &#8220;two button&#8221; problem because if there were more than two buttons, the one that is styled differently is probably the one that is active. We could use our grade school brains to figure out which button is active.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"791\" height=\"1024\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?resize=791%2C1024&#038;ssl=1\" alt=\"\" class=\"wp-image-7466\" style=\"width:400px;height:auto\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?resize=791%2C1024&amp;ssl=1 791w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?resize=232%2C300&amp;ssl=1 232w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?resize=768%2C995&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?resize=1186%2C1536&amp;ssl=1 1186w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/joinPdf_3f0300690d09f12d1940b2475ca2d8d3_page-0069.jpg?w=1207&amp;ssl=1 1207w\" sizes=\"auto, (max-width: 791px) 100vw, 791px\" \/><figcaption class=\"wp-element-caption\">(<a href=\"https:\/\/subiscanoajsdblearning.z13.web.core.windows.net\/which-one-is-different-worksheet.html\">via<\/a>)<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Ideally, though, we don&#8217;t have to think very hard. It should be obvious which one is active. <\/p>\n\n\n\n<p>Again, the problem:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"970\" height=\"462\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-1.30.22-PM.png?resize=970%2C462&#038;ssl=1\" alt=\"\" class=\"wp-image-7480\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-1.30.22-PM.png?w=970&amp;ssl=1 970w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-1.30.22-PM.png?resize=300%2C143&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-1.30.22-PM.png?resize=768%2C366&amp;ssl=1 768w\" sizes=\"auto, (max-width: 970px) 100vw, 970px\" \/><\/figure>\n<\/div>\n\n\n<p>The most obvious solution here is to make both button styles the same, but be additive when one of them is the active button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"526\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.40.56-PM.png?resize=1024%2C526&#038;ssl=1\" alt=\"\" class=\"wp-image-7482\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.40.56-PM.png?resize=1024%2C526&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.40.56-PM.png?resize=300%2C154&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.40.56-PM.png?resize=768%2C394&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.40.56-PM.png?w=1106&amp;ssl=1 1106w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n<\/div>\n\n\n<p> I feel like it&#8217;s very clear now that &#8220;Try it free&#8221; is the selected button now. Even if it&#8217;s not to a user immediately. If they tab\/arrow\/whatever to the <em>other<\/em> button, that outline design will move to it and it will become clear then.<\/p>\n\n\n\n<p>You could also, ya know, literally point to it:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"462\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.43.43-PM.png?resize=1024%2C462&#038;ssl=1\" alt=\"\" class=\"wp-image-7484\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.43.43-PM.png?resize=1024%2C462&amp;ssl=1 1024w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.43.43-PM.png?resize=300%2C135&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.43.43-PM.png?resize=768%2C346&amp;ssl=1 768w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.43.43-PM.png?w=1166&amp;ssl=1 1166w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/figure>\n<\/div>\n\n\n<p>Perhaps you could resort to more &#8220;extreme&#8221; design styles like this when there is prove-ably no mouse\/cursor involved, like:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-keyword\">@media<\/span> (<span class=\"hljs-attribute\">hover:<\/span> none) <span class=\"hljs-keyword\">and<\/span> (<span class=\"hljs-attribute\">pointer:<\/span> coarse) {\n  <span class=\"hljs-selector-tag\">button<\/span><span class=\"hljs-selector-pseudo\">:active<\/span> {\n    <span class=\"hljs-comment\">\/* big obvious arrow styles *\/<\/span>\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><a href=\"https:\/\/frontendmasters.com\/blog\/learn-media-queries\/\">We&#8217;ve got a recent post on @media queries<\/a> that goes into lots of situations like this!<\/p>\n\n\n\n<p>This &#8220;two button&#8221; problem also can come up in the design pattern of &#8220;toggles&#8221;. Take something like this:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"714\" height=\"276\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.49.02-PM.png?resize=714%2C276&#038;ssl=1\" alt=\"\" class=\"wp-image-7486\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.49.02-PM.png?w=714&amp;ssl=1 714w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.49.02-PM.png?resize=300%2C116&amp;ssl=1 300w\" sizes=\"auto, (max-width: 714px) 100vw, 714px\" \/><figcaption class=\"wp-element-caption\">A &#8220;pill&#8221; toggle design pattern.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>Which one of those buttons is currently active? The up arrow? The down arrow? Neither? It&#8217;s impossible to tell by look alone.<\/p>\n\n\n\n<p>Sometimes in this case the &#8220;active&#8221; button is &#8220;grayed out&#8221;:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"738\" height=\"278\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.52.05-PM.png?resize=738%2C278&#038;ssl=1\" alt=\"\" class=\"wp-image-7487\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.52.05-PM.png?w=738&amp;ssl=1 738w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-3.52.05-PM.png?resize=300%2C113&amp;ssl=1 300w\" sizes=\"auto, (max-width: 738px) 100vw, 738px\" \/><\/figure>\n<\/div>\n\n\n<p>The implication here is that the up arrow is the &#8220;active&#8221; one, so you don&#8217;t need to press it again as it won&#8217;t do anything. Only the non-active button is pressable. I feel like this is okay-ish as a pattern, but it&#8217;s not my favorite as the active state is less prominent instead of more prominent almost indicating it&#8217;s disabled for some other reason or doesn&#8217;t matter.<\/p>\n\n\n\n<p>This kind of thing makes me almost miss the days of skeuomorphism where digital interfaces were designed to try to mimic real world surfaces and objects. We don&#8217;t have to go full leather-coated buttons though, we can just make the active button appear pressed through shadows and flattening.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"772\" height=\"296\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-4.06.07-PM.png?resize=772%2C296&#038;ssl=1\" alt=\"\" class=\"wp-image-7488\" style=\"width:440px\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-4.06.07-PM.png?w=772&amp;ssl=1 772w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-4.06.07-PM.png?resize=300%2C115&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-21-at-4.06.07-PM.png?resize=768%2C294&amp;ssl=1 768w\" sizes=\"auto, (max-width: 772px) 100vw, 772px\" \/><\/figure>\n<\/div>\n\n\n<p>This situation differs from the TV interface issue above in that this &#8220;active&#8221; button is indicating the button <em>has already<\/em> been pressed, not that it&#8217;s the button that <em>will be<\/em> pressed. So you&#8217;d need a style for that state as well.<\/p>\n\n\n\n<p>Maybe these aren&#8217;t the most amazing examples in the world, but I hope I&#8217;ve got you thinking about the two-button problem. When there are only two buttons, you can&#8217;t just pick two arbitrary different styles, as that doesn&#8217;t help people understand which of the two are active. You need to think about it a little deeper and get those styles in a place where it&#8217;s obvious.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you&#8217;ve got two buttons with two different looks (and no cursor), how do you know which one you&#8217;re about to activate? You&#8217;ll need to be careful with the design.<\/p>\n","protected":false},"author":1,"featured_media":7490,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[408,93,7,24],"class_list":["post-7422","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-media","tag-buttons","tag-css","tag-design"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/10\/two-button-problem.jpg?fit=2000%2C1200&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7422","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=7422"}],"version-history":[{"count":7,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7422\/revisions"}],"predecessor-version":[{"id":7491,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/7422\/revisions\/7491"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/7490"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=7422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=7422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=7422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}