Skip to main content
Unveilydocs

WCAG Compliance

WCAG 2.1/2.2 AA compliance guide

Built-in — No separate implementation needed

All accessibility features described on this page are already implemented in the Unveily SDK native components. Web developers do not need to write any native code separately. Both Android and iOS are supported equally.

Overview

The Unveily SDK's native UI components are designed to meet WCAG 2.1/2.2 AA standards. Users who need accessibility (visual impairment, motor impairment, hearing impairment, etc.) can use the app equally.

StandardItemApplied ComponentsAndroidiOS
WCAG 1.1.1Non-text content (screen reader labels)Panel, menu, tab, drawer
WCAG 1.4.3Contrast ratio (4.5:1 or higher)Panel background, menu icons
WCAG 1.4.4Text resize (up to 200%)Accessibility panel settings
WCAG 2.1.1Keyboard accessAll interactive elements
WCAG 2.4.3Focus orderAccessibilityPanel, SideDrawer, TopDownMenu
WCAG 2.5.5Minimum touch target (48dp / 44pt)Tabs, drawer rows, menu items
WCAG 2.5.8Minimum target size (24dp, WCAG 2.2)Badge, icon buttons

Bridge readiness

The JavaScript examples on this page use window.unveilyBridge (lowercase). If you call a namespace such as accessibilityPanel at mount time in an SPA (React, Vue, etc.), wait for the unveilyGlueReady event before calling. Calls triggered by user actions (e.g. a button click) do not need this.


Focus Trap (WCAG 2.4.3)

When a panel, drawer, or menu opens, focus cycles only within it.

Android: Tab → next element, Shift+Tab → previous element, Tab from the last element → back to first.

AccessibilityPanelView.kt (inside SDK)
// Tab / Shift+Tab cycling — handled automatically by the SDK
setOnKeyListener { _, keyCode, event ->
    if (keyCode == KeyEvent.KEYCODE_TAB && event.action == KeyEvent.ACTION_DOWN) {
        val focusables = getFocusableChildren()
        val nextIndex = if (event.isShiftPressed)
            (currentIndex - 1 + focusables.size) % focusables.size
        else
            (currentIndex + 1) % focusables.size
        focusables[nextIndex].requestFocus()
        true
    } else false
}

iOS: When the panel opens, UIAccessibility.post(notification: .screenChanged, argument: containerView) is called so VoiceOver immediately moves focus inside the panel.

AccessibilityPanelView.swift (inside SDK)
// VoiceOver automatic notification on panel display — handled automatically by the SDK
UIAccessibility.post(notification: .screenChanged, argument: containerView)

Screen Reader Labels (WCAG 1.1.1)

All UI elements automatically have labels that screen readers (Android TalkBack / iOS VoiceOver) can read.

Android (inside SDK)
// Active item: "Camera"
// Disabled item: "Camera, disabled" — not distinguishable by color alone
itemView.contentDescription = if (enabled) label
    else "$label, ${getString(R.string.acc_state_disabled)}"
iOS (inside SDK)
// Applied automatically via NSLocalizedString
button.accessibilityLabel = NSLocalizedString("acc_state_disabled", comment: "")
button.accessibilityTraits = enabled ? .button : [.button, .notEnabled]

Badge Notification Count Announcement

Android
// TalkBack: "3 notifications"
badge.contentDescription = getString(R.string.acc_badge_count, count)
iOS
// VoiceOver: "3 notifications"
badge.accessibilityLabel = String(format: NSLocalizedString("acc_badge_count", comment: ""), count)

Text Resize (WCAG 1.4.4)

When the user sets the font size in the accessibility panel, the WebView text size is also adjusted. The accessibility panel offers three steps: normal / large / extraLarge. WCAG 1.4.4 requires that content remains usable at up to 200% zoom; in addition to this panel setting, the WebView honors the user's system text-size setting, so content stays usable at 200% zoom.

SettingWebView textZoom
Normal100%
Large130%
Extra Large160%

You can read the current setting from JavaScript. getSettings takes a callback function name as a string; there is no synchronous form:

window.unveilyBridge.accessibilityPanel.getSettings("onAccessibilitySettingsLoaded");

window.onAccessibilitySettingsLoaded = function (settings) {
  console.log(settings.fontSize); // "normal" | "large" | "extraLarge"
};

Minimum Touch Targets (WCAG 2.5.5 / 2.5.8)

All interactive elements guarantee a minimum touch size. iOS uses 44pt and Android uses 48dp (physically equivalent).

ComponentAndroidiOS
Accessibility panel item48dp × 72dp44pt × 66pt
Bottom tab48dp × 48dp44pt × 44pt
Drawer row48dp × 56dp44pt × 52pt
Badge24dp × 24dp (WCAG 2.2)24pt × 24pt (WCAG 2.2)

High Contrast Mode (WCAG 1.4.3)

Activating high contrast mode in the accessibility panel dynamically changes the background style.

iOS: Background color switches from systemBackgroundblack, text color from labelwhite, ensuring a 4.5:1 contrast ratio.
Android: Panel background opacity is increased and blur effects are removed.

window.unveilyBridge.accessibilityPanel.getSettings("onAccessibilitySettingsLoaded");

window.onAccessibilitySettingsLoaded = function (settings) {
  if (settings.highContrast) {
    // Recommended: also apply a high-contrast style to web content
    document.body.classList.add("high-contrast");
  }
};

Multilingual Accessibility Strings

TalkBack/VoiceOver labels automatically change to match the app language. The SDK supports 3 languages: Korean (ko), English (en), and Japanese (ja).

String Key한국어English日本語
acc_high_contrast고대비High Contrastハイコントラスト
acc_font_size글꼴 크기Font Size文字サイズ
acc_tts읽어주기Read Aloud読み上げ
acc_easy_read쉬운 읽기Easy Readかんたん表示
acc_haptic진동 피드백Vibration振動フィードバック
acc_tab_pin탭 바 고정Pin Tab Barタブ固定
acc_left_handed왼손 모드Left-Hand Mode左利きモード
acc_one_handed한손 모드One-Hand Mode片手モード
acc_state_disabled비활성화됨Disabled無効
acc_state_selected선택됨Selected選択済み
acc_badge_count알림 %ld건%ld notifications%ld件の通知

TTS voice languages are separate

The table above lists UI (screen reader label) languages. TTS speech synthesis separately also supports zh-CN (Simplified Chinese) — that is a voice output language, not a UI language.


Motor Impairment Support

Left-Handed Mode

Switches the drawer from the right side of the screen to the left.

window.unveilyBridge.accessibilityPanel.open();

The user sets it via the "Left-Hand Mode" toggle in the panel.

One-Handed Mode

Compresses content into the bottom area of the screen for single-handed use.

Always Show Tab Bar

Pins an auto-hiding tab bar to always-visible state.

window.unveilyBridge.accessibilityPanel.open();

The user sets it via the "Pin Tab Bar" toggle in the panel.

Easy Read

Simplifies the layout so users with cognitive disabilities can easily navigate.


Web Content Accessibility

Accessibility for web content within the WebView is the responsibility of the web developer. Apply standard web accessibility techniques such as aria-* attributes, semantic HTML, and focus management.

Use TTS Bridge

By calling TTS directly from web content, you can implement a read-aloud feature without Android TalkBack / iOS VoiceOver. For more details, refer to the Accessibility Bridge API.

On this page