Accessible and Functional Quantity Spinbutton Pattern Developer Mica has published a detailed guide on implementing accessible and functional quantity spinbutton patterns for e-commerce and booking platforms. The article outlines keyboard interactions, ARIA attributes, and screen reader support for NVDA and VoiceOver, emphasizing the importance of accessibility in critical user flows. Hey This is Mica writing, a human not an AI agent nothing against them, not discrimination of any kind is allowed here . Just a brief disclaimer before starting: this post was non AI-generated I am not going to lie, I tried to use it for some research but since the errors I found were not properly documented the AI invented answers, lol because I felt the urgent need to start using my brain and hands to craft something from scratch. If you are a human, let's connect, at the end you will find the ways to reach me. I am on a doom scrolling detox so you won't find me on instagram or twitter now. So, I have a question: Is there anybody out there? https://www.youtube.com/watch?v=Aiu5Fr7-hFQ&list=RDAiu5Fr7-hFQ&start radio=1 If you work on an e-commerce, a booking hotels, flights, trains, etc platform, a restaurant reservation system maybe you are familiar with the quantity spinbutton component. It is a common UI pattern that allows users to select a quantity of items they want to purchase or book. It is configured by two buttons and one input; one button for increasing the quantity, another button to decrease the quantity and an input where the user is able to type the desired amount or increase/decrease the quantity using the Up Arrow or Down Arrow accordingly. Sounds simple, and yes it is, but it is also a critical flow in the user journey. If it's badly implemented, you can not only be potentially losing sales translation: losing money, which is important but also creating a frustrating experience for users with disabilities which should be more important than money, but those are my morals and ethics, lol . My goal in this article is setting a clear basis of a non-negotiable structure and behavior of the quantity spinbutton pattern and from there, explore different variations depending on the use case. Disclaimer: This is not a written-in-stone guide, I can make mistakes, so please let me know if you disagree with something. | Key | Action | |---|---| | Up Arrow | Increases the value by its step value | | Down Arrow | Decreases the value by its step value | | Home | If the spinbutton has a minimum value, sets the value to its minimum | | End | If the spinbutton has a maximum value, sets the value to its maximum | | Command or Fn + Right Arrow | Substitute for Apple's keyboards that do not have a End key to set the value to its maximum | | Command or Fn + Left Arrow | Substitute for Apple's keyboards that do not have a End key to set the value to its minimum | You can download NVDA here https://www.nvaccess.org/download/ and it's only available for the Windows operating system. It is compatible with Chrome, Firefox and Edge browsers. Long story short, an NVDA modifier key is needed to navigate using this screen reader. The modifier key can be Insert key by default or it can be remapped to the Caps Lock in the settings. Two modes for different purposes can be found: NVDA automatically switches between Browse and Focus modes, but the user can toggle them using Insert + Space Bar. | Command | Task | |---|---| | Down Arrow Browse Mode | Read next item | | Enter or Space Bar | Activate button | | Down Arrow Focus Mode | Decrement by step | | Up Arrow Focus Mode | Increment by step | | Home | Jump to aria-valuemin via your custom handler | | End | Jump to aria-valuemax via your custom handler | | Tab | Commit value, leave the field, return to browse mode | If you are a macOS user, VoiceOver comes built into the operating system of your MacBook. It's compatible with the Safari browser. VoiceOver uses the Control and Option keys before each command. This combination is called VO and these keys can be locked/unlocked by pressing Control + Option + ; semicolon all together. | Command | Task | |---|---| | Tab/Shift + Tab | Go to next/previous focusable item link, button, input, etc. | | VO + Space Bar | Activate a link or form control | | VO + Right Arrow | Move VO cursor to next element not limited to focusable items | | VO + Left Arrow | Move VO cursor to previous element | | VO + Shift + Down Arrow | Once the VO cursor is on the spinbutton, this combination enters the spinbutton | | Up Arrow | Once inside the spinbutton, increment by step | | Down Arrow | Once inside the spinbutton, decrement by step | | Home | Jump to aria-valuemin via your custom handler | | End | Jump to aria-valuemax via your custom handler | If you are an iOS user, VoiceOver is the screen reader by default on the operating system of your iPhone. It's compatible with the Safari browser. Unlike VoiceOver on macOS, VoiceOver on iOS, the navigation is controlled by finger gestures. | Gesture | Task | |---|---| Swipe next | Read next item | Swipe left | Read previous item | Double-tap | Activate link, button | Swipe up | If the VO cursor is over the spinbutton, increase the value | Swipe down | If the VO cursor is over the spinbutton, decrease the value | If you are an Android user, TalkBack is the default screen reader on the operating system of your mobile. It's compatible with Chrome, Firefox and Edge. Like VoiceOver for iOS, the navigation is controlled by gestures with the fingers. | Gesture | Task | |---|---| Swipe next | Read next item | Swipe left | Read previous item | Double-tap | Activate link, button | Swipe up | If the VO cursor is over the spinbutton, increase the value | Swipe down | If the VO cursor is over the spinbutton, decrease the value | Currently everyone is following the APG ARIA Authoring Practices Guide https://www.w3.org/WAI/ARIA/apg/patterns/ as if it were the bible and not as what it is: a guide , a very useful guide, btw, THE guide. Everything written there is considered a commandment written in stone by The code in this example is not intended for production environments. Before using it for any purpose, read this to understand why. and then a list of reasons why you should be critical of the pattern provided. In this case, the most important one is: Robust accessibility can be further optimized by choosing implementation patterns that maximize use of semantic HTML and heeding the warning that No ARIA is better than Bad ARIA. So, what does this mean? Well, a couple of important things: After this brief introduction to the APG, I would like to dive into its Spinbutton pattern . role="spinbutton" on the input tag instead of using the native HTML solutions provided by the tag itself, the buttons are removed from the focus flow because they have a tabindex="-1" but they are still operable via mouse and by using screen readers. Only the tag with the role="spinbutton" is not fully semantic by itself and we will need to add the keyboard and screen reader functionalities programmatically and make it semantic by adding properties and states to the input element. In the accessibility field we have a mantra: No ARIA is better than Bad ARIA . You should be extra careful when using ARIA because, if it is not used correctly, you will end up creating more issues than solving them. Again, the intention is good but the outcome is more barriers. Last month, WebAIM org https://webaim.org/ launched its annual report for 2026 about the state of accessibility in over 1 million pages: The WebAIM Million https://webaim.org/projects/million/ . The report shows that in 2026, accessibility errors increased by 10.1% according to the WCAG 2.2 Level A/AA conformance failures and concluded with the following reflection: The 2026 WebAIM Million analysis found notable increases in both the number of detected accessibility errors and number of pages with WCAG conformance failures, reversing a trend of gradual accessibility improvements in recent years. A primary concern is the significant increase in home page complexity and ARIA code, both of which correlate to increased detectable errors. These trends likely reflect broader shifts in web development including increased reliance on 3rd party frameworks and libraries and automated or AI-assisted coding practices “vibe coding” . Home pages are getting larger and more technologically complex at an alarming rate, making accessibility more difficult to achieve and maintain. A key takeaway from this year's report is improving accessibility at scale will require both better practices and simpler systems. Alternatively, complex systems need to do a better job of focusing on accessibility fundamentals. It's not a surprise that creating components using AI without questioning the output will end up creating more barriers for users with disabilities, and sloppier websites overall. Also, the lack of native and accessible examples on the web makes the AI coding agents return inaccessible components, but okay not everything is the fault of the AI, to be honest. you can find the functional example here https://micaavigliano.com/en/blog/quantity-spinbutton-pattern functional-example-apg