Content Description is an accessibility property that conveys a textual description of non-text content to assistive technologies. In iOS it is the accessibilityHint attribute for UIView, in Android — contentDescription in XML markup. According to W3C WCAG 2.2, 2023, the absence of text alternatives for non-text content is one of the most common accessibility violations in mobile applications. Properly filled descriptions make the app accessible for people with visual impairments who use VoiceOver and TalkBack.
Key Takeaways
Content Description is a string property of a UI element that provides a textual representation of visual content to assistive technologies. A screen reader (VoiceOver on iOS, TalkBack on Android) reads the description aloud instead of attempting to recognize the element visually. Descriptions are applied to images without a text layer, icons, charts, custom controls, and any non-text elements.
According to Google Material Design, 2024, elements without contentDescription violate WCAG 1.1.1 (Non-text Content). Accessibility Scanner checks show that up to 40% of icons in shopping apps lack descriptions. A VoiceOver user hears “image” or “button” without specifics — such an interface becomes unusable for navigation.
Content Description does not replace the visible text of an element. If a button contains the text label “Send,” there is no need to set an additional description — the screen reader will read the text. For images, icons, and input fields, a description is mandatory.
The Accessibility Scanner (Android) and Xcode Accessibility Inspector (iOS) tools automatically check for descriptions. It is recommended to run these checks on every screen before release.
A user with visual impairment relies on VoiceOver to understand the interface. If a shopping cart icon lacks a description, they only hear “button.” To find out what the button does, they have to tap it blindly — risking an irreversible action. A description like “Remove item from cart” solves this problem in one second.
A user with temporary limitations (bright sunlight outdoors, a cracked screen) also uses VoiceOver. According to Apple Accessibility Report, 2023, about 20% of VoiceOver users do not have permanent visual impairments — they turn the feature on situationally.
WCAG 1.1.1 (Level A) requires that all non-text content have a text alternative. Exception: content that is decorative, used only for visual presentation, or conveys no information. The decorativeness test: if you remove the element, does the page meaning change? If not — it can be hidden from the screen reader.
Accessibility Label (accessibilityLabel in iOS) is the element name that the screen reader speaks on focus. Content Description (accessibilityHint in iOS) is additional clarification announced after the name that conveys the result of an action.
The difference is clear with a “Cart” button example. Label: “Cart.” Description: “Opens the checkout screen.” VoiceOver says: “Cart. Opens the checkout screen.” If only the Label is set, the user will not know what happens after tapping.
| Property | iOS | Android | Purpose |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | Element name (button, field, image) |
| Description | accessibilityHint | contentDescription (extended) | Clarification of action or meaning |
| Trait | accessibilityTraits | role / className | Element role (button, heading) |
Rule: Label answers “What is this?”, Description answers “What will happen?” In Android, contentDescription can serve both roles, but in practice it is better to separate them: use concatenation “[name], [explanation].”
For complex gestures (swipe to delete, long press for context menu), accessibilityHint is mandatory. A VoiceOver user does not know about hidden gestures unless they are described. Specify: “Swipe left to delete” in the element hint.
On the iOS platform, accessibilityHint is set via the eponymous property of UIView or NSObject. The value is a string of up to 80 characters. VoiceOver reads the hint after the label when detailed descriptions mode is enabled (in VoiceOver settings — “Verbosity”).
Example of setting a hint for a custom button:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "Add to favorites"
self.accessibilityHint = "Will save the item to the favorites list"
}
}
For UIImageView without text content, you must set isAccessibilityElement = true and accessibilityHint:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "Sales chart for the last quarter"
VoiceOver reads: “Sales chart for the last quarter.” If the hint is empty — only “image.” Apple HIG, 2024 recommends not using verbs like “tap” or “press” in hints — VoiceOver automatically adds a gesture instruction.
In SwiftUI, the hint is set via a chain modifier:
Image(systemName: "trash")
.accessibilityLabel("Delete")
.accessibilityHint("Permanently deletes the selected item")
SwiftUI automatically combines modifiers for composite views. If an Image is inside a Button, SwiftUI uses the button label as the primary accessibilityLabel.
In Android, contentDescription is set either in XML markup or programmatically via setContentDescription(). TalkBack announces the description when the element receives focus.
Example in XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="Search products" />
Programmatic setting for dynamic elements:
binding.iconSearch.contentDescription =
"Search. Will open the search screen with filters"
For decorative images (separators, backgrounds, decorative icons) set contentDescription = "@null" or setContentDescription(null) — TalkBack will skip such elements. In XML: android:contentDescription="@null". An empty string "" does not work — TalkBack will still announce “image.”
For ImageButton, always set contentDescription — TalkBack does not see text on images. For CheckBox, the description should change dynamically: “Selected” / “Not selected” instead of a static description. Use setContentDescription in the state listener.
Informativeness — the description should convey meaning, not appearance. Not “Blue icon with a checkmark,” but “Item added to cart.” A screen reader does not care about colors — it cares about the result.
Conciseness — optimal length is 2–4 words (up to 80 characters). Long descriptions slow down navigation: VoiceOver reads sequentially, each word is a second of the user’s time. According to Apple WWDC 2023, “Accessibility by Design”, a phrase longer than 5 seconds of reading interrupts the cognitive flow.
Uniqueness — no two elements on the same screen should have the same description. The user will not be able to distinguish which result will be triggered by focusing on the first vs. the second element. If there are multiple “Buy” buttons, add an identifier: “Buy iPhone 15,” “Buy iPhone 15 Pro.”
Localization — Content Description must be translated into all languages supported by the app. A localization error in descriptions is one of the common reasons for failing an Accessibility Review in the App Store.
Research by Nielsen Norman Group, 2024 showed that the optimal description length for screen readers is 3–5 words (up to 50 characters). Longer descriptions reduce navigation speed by 30%, as the user has to wait for the announcement to finish before the next step.
Redundancy — the description duplicates visible text. If a button contains the text “Send,” do not set accessibilityHint = “Send button.” VoiceOver will read the text automatically, and the hint will add unnecessary noise.
Confusion with Label — using contentDescription instead of a label for text buttons. In iOS, accessibilityLabel should match the button text (or be empty if the text is already visible), and the hint should only clarify the action. According to Google Testing Blog, 2024, 23% of reviewed apps in the Play Store have duplicate descriptions.
Ignoring dynamics — the description does not update when the state changes. For example, a “Wi-Fi” toggle’s description remains “Enable Wi-Fi” even after it is turned on. Correct approach: dynamically change the description to “Disable Wi-Fi” by observing the state.
After a design update (icon changes, element rearrangement), Content Description is often lost. Reason: the designer replaces an image, and the developer does not check the accessibility properties of the new asset. Solution: make accessibility checks a mandatory step in code review — add a checklist item: “Is Content Description updated?”
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
Frequently Asked Questions
VoiceOver or TalkBack will simply announce “image” or “button” without specifying its purpose. This violates WCAG 1.1.1 and makes the app inaccessible for people with visual impairments.
No. If the button has a text label, VoiceOver reads it automatically. A description (accessibilityHint) can be added to clarify the result of tapping, but a Label is not required.
In iOS set isAccessibilityElement = false. In Android set contentDescription = "@null". The screen reader will skip such elements entirely without making a sound.
In iOS use NSLocalizedString for accessibilityHint, in Android — string resources via @string/. Translating descriptions is mandatory for all supported languages.
Add UI tests that verify descriptions exist for all ImageView elements. In iOS — XCUIApplication, in Android — AccessibilityCheckRule from Espresso. Accessibility Scanner can be run in CI via the command line.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also