← Back to books

Chapter 1: Why Accessibility Matters

Open your most-used app and turn off the screen. Not dim it — turn it off, and try to send a message anyway.

You can't, of course. But roughly a quarter of a million Android users in your country do something close to this every single day. They navigate their phones without ever looking at the screen, listening instead to a synthetic voice read the interface aloud, swiping to move from one element to the next. For them, your beautifully arranged layout doesn't exist as a picture. It exists as a list of things the screen reader can announce. And if you built that app without thinking about accessibility, that list is probably a mess: unlabeled buttons that announce nothing, images described as "image image image," controls that can't be reached at all.

This book is about making sure that when someone can't see your carefully designed screen, they can still use your app — and, as you'll discover, about a dozen other situations you probably haven't considered yet. We'll do all of it in Jetpack Compose, which happens to have one of the cleaner accessibility models of any modern UI toolkit once you understand how it thinks.

Before we write a single line of semantics {}, though, it's worth being honest about why you should care. Not the feel-good version. The real one.

Accessibility is not charity

Let's clear up the biggest misconception first, because it quietly poisons how most developers approach this topic.

Accessibility is not a favor you do for a small, unfortunate group of people. It is a property of well-built software, in the same way that "doesn't crash on rotation" or "works offline" are properties of well-built software. When we say an app is accessible, we mean it can be operated by people using a wide range of abilities and input methods — including the assistive technologies built into every Android phone in the world.

The reason this framing matters is that "charity" thinking leads to charity-quality results. It gets you a rushed pass at the end of a project where someone adds a few content descriptions, ships it, and moves on. "Property of the software" thinking leads to something durable: accessibility baked into your components, tested like any other feature, and cheap to maintain because it was never bolted on in a panic.

There's also a factual problem with the charity framing. The group you're "helping" is not small.

The numbers are bigger than you think

According to the World Health Organization, an estimated 1.3 billion people — about 16% of the global population, or roughly one in six of us — live with a significant disability. That already makes people with disabilities the largest minority group on the planet, and the figure is growing, driven by aging populations and the rise of chronic conditions like diabetes, stroke, and vision loss.

But even that number dramatically undersells your actual audience, because it only counts permanent disability. To understand who accessibility really serves, it helps to think in terms of three categories, a model popularized by Microsoft's inclusive design team:

  • Permanent. A person with one arm. A person who is blind. A person who is Deaf.
  • Temporary. A person with a broken arm in a cast. A person recovering from eye surgery. A person with an ear infection who can't hear well this week.
  • Situational. A parent holding a baby in one arm. Someone in bright sunlight who can't see the screen. Someone in a loud train who can't hear audio, or a quiet meeting where they can't turn it on. Someone who is exhausted at 2 a.m. and can barely focus.

Look at that list again. The situational column is everyone, at some point, every week. When you make a touch target big enough for someone with a motor impairment, you also make it easier to tap for the person jogging. When you make sure text can scale up for someone with low vision, you also help the middle-aged user reading without their glasses. When you provide captions for a Deaf user, you also serve the millions of people who watch video with the sound off.

This is called the curb-cut effect, after the ramps cut into sidewalk corners. They were mandated for wheelchair users — but today they're used far more often by people with strollers, delivery carts, rolling luggage, and bicycles. The accommodation designed for a specific need turned out to make the whole environment better for everybody. Software accessibility works exactly the same way. Almost every accessibility improvement you'll learn in this book is quietly a usability improvement for your entire user base.

So when you invest in accessibility, you are not building a special ramp for a few people off to the side. You are improving the main entrance.

The business case, stated plainly

Because I suspect some of you are the sort of developer who evaluates every hour of work against whether it moves a metric — good, that instinct will serve you here — let me put the commercial argument directly.

A larger addressable market. If one in six people has a disability, and your app is unusable for a meaningful slice of them, you've silently excluded a portion of your potential users and, if you monetize, your potential revenue. For a paid app or subscription product, that exclusion is money left on the table for no reason other than neglect.

Better ratings and retention. Users who can't use part of your app don't file neat bug reports explaining the accessibility gap. They leave a one-star review that says "doesn't work" and uninstall. Frustration from inaccessible interfaces is indistinguishable, in your analytics, from any other kind of churn — which means it's invisible until you go looking for it.

Aging users are your users. The single largest driver of disability worldwide is age. Vision, hearing, motor control, and cognition all shift as people get older. If your app expects to have users five or ten years from now, a growing share of them will need the exact accommodations this book teaches.

SEO for app stores and reputation. Both Google and Apple actively promote accessibility, surface it in their review processes, and feature apps that do it well. An accessible app is more likely to pass review cleanly and less likely to generate the kind of public complaints that damage a brand.

None of these require you to be a saint. They just require you to notice that inaccessible software is leaving value uncollected.

The legal case is no longer hypothetical

For years, accessibility advocates warned developers about legal risk, and for years most developers correctly guessed they could ignore it. That window has closed, at least for anyone touching the European market.

On June 28, 2025, the European Accessibility Act (EAA) — Directive (EU) 2019/882 — became enforceable across all 27 EU member states. For the first time, a broad accessibility mandate applies to private-sector digital products and services, and it explicitly names mobile apps as covered. If you provide e-commerce, banking, transport, telecommunications, e-books, or a range of other consumer services to EU customers, your app is expected to meet the requirements — regardless of whether your company is based in the EU.

The technical bar is the European standard EN 301 549, which incorporates the Web Content Accessibility Guidelines (WCAG) at Level AA. You'll hear "WCAG 2.1 AA" and "WCAG 2.2 AA" used as the practical benchmark. Don't worry about memorizing the standards yet; much of this book is, in effect, a hands-on tour of what they ask for, translated into Compose.

And this has teeth. Penalties vary by member state but reach up to €100,000 per violation in some countries, or a percentage of annual turnover in others. Enforcement is not theoretical: the first EAA lawsuits were filed in France in late 2025, and in June 2026 a French court ordered a major retailer to make both its website and its mobile application fully accessible, under a daily fine for every day of delay.

A few honest caveats, because I'd rather you trust this book than oversell you:

  • The EAA carves out microenterprises (broadly, fewer than 10 employees and under €2 million turnover) from some service obligations. A solo indie developer may fall outside parts of it — but the moment you build for a client, an employer, or a company of any size, that shield disappears.
  • The United States has no single equivalent statute for mobile apps, but the Americans with Disabilities Act (ADA) has been applied to apps through litigation, and lawsuits over inaccessible apps are common and expensive to fight.
  • Many other countries — Canada, Australia, and others — have their own accessibility laws, most of them also pointing back to WCAG.

The practical takeaway is simple: accessibility has crossed the line from "nice to have" to "increasingly a legal requirement," and the direction of travel is only one way. Learning it now is cheaper than being forced to retrofit it later under a deadline set by a regulator.

So why Jetpack Compose specifically?

If you've done accessibility work in the old Android View system, you may be bracing yourself. There, accessibility meant wrestling with AccessibilityNodeInfo, importantForAccessibility flags scattered across XML, contentDescription attributes, and custom AccessibilityDelegate classes when things got complicated. It worked, but it was fiddly, and the accessibility information lived separately from the code that drew the UI.

Compose takes a fundamentally different approach, and it's one of the quiet pleasures of the framework once it clicks.

In Compose, every composable can contribute to a parallel structure called the semantics tree. Think of it as a second description of your UI that exists purely for tools that aren't human eyes — screen readers, automated tests, and other assistive services. Your Column, Row, and Box describe how things look. The semantics tree describes what things mean: "this is a button labeled Add to favorites," "this is a heading," "this checkbox is currently checked."

Here's the elegant part: for most standard components, Compose builds this tree for you automatically. A Button already announces itself as a button. A Text already exposes its text as a label. A Checkbox already reports its checked state. A huge amount of accessibility, in Compose, is simply not undoing the good defaults you get for free.

The work — and the skill this book teaches — comes in three flavors:

  1. Filling in what Compose can't infer. An icon has no words, so Compose can't guess what it means. You supply that with contentDescription.
  2. Correcting what Compose gets wrong or gets too right. Sometimes the automatic tree is too noisy, or announces things in a confusing order, and you need to reshape it.
  3. Describing custom components. When you draw something bespoke — a custom slider, a swipeable card, a canvas-based control — Compose has no idea what it is, and you describe its meaning by hand.

All three are done through one central tool: the Modifier.semantics {} block, plus a small family of related modifiers. Once you understand the semantics tree as a mental model, accessibility in Compose stops feeling like a checklist of magic incantations and starts feeling like what it is — a second, structured description of your interface that you author deliberately.

A first taste

Let's make this concrete with the smallest possible example, so the ideas above have something to hang on. Don't worry about understanding every detail; we'll take all of this apart properly in the chapters ahead.

Here is a favorite button. It looks perfect on screen — a heart icon that fills in when tapped. And it is completely broken for a screen reader user:

IconButton(onClick = { toggleFavorite() }) {
    Icon(
        imageVector = if (isFavorite) Icons.Filled.Favorite
                      else Icons.Outlined.FavoriteBorder,
        contentDescription = null
    )
}

The problem is that single word: contentDescription = null. An icon is just a picture — it carries no text. By passing null, we've told Compose this image has no meaning worth announcing. So when a TalkBack user swipes to this control, the screen reader says something like "button" — and nothing else. Button that does what? The user has no idea. They're staring at a locked door with no label.

Now the fix:

IconButton(onClick = { toggleFavorite() }) {
    Icon(
        imageVector = if (isFavorite) Icons.Filled.Favorite
                      else Icons.Outlined.FavoriteBorder,
        contentDescription = if (isFavorite) "Remove from favorites"
                             else "Add to favorites"
    )
}

Same layout. Same pixels. But now TalkBack announces "Add to favorites, button" — and, because the description changes with state, "Remove from favorites, button" once it's been tapped. We changed one argument and turned a dead control into a usable one.

That's the entire spirit of this book in miniature. Accessibility in Compose is rarely about grand rewrites. It's a series of small, precise decisions — a description here, a role there, a merged group somewhere else — that add up to an interface anyone can operate. And most of those decisions cost you seconds if you make them as you build, versus hours if you retrofit them at the end.

(You may have noticed contentDescription = null isn't always wrong — sometimes an icon really is decorative, and null is exactly right. Knowing the difference is a real skill, and it's the whole subject of Chapter 4. For now, just notice that the choice matters.)

What you'll build, and what you'll learn

Throughout this book we'll develop a single running example — a personal notes-and-checklist app called Beacon — evolving it chapter by chapter from an app that merely looks finished into one that is genuinely usable by everyone. Building one app end to end, rather than showing disconnected snippets, means you'll see how accessibility decisions interact: how a choice about headings affects navigation, how touch-target sizing meets focus order, how testing catches the regressions you'll inevitably introduce.

By the end, you will be able to:

  • Explain how Android's assistive technologies — TalkBack, Switch Access, Voice Access, and magnification — actually consume your UI, so accessibility stops being guesswork.
  • Read and reason about the Compose semantics tree, the single mental model that makes everything else make sense.
  • Label content correctly, including the genuinely tricky judgment calls about what to describe and what to leave silent.
  • Handle roles, headings, grouping, focus order, and traversal so your app reads in an order that makes sense.
  • Respect the user's system settings for text scaling, contrast, and reduced motion.
  • Make interactive and fully custom components accessible, not just the built-in ones.
  • Test accessibility with automated tools and a real manual TalkBack workflow, and audit an existing app to find what's broken.
  • Fold all of it into a design system so that accessibility becomes the default your components enforce, rather than a thing you remember to add.

We'll assume you're already comfortable writing basic Compose UI — composables, Modifier, state, simple layouts. You do not need any prior accessibility experience. If you've never turned on a screen reader in your life, you're exactly the reader I wrote this for.

Which, by the way, is the one piece of homework I'll give you before Chapter 2.

Try this before you turn the page

Reading about screen readers is nothing like using one. So go turn TalkBack on.

On your Android phone, open Settings → Accessibility → TalkBack, and switch it on. (You can also set up the volume-key shortcut so you can toggle it quickly — you'll want that.) Then open an app you know well and try to use it without looking at the screen more than you have to. Swipe right to move to the next element. Double-tap to activate. Try to complete one ordinary task — send a message, add an item to a cart, play a song.

It will feel awkward and slow, and that's the point. Notice the buttons that announce nothing. Notice the images described by their filename, or not at all. Notice where you get lost. Notice, too, the apps that get it right, and how smooth they suddenly feel.

Then turn TalkBack back off, and come to the next chapter with that experience fresh. Everything we build from here exists to serve the person for whom that experience isn't an experiment — it's just Tuesday.

Summary

  • Accessibility is a property of well-built software, not an act of charity — and framing it as charity produces charity-quality results.
  • The audience is enormous: about 1.3 billion people, one in six, live with a significant disability, and permanent disability is only part of the picture. Temporary and situational limitations make accessibility relevant to everyone, an idea captured by the curb-cut effect.
  • The business case is straightforward: a larger reachable market, better ratings and retention, an aging user base, and favor from the app stores.
  • The legal case is now real. The European Accessibility Act has been enforceable since June 2025, explicitly covers mobile apps, points at WCAG AA as the standard, and is already producing court orders against inaccessible apps.
  • Jetpack Compose models accessibility through a semantics tree — a parallel, meaning-focused description of your UI. Standard components populate it automatically; your job is to fill gaps, fix mistakes, and describe custom components, mostly through Modifier.semantics {}.
  • Most accessibility work is small and cheap if done as you build, and expensive only when retrofitted.

In the next chapter, we'll go under the hood and see exactly how TalkBack and the other assistive services turn your app into something a person can hear and operate — because you can't build for a system you don't understand.