A Morning Like Any Other
Let me walk you through my morning. I pick up my phone, turn on TalkBack, and try to check my bank balance. That's it. Nothing complicated. No international wire transfer, no stock trade, no mortgage application. Just: how much money do I have?
What follows is a fifteen-minute obstacle course that most sighted people would never believe. I lost my sight at age 12. I've worked in the banking and financial services space as an accessibility architect for over sixteen years. I use banking apps every single day — not as a test exercise, but because I have to. I have bills to pay. Rent is due. My credit card statement won't read itself.
So let me take you through what actually happens. Not theory. Not guidelines. The real thing.
The Login Screen: Where It Falls Apart Before It Begins
I open the app. TalkBack announces: "Image." Then: "Edit box." Then: "Button."
That's it. No label on the edit box telling me it's a username field. No label on the button telling me it's "Login" or "Submit." Just "Image. Edit box. Button." I'm expected to guess.
I type my username from memory — I've done this enough times to know the layout. Then I swipe to what I hope is the password field. TalkBack says "Edit box" again. No label. I type my password and tap what I believe is the login button.
Nothing happens for a few seconds. Then: "WebView." A CAPTCHA has appeared. A visual CAPTCHA. Squiggly letters on a noisy background that I'm supposed to type into a box. There is no audio alternative. There is no way to request a different challenge. My screen reader sees the image and announces: "Unlabelled image."
I am locked out of my own bank account.
Some banks have moved to OTP-based verification instead, which should be better. But here's what often happens: the OTP arrives by SMS, I switch to my messaging app to read it, copy the code, switch back to the banking app — and the app has reset. The OTP field is gone. The session has timed out. I start over.
And when the OTP field does work, it's often six separate input boxes — one for each digit. Each box is unlabelled. TalkBack doesn't tell me which digit I'm on. I type the first number. Did it go in? I can't tell. I swipe forward. "Edit box." Is this the second box or still the first? There's no way to know without sighted help.
Biometric login — fingerprint or face recognition — is often the only usable path. But many apps bury the biometric option behind the inaccessible login screen. You have to log in once with a password to enable fingerprint authentication. It's a catch-22.
Navigation: The Invisible Maze
Let's say I get past login. Now I need to navigate the app. The first thing TalkBack hits is usually a hamburger menu icon. Except it doesn't say "Menu." It says "Button" or, worse, nothing at all. I've encountered apps where the main navigation icon is an unlabelled image button. I tap it and hope for the best.
The menu opens — I think. There's no announcement that a menu has appeared. No change in focus. I swipe right and hear: "Image. Image. Image. Image." Four icons with no text labels. Are these Account, Transfers, Bills, Settings? Or Home, Offers, Rewards, Help? I have no idea. Each one is a mystery door.
Many banking apps rely heavily on swipe gestures for navigation. Swipe up for account summary. Swipe down to refresh. Swipe left to see the next card in a carousel. These gestures directly conflict with the gestures I use to operate TalkBack. When I swipe right, I'm trying to move to the next element on screen. But the app intercepts that gesture and interprets it as "dismiss this notification card." Suddenly I've closed something I haven't even read yet.
There are no alternative navigation paths. No visible "Next" and "Previous" buttons. No keyboard shortcuts. Just gestures that my screen reader has already claimed.
Checking My Balance: The Simplest Task That Isn't
I navigate to what I believe is the account summary. TalkBack begins reading: "Image. Text. Text. Text. Heading. Double tap to activate."
None of these "Text" elements have meaningful labels. I don't know which one is my account number, which is the account type, and which is the balance. They're all just "Text."
I've seen apps where the account balance is rendered as an image. A flat image of the number. My screen reader sees it and says: "Unlabelled image." My balance could be five hundred rupees or five lakh. I have no way to know.
Other apps use custom-drawn text — canvas elements or styled spans with no semantic meaning. The balance appears on screen but doesn't exist in the accessibility tree. It's a ghost. Visible to eyes, invisible to my software.
One major bank's app reads my balance correctly about half the time. The other half, it announces the balance from a cached version of the page — the balance from yesterday, or last week. There's no indication that the data is stale. I've made financial decisions based on incorrect information because the app couldn't be bothered to announce a refresh.
Making a Transfer: A Form Designed for Frustration
Now I want to send money to someone. I find the transfer option after navigating through the unlabelled icons. A form appears.
The first field says "Edit box." Not "Beneficiary name" or "Account number" — just "Edit box." I swipe to the next field. "Edit box." And the next. "Edit box." There are five or six fields in a row, and none of them tell me what they expect. I have to rely on the visual order matching a standard pattern: beneficiary, account number, IFSC code, amount, remarks. But if the developer reordered the fields, or added an extra one, I'm filling in the wrong information in every box.
Then comes the dropdown for selecting the bank or the account to transfer from. I double-tap to open it. TalkBack goes silent. Nothing is announced. The dropdown has opened visually — I can hear my colleague confirm this when I ask — but it's a custom component that doesn't expose its options to the accessibility API. I swipe right. Nothing. Swipe down. Nothing. The dropdown has effectively trapped me in a void. I can't select a bank. I can't close the dropdown. I have to force-close the app and start over.
On a popular UPI app, the process is marginally better. I can enter a UPI ID. But the "Verify" button that confirms the recipient's name is unlabelled — it just says "Button." I tap it, wait, and hear nothing. Has the name been verified? Is this the right person? I'm about to send money and I can't confirm who will receive it.
The confirmation screen is the worst part. After I've painstakingly filled out every field, the app shows a summary: recipient name, amount, account details, and a "Confirm" button. This screen has a thirty-second timeout. If I don't tap "Confirm" within thirty seconds, the transaction is cancelled. But TalkBack reads the screen sequentially, one element at a time. By the time I've listened to the recipient details and reached the amount, the screen has already redirected. Transaction cancelled. Start over.
I'm not slow. The app is impatient. It was designed for someone who can see the entire screen at once. I read it one word at a time, in a single stream. That takes more than thirty seconds, and the app punishes me for it.
Paying Bills: Calendar Roulette and Silent Failures
Bill payments introduce their own unique brand of inaccessibility. I need to pay my electricity bill. I find the bill payment section, select my provider, and enter my consumer number. So far, so good — if the fields happen to be labelled, which is a coin toss.
Then the app asks me to select a payment date. A date picker appears. It's a visual calendar grid. Rows for weeks, columns for days. My screen reader reads it as a flat sequence of numbers: "1. 2. 3. 4. 5. 6. 7. 8. 9..." I have no way to know which number corresponds to which day of the week. I don't know where the current date is. I don't know which month I'm looking at. The "Previous month" and "Next month" buttons are unlabelled arrows.
I tap a number at random, hoping it's a reasonable date. Sometimes I accidentally select a date in the past and the app throws an error that TalkBack doesn't announce. I just know the form didn't submit. Was it the date? Was it something else? Silence.
The amount field is another quiet disaster. I type 2500. But the field doesn't announce what currency it expects. Is this rupees? Is there a paise field somewhere else? Some apps auto-format the number with commas as I type, and each keystroke triggers TalkBack to re-read the entire field from the beginning. I type "2" and hear "2." I type "5" and hear "25." I type "0" and hear "250." I type "0" and hear "2,500." That last comma insertion means TalkBack just announced "2 comma 500" instead of "two thousand five hundred." It's disorienting, every time.
The final insult is the success or failure message. I tap "Pay." The app processes the payment. A message appears on screen for three seconds: "Payment successful" or "Payment failed — insufficient funds." Then it auto-redirects to the home screen. TalkBack never gets a chance to read the message. I've just sent money — or haven't — and I have no idea which one it is. I have to go find my transaction history and check there, assuming the transaction history is accessible. Often, it isn't.
The Security vs. Accessibility Myth
I've sat in dozens of meetings with bank product teams where someone says it. The line I've come to dread: "We can't make it accessible because of security requirements."
This is almost always wrong. Let me be specific about why.
Visual CAPTCHAs are not more secure than audio CAPTCHAs or challenge-response alternatives. Bot operators use OCR to crack visual CAPTCHAs; they don't use screen readers. An audio CAPTCHA or a simple logic-based challenge ("What is three plus five?") provides equivalent security without locking out blind users.
Session timeouts that are too short don't prevent fraud — they prevent me from completing transactions. WCAG requires that users be warned before a timeout and given the option to extend their session. This doesn't weaken security. It means a legitimate user who needs more time gets more time, while a genuinely abandoned session still expires.
Masking the account balance or showing it as an image doesn't protect anyone from anything. If someone has already authenticated and is inside the app, they're the account holder. The balance should be in accessible text. Rendering it as an image just prevents screen readers from reading it — it doesn't prevent shoulder surfers or screenshots.
The screen reader itself is not a security risk. TalkBack and VoiceOver read what's in the accessibility tree — the same information that's displayed visually on screen. Making content accessible doesn't expose additional data. It exposes the same data through a different channel.
What Banks Should Do
I'm not asking for a separate app for blind users. I'm not asking for a simplified version with fewer features. I'm asking for the same app, built correctly. Here's what that looks like:
- Label everything. Every input field, every button, every icon needs an accessible name. If it does something, it needs to say what it does. This is the single most impactful change and often the easiest to implement. One attribute:
aria-labelor a proper<label>element. That's it. - Announce dynamic changes. When content changes on screen — a balance updates, an OTP timer ticks down, a success message appears — use
aria-liveregions to announce it. Don't assume I can see it. - Extend timeouts or make them adjustable. If your confirmation screen auto-redirects in thirty seconds, make it sixty. Or better, let the user choose. WCAG 2.2 Success Criterion 2.2.1 is clear on this: provide a way to turn off, adjust, or extend time limits.
- Use native components wherever possible. Native HTML select elements, native date inputs, native checkboxes — these work with screen readers out of the box. Every custom component you build from scratch is a component you need to make accessible from scratch. Most teams don't.
- Provide alternatives to gesture-based navigation. If a swipe gesture performs an action, provide a button that does the same thing. Gestures are invisible to users who can't see a visual cue telling them to swipe.
- Replace visual CAPTCHAs. Use audio CAPTCHAs, logic challenges, or server-side bot detection that doesn't require any user interaction at all. ReCAPTCHA v3 does this silently. There is no excuse for a visual-only CAPTCHA in 2026.
- Test with real assistive technology users. Not just automated tools. Not just one round of testing before launch. Include screen reader users in your regular QA cycle. Pay them for their time. They'll find what your tools can't.
- Don't treat accessibility as a feature — treat it as quality. Accessible code is well-structured code. Proper labels, semantic HTML, logical focus order — these make the app better for everyone, including sighted users who rely on voice control, older adults with motor impairments, and people using the app in bright sunlight who need high contrast.
This Isn't Hypothetical
Everything I've described in this post has happened to me. Not once, not as an edge case, but repeatedly, across multiple banking apps from some of the largest financial institutions in the country. These are banks that spend crores on their mobile platforms. They have hundreds of developers. They conduct extensive testing — for features, performance, security.
They just don't test for people like me.
And it's not just me. There are millions of people with visual impairments in India who need to manage their finances independently. Every inaccessible app is a message to those millions: you don't matter enough for us to build this correctly.
I don't think that's the intention. But it is the impact.
I'm not asking for special treatment. I'm not asking for charity, or sympathy, or a separate "accessible version" tucked away in a corner. I'm asking to use my own money. The money I earned. In the account that has my name on it. Through the app that my bank requires me to use.
That shouldn't require fifteen minutes and a prayer. It should work.
If your team builds banking software and you're reading this, I'd welcome the conversation. Get in touch — I'd rather help you fix this than write about it.