Accessibility

Back

Loading concept...

🌈 Making Your App Talk to Everyone: React Native Accessibility

The Magic Door Story

Imagine you built the most amazing treehouse ever! It has slides, secret rooms, and a candy dispenser. But wait… what if your friend uses a wheelchair? What if another friend can’t see? Your awesome treehouse would be useless to them! 😢

Accessibility is like adding a magic door to your treehouse. This magic door changes itself to help EVERYONE enter and enjoy your creation. Some friends need a ramp. Some need audio descriptions. Some read right-to-left. The magic door handles it all!

In React Native, we have four magic tools to build this door:

  1. 🎤 AccessibilityInfo API - Asks the phone what help the user needs
  2. 🏷️ Accessibility Props - Labels that describe everything to assistive tools
  3. 📢 Screen Reader Support - Makes your app talk out loud
  4. ↔️ RTL Support - Flips your app for languages that read right-to-left

🎤 AccessibilityInfo API: The Phone Whisperer

What Is It?

Think of AccessibilityInfo as a spy that finds out what special settings the user has turned on. Is the screen reader active? Does the user need bigger text? This API tells you!

Why Do We Need It?

Imagine serving ice cream. Before scooping, you ask: “Any allergies?” That’s what AccessibilityInfo does - it asks the phone about the user’s needs BEFORE showing content.

Simple Example

import { AccessibilityInfo } from 'react-native';

// Check if screen reader is on
const checkScreenReader = async () => {
  const isEnabled = await AccessibilityInfo
    .isScreenReaderEnabled();

  if (isEnabled) {
    console.log('Screen reader is ON!');
  }
};

Listening for Changes

// React to changes in real-time
useEffect(() => {
  const listener = AccessibilityInfo
    .addEventListener(
      'screenReaderChanged',
      (isEnabled) => {
        setScreenReaderOn(isEnabled);
      }
    );

  return () => listener.remove();
}, []);

Key Methods You’ll Use

Method What It Does
isScreenReaderEnabled() Is VoiceOver/TalkBack on?
isBoldTextEnabled() User wants bold text?
isReduceMotionEnabled() User dislikes animations?
announceForAccessibility() Speak a message out loud

Real-World Magic

// Announce important updates
const onPurchaseComplete = () => {
  AccessibilityInfo.announceForAccessibility(
    'Purchase complete! Receipt sent to email.'
  );
};
graph TD A["User Opens App"] --> B{Check AccessibilityInfo} B --> C["Screen Reader On?"] B --> D["Bold Text On?"] B --> E["Reduce Motion On?"] C --> F["Add extra labels"] D --> G["Use larger fonts"] E --> H["Disable animations"]

🏷️ Accessibility Props: Name Tags for Everything

What Are They?

Imagine going to a party where nobody has name tags. Confusing, right? Accessibility Props are name tags for every button, image, and text in your app. Screen readers read these tags out loud.

The Most Important Props

1. accessible - “Hey, I’m important!”

// Group items as one unit
<View accessible={true}>
  <Text>John Doe</Text>
  <Text>Online</Text>
</View>
// Screen reader says: "John Doe Online"

2. accessibilityLabel - “Call me this!”

// Without label: "Button"
// With label: "Add to cart, 29 dollars"
<TouchableOpacity
  accessibilityLabel="Add to cart, 29 dollars"
>
  <Icon name="cart" />
</TouchableOpacity>

3. accessibilityHint - “Here’s what I do!”

<TouchableOpacity
  accessibilityLabel="Submit order"
  accessibilityHint="Double tap to place order"
>
  <Text>Submit</Text>
</TouchableOpacity>

4. accessibilityRole - “I’m a type of thing!”

// Tell the system what this element IS
<TouchableOpacity accessibilityRole="button">
  <Text>Click Me</Text>
</TouchableOpacity>

// Common roles:
// button, link, image, header,
// checkbox, radio, slider, switch

5. accessibilityState - “Here’s my status!”

<TouchableOpacity
  accessibilityRole="checkbox"
  accessibilityState={{
    checked: isChecked,
    disabled: isDisabled
  }}
>
  <Text>Accept Terms</Text>
</TouchableOpacity>

Quick Reference Table

Prop Purpose Example Value
accessible Group elements true
accessibilityLabel Name it "Profile picture"
accessibilityHint Explain action "Opens gallery"
accessibilityRole Type of element "button"
accessibilityState Current status {selected: true}
graph TD A["UI Element"] --> B["accessible=true"] B --> C["accessibilityLabel"] C --> D["accessibilityHint"] D --> E["accessibilityRole"] E --> F["accessibilityState"] F --> G["Screen Reader&lt;br/&gt;Understands Everything!"]

📢 Screen Reader Support: Making Your App Speak

What Is a Screen Reader?

A screen reader is like a tour guide for blind users. It reads everything on screen out loud. On iOS it’s called VoiceOver. On Android it’s called TalkBack.

How Users Navigate

Screen reader users don’t see your beautiful design. They hear it! They swipe left/right to move between elements. Double-tap to activate.

Making Elements Focusable

// This becomes a "stop" for the screen reader
<View
  accessible={true}
  accessibilityLabel="Welcome message"
>
  <Text>Hello! Ready to learn?</Text>
</View>

Hiding Decorative Elements

// Don't read this out loud - it's just decoration
<Image
  source={decorativeLine}
  accessibilityElementsHidden={true}
  importantForAccessibility="no-hide-descendants"
/>

Managing Focus

import { findNodeHandle, AccessibilityInfo }
  from 'react-native';

// Move focus to a specific element
const focusOnError = () => {
  const node = findNodeHandle(errorRef.current);
  AccessibilityInfo.setAccessibilityFocus(node);
};

Live Regions: Announce Updates

// When this text changes, announce it!
<Text accessibilityLiveRegion="polite">
  {itemCount} items in cart
</Text>

// "polite" = wait for user to finish
// "assertive" = interrupt immediately

Best Practices Checklist

✅ Every image has a label or is hidden ✅ Buttons describe their action ✅ Form errors announce themselves ✅ Important updates use announceForAccessibility ✅ Focus moves logically through the screen

graph TD A["Screen Reader User"] --> B["Swipe Right"] B --> C["Read Element 1"] C --> D["Swipe Right"] D --> E["Read Element 2"] E --> F["Double Tap"] F --> G["Activate Element"] G --> H["Announce Result"]

↔️ RTL Support: Flipping Your App

What Is RTL?

Some languages read Right-To-Left: Arabic, Hebrew, Persian, Urdu. When users choose these languages, your ENTIRE app should flip like a mirror!

The Magic of I18nManager

import { I18nManager } from 'react-native';

// Check current direction
console.log(I18nManager.isRTL);
// true or false

// Force RTL (requires app restart)
I18nManager.forceRTL(true);
I18nManager.allowRTL(true);

Automatic Layout Flipping

Good news! Flexbox direction flips automatically!

// This row flips in RTL languages
<View style={{ flexDirection: 'row' }}>
  <Icon name="arrow" />
  <Text>Next</Text>
</View>

// LTR: [→] Next
// RTL: Next [←]

Prevent Flipping When Needed

Some things shouldn’t flip (like video players):

// Keep this element always LTR
<View style={{
  flexDirection: 'row',
  // STOP! Don't flip this!
  writingDirection: 'ltr'
}}>
  <PlayButton />
  <Scrubber />
</View>

Text Alignment

// Auto-align based on language
<Text style={{ textAlign: 'auto' }}>
  This aligns correctly in any language
</Text>

// Explicit control
<Text style={{ writingDirection: 'rtl' }}>
  עברית
</Text>

Handling Icons

// Flip arrow icons in RTL
<Image
  source={arrowIcon}
  style={{
    transform: [{
      scaleX: I18nManager.isRTL ? -1 : 1
    }]
  }}
/>

RTL Testing Tips

  1. Add RTL language in phone settings
  2. Or force RTL in your app temporarily
  3. Check ALL screens flip correctly
  4. Icons that “point” should flip too
graph TD A["User Selects Arabic"] --> B["I18nManager.isRTL = true"] B --> C["Flexbox Rows Flip"] B --> D["Text Aligns Right"] B --> E["Margins Swap"] C --> F["App Looks Natural in RTL"] D --> F E --> F

🎯 Putting It All Together

Here’s a complete accessible component:

const ProductCard = ({ product }) => {
  const screenReaderOn = useScreenReader();

  return (
    <TouchableOpacity
      accessible={true}
      accessibilityRole="button"
      accessibilityLabel={
        `${product.name}, ${product.price}`
      }
      accessibilityHint="Double tap to view details"
      accessibilityState={{
        selected: product.isSelected
      }}
      style={{
        flexDirection: 'row' // Auto-flips in RTL
      }}
    >
      <Image
        source={product.image}
        accessibilityLabel={product.imageDesc}
      />
      <View>
        <Text style={{ textAlign: 'auto' }}>
          {product.name}
        </Text>
        <Text>{product.price}</Text>
      </View>
    </TouchableOpacity>
  );
};

🌟 Remember These Golden Rules

  1. Ask First → Use AccessibilityInfo to know user needs
  2. Label Everything → Give every element a clear name
  3. Announce Changes → Tell users what happened
  4. Flip Gracefully → Support RTL languages naturally

When you build accessible apps, you’re not just following rules. You’re opening doors for millions of people who otherwise couldn’t use your creation. That’s not just good coding - that’s being a hero! 🦸‍♀️


“The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.” — Tim Berners-Lee

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.