Content Description — својство приступачности које преноси текстуални опис нетекстуалног садржаја помоћним технологијама. У iOS-у ово је атрибут accessibilityHint за UIView, у Android-у — contentDescription у XML ознакама. Према подацима W3C WCAG 2.2, 2023, недостатак текстуалних алтернатива за нетекстуални садржај је један од најчешћих прекршаја приступачности у мобилним апликацијама. Правилно попуњени опис чине апликацију доступном за особе са оштећењем вида које користе VoiceOver и TalkBack.
Главно
Content Description — својство низа елемента интерфејса које преноси текстуалну репрезентацију визуелног садржаја помоћним технологијама. Screen reader (VoiceOver у iOS-у, TalkBack у Android-у) чита опис уместо да покушава да визуелно препозна елемент. Опис се примењује на слике без текстуалног слоја, иконе, графиконе, прилагођене контроле и све нетекстуалне елементе.
Према подацима Google Material Design, 2024, елементи без contentDescription крше правило WCAG 1.1.1 (Non-text Content). Провера Accessibility Scanner показује да до 40% икона у продавницама апликација нема опис. Корисник VoiceOver-а чује само «слика» или «дугме» без прецизирања — такав интерфејс постаје неупотребљив за навигацију.
Content Description не замењује видљиви текст елемента. Ако дугме садржи текстуалну ознаку «Пошаљи», није потребан додатни опис — screen reader ће прочитати текст. За слике, иконе и поља за унос опис је обавезан.
Алати Accessibility Scanner (Android) и Xcode Accessibility Inspector (iOS) аутоматски проверавају присуство описа. Препоручује се покретање ових провера на сваком екрану пре објављивања.
Корисник са оштећењем вида ослања се на VoiceOver да би разумео интерфејс. Ако икона корпе нема опис, чује само «дугме». Да би сазнао шта дугме ради, мора да га притине на слепо — ризик од неповратне радње. Опис «Уклони производ из корпе» решава овај проблем за секунду.
Корисник са привременим ограничењима (јако сунце напољу, поломљен екран) такође користи VoiceOver. Према подацима Apple Accessibility Report, 2023, око 20% корисника VoiceOver-а нема трајна оштећења вида — укључују ову функцију ситуационо.
Критеријум WCAG 1.1.1 (ниво А) захтева да сваки нетекстуални садржај има текстуалну алтернативу. Изузетак: садржај који је декоративан, користи се само за визуелно обликовање или не носи информације. Тест декоративности: ако уклонимо елемент, да ли се мења значење странице? Ако не — може се сакрити од screen reader-а.
Accessibility Label (accessibilityLabel у iOS-у) — име елемента које screen reader изговара при фокусу. Content Description (accessibilityHint у iOS-у) — додатно објашњење које се чита после имена и обавештава о резултату радње.
Разлика се добро види на примеру дугмета «Корпа». Label: «Корпа». Description: «Отвориће екран наручивања». VoiceOver каже: «Корпа. Отвориће екран наручивања». Ако се постави само Label, корисник неће знати шта ће се десити после притиска.
| Својство | iOS | Android | Намена |
|---|---|---|---|
| Label | accessibilityLabel | contentDescription | Име елемента (дугме, поље, слика) |
| Description | accessibilityHint | contentDescription (проширена) | Објашњење радње или значења |
| Trait | accessibilityTraits | role / className | Улога елемента (дугме, наслов) |
Правило: Label одговара на питање «Шта је ово?», Description — «Шта ће се десити?». У Android-у contentDescription може да испуни обе улоге, али у пракси је боље раздвојити их: користити конкатенацију «[име], [објашњење]».
За сложене покрете (превлачење за брисање, дуг притисак за контекстуални мени) accessibilityHint је обавезан. Корисник VoiceOver-а не зна за скривене покрете ако нису описани. Наведите: «Превлачите улево за брисање» у hint-у елемента.
У платформи iOS, accessibilityHint се поставља преко истоименог својства UIView или NSObject. Вредност — низ до 80 карактера. VoiceOver чита hint после label-а ако је укључен режим детаљних описа (у подешавањима VoiceOver-а — «Verbosity»).
Пример постављања hint-а за прилагођено дугме:
import UIKit
class CustomButton: UIButton {
override func awakeFromNib() {
super.awakeFromNib()
self.accessibilityLabel = "Додај у омиљене"
self.accessibilityHint = "Сачуваће производ у листу омиљених"
}
}
За UIImageView без текстуалног садржаја обавезно поставити isAccessibilityElement = true и accessibilityHint:
let imageView = UIImageView(image: UIImage(named: "chart-sales"))
imageView.isAccessibilityElement = true
imageView.accessibilityHint = "Графикон продаје за последњи квартал"
VoiceOver чита: «Графикон продаје за последњи квартал». Ако је hint празан — само «слика». Apple HIG, 2024 препоручује да се у hint-у не користе глаголи попут «притисните» или «додирните» — VoiceOver аутоматски додаје упутство за покрет.
У SwiftUI-ју hint се поставља преко chain модификатора:
Image(systemName: "trash")
.accessibilityLabel("Обриши")
.accessibilityHint("Неповратно ће обрисати изабрани елемент")
SwiftUI аутоматски комбинује модификаторе за сложене прегледе. Ако се Image налази унутар Button, SwiftUI користи label дугмета као главни accessibilityLabel.
У Android-у contentDescription се поставља или у XML ознакама или програмски преко setContentDescription(). TalkBack чита опис при фокусу на елементу.
Пример у XML-у:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_search"
android:contentDescription="Претрага производа" />
Програмско постављање за динамичке елементе:
binding.iconSearch.contentDescription =
"Претрага. Отвориће екран претраге са филтерима"
За декоративне слике (сепаратори, позадине, декоративне иконе) поставите contentDescription = "@null" или setContentDescription(null) — TalkBack ће прескочити такав елемент. У XML-у: android:contentDescription="@null". Празан низ "" не ради — TalkBack ће и даље рећи «слика».
За ImageButton увек поставите contentDescription — TalkBack не види текст на слици. За CheckBox опис треба динамички да се мења: «Изабрано» / «Није изабрано» уместо статичког описа. Користите setContentDescription у слушаоцу стања.
Информативност — опис треба да преноси смисао, а не спољашњи изглед. Не «Плава икона са кврчицом», већ «Производ додат у корпу». Screen reader не занимају боје — занима га резултат.
Концизност — оптимална дужина 2–4 речи (до 80 карактера). Дуги описи успоравају навигацију: VoiceOver чита секвенцијално, свака реч је секунда корисниковог времена. Према подацима Apple WWDC 2023, «Accessibility by Design», фраза дужа од 5 секунди читања прекида когнитивни ток.
Јединственост — на једном екрану не сме бити два елемента са истим описом. Корисник неће моћи да разликује који резултат ће произвести фокус на првом и другом елементу. Ако има више дугмади «Купи» — додајте идентификатор: «Купи iPhone 15», «Купи iPhone 15 Pro».
Локализација — Content Description се преводи на све језике које апликација подржава. Грешка локализације описа је један од честих разлога неуспеха Accessibility Review-а у App Store-у.
Истраживање Nielsen Norman Group, 2024 показало је да је оптимална дужина описа за screen reader 3–5 речи (до 50 карактера). Дужи описи смањују брзину навигације за 30%, јер корисник мора да чека завршетак читања пре следећег корака.
Сувишност — опис дуплира видљиви текст. Ако дугме садржи текст «Пошаљи», не постављајте accessibilityHint = «Дугме пошаљи». VoiceOver ће аутоматски прочитати текст, а hint ће додати непотребну буку.
Забуна са Label — коришћење contentDescription уместо label за текстуална дугмад. У iOS-у accessibilityLabel треба да се поклапа са текстом дугмета (или буде празан ако је текст већ видљив), а hint само објашњава радњу. Према подацима Google Testing Blog, 2024, 23% проверених апликација у Play Store-у имају дуплиране описе.
Игнорисање динамике — опис се не ажурира при промени стања. На пример, код прекидача «Wi-Fi» опис остаје «Укључи Wi-Fi» чак и након укључења. Исправно: динамички мењати опис на «Искључи Wi-Fi» кроз посматрање стања.
Након ажурирања дизајна (промена икона, премештање елемената), Content Description често нестане. Разлог: дизајнер замењује слику, програмер не проверава својства приступачности новог средства. Решење: учинити проверу приступачности обавезним кораком code review-а — додати контролну листу са ставком «Content Description ажуриран?».
func testContentDescriptionExists() {
let app = XCUIApplication()
app.launch()
let image = app.images["chart-sales"]
XCTAssertNotNil(image.label)
XCTAssertGreaterThan(image.label.count, 0)
}
Често постављана питања
Корисник VoiceOver-а или TalkBack-а чуће само «слика» или «дугме» — без навођења намене. Ово крши WCAG 1.1.1 и чини апликацију недоступном за људе са оштећењем вида.
Не. Ако дугме садржи текстуалну ознаку, VoiceOver ће је аутоматски прочитати. Опис (accessibilityHint) се може додати ради објашњења резултата притиска, али Label није потребан.
У iOS-у поставите isAccessibilityElement = false. У Android-у поставите contentDescription = "@null". Screen reader ће потпуно прескочити такав елемент, не производећи звук.
У iOS-у користите NSLocalizedString за accessibilityHint, у Android-у — ресурсе низа преко @string/. Превод описа је обавезан за све подржане језике.
Додајте UI тестове који проверавају присуство описа за све ImageView. У iOS-у — XCUIApplication, у Android-у — AccessibilityCheckRule из Espresso-а. Accessibility Scanner се може покренути у CI-у преко командне линије.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође