Focus Order হল সেই ক্রম যেখানে ইন্টারফেস উপাদানগুলি কীবোর্ড, Switch Control, VoiceOver বা TalkBack-এর সাহায্যে নেভিগেট করার সময় ফোকাস পায়। মোবাইল অ্যাপ্লিকেশনে, ফোকাস অর্ডার নির্ধারণ করে যে ব্যবহারকারী কীভাবে নিয়ন্ত্রণের মধ্যে অঙ্গভঙ্গি বা বোতামের মাধ্যমে চলাচল করে। W3C WCAG 2.2, Success Criterion 2.4.3, 2023 অনুসারে, ফোকাসকে একটি যৌক্তিক ক্রমে অনুসরণ করা উচিত যা বিষয়বস্তুর অর্থ সংরক্ষণ করে। এই নীতি লঙ্ঘন অ্যাক্সেসিবিলিটি অডিট ব্যর্থ হওয়ার একটি সাধারণ কারণ।
মূল বিষয়
Focus Order হল সেই ক্রম যেখানে ব্যবহারকারী বিকল্প ইনপুট পদ্ধতি ব্যবহার করে ইন্টারেক্টিভ উপাদানগুলির মধ্যে চলাচল করে: কীবোর্ড (Tab), Switch Control (ধাপে ধাপে), VoiceOver (ডান/বাম সোয়াইপ) বা TalkBack। মাউস বা টাচ স্ক্রিনের বিপরীতে, যেখানে ব্যবহারকারী সরাসরি একটি উপাদান নির্বাচন করে, ফোকাস নেভিগেশন রৈখিক — প্রতিটি ধাপ পরবর্তী উপাদানে ফোকাস সরায়।
Apple HIG, 2024 অনুসারে, VoiceOver অ্যাক্সেসিবিলিটি ট্রিতে উপাদানগুলির ক্রম ব্যবহার করে, যা ভিজুয়াল অবস্থানের উপর ভিত্তি করে তৈরি করা হয়: উপরের বাম কোণ → নীচের ডান কোণ। যদি স্ক্রিনে জটিল লেআউট (কলাম, Grid, ZStack) থাকে, তবে ট্রি ভিজুয়াল অর্ডারের সাথে মেলে না।
WCAG 2.4.3 নীতি: “যদি একটি ওয়েব পৃষ্ঠা বিভাগগুলির মাধ্যমে ক্রমিকভাবে নেভিগেট করা যায় এবং ফোকাস অর্ডার অর্থকে প্রভাবিত করে, তবে ফোকাসকে এমন একটি ক্রমে অনুসরণ করা উচিত যা অর্থ এবং পরিচালনাযোগ্যতা সংরক্ষণ করে”। ব্যতিক্রম: গতিশীল বিষয়বস্তু যেখানে মনোযোগ আকর্ষণ করতে ফোকাস লাফ দিতে পারে (সতর্কতা, মোডাল উইন্ডো)।
একটি Switch Control ব্যবহারকারী (মোটর অক্ষম ব্যক্তি) স্বয়ংক্রিয়ভাবে উপাদানগুলির মধ্যে চলে — চক্রের পর চক্র। যদি ক্রম ভেঙে যায়, ব্যবহারকারী ফর্ম সম্পূর্ণ করতে 3 গুণ বেশি সময় নেয়। Deque University, 2024 অনুসারে, সঠিক Focus Order সহায়ক প্রযুক্তি ব্যবহারকারীদের জন্য ফর্ম সম্পূর্ণ করার সময় 60% কমিয়ে দেয়।
বিশেষ মনোযোগ — মোডাল উইন্ডো। মোডাল খোলার পরে, ফোকাসকে অবিলম্বে মোডালের ভিতরে প্রথম ইন্টারেক্টিভ উপাদানে যেতে হবে (সাধারণত “বন্ধ” বা “নিশ্চিত” বোতাম)। বন্ধ করার পরে — যে উপাদানটি মোডাল ট্রিগার করেছে তাতে ফিরে আসা উচিত। এটি WCAG 2.4.3-এর প্রয়োজনীয়তা এবং একই সাথে একটি সাধারণ ভুল।
iOS-এ, VoiceOver জ্যামিতির উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে ক্রম তৈরি করে: উপাদানগুলি Y দ্বারা, তারপর X দ্বারা সাজানো হয়। জটিল কাঠামো সহ স্ক্রিনের জন্য, এই ক্রম ভুল হতে পারে — ডেভেলপারকে হস্তক্ষেপ করতে হবে।
প্রধান সরঞ্জাম:
একটি পণ্য কার্ডের জন্য কাস্টম ক্রম সেট করার উদাহরণ:
class ProductCardView: UIView {
let titleLabel = UILabel()
let priceLabel = UILabel()
let buyButton = UIButton()
override var accessibilityElements: [Any]? {
get {
return [titleLabel!, priceLabel!, buyButton!]
}
set {}
}
}
একটি ক্রিয়ার পরে প্রোগ্রাম্যাটিক ফোকাস সরানোর জন্য:
UIAccessibility.post(
notification: .layoutChanged,
argument: newlyAddedItem
)
shouldGroupAccessibilityElement বৈশিষ্ট্য সংগ্রহে কার্ডের জন্য দরকারী। যদি প্যারেন্ট কার্ডে true সেট করা হয়, VoiceOver পুরো কার্ডটিকে একটি উপাদান হিসাবে উপলব্ধি করে। ব্যবহারকারী পুরো কার্ড সক্রিয় করতে ডাবল-ট্যাপ করতে পারে, বা অভ্যন্তরীণ নেভিগেশনের জন্য রটার কনফিগার করতে পারে। UICollectionViewCell এবং UITableViewCell-এর জন্য প্রস্তাবিত।
Android-এ, TalkBackও জ্যামিতিক ক্রম ব্যবহার করে, তবে স্পষ্ট nextFocus* অ্যাট্রিবিউটগুলিকে অগ্রাধিকার দেওয়া হয়। এই অ্যাট্রিবিউটগুলি XML-এ বা প্রোগ্রাম্যাটিকভাবে সেট করা হয়:
| অ্যাট্রিবিউট | উদ্দেশ্য | উদাহরণ |
|---|---|---|
| nextFocusDown | নীচে নেভিগেট করার সময় উপাদান | @+id/field_email |
| nextFocusUp | উপরে নেভিগেট করার সময় উপাদান | @+id/field_name |
| nextFocusLeft | বামে উপাদান | @+id/btn_back |
| nextFocusRight | ডানে উপাদান | @+id/btn_next |
একটি নিবন্ধন ফর্মের জন্য উদাহরণ:
<EditText
android:id="@+id/field_email"
android:nextFocusDown="@+id/field_password" />
<EditText
android:id="@+id/field_password"
android:nextFocusDown="@+id/btn_submit" />
RecyclerView-এর জন্য, ফোকাস অর্ডার গতিশীল — অ্যাডাপ্টার দ্বারা নির্ধারিত। যদি কোষগুলির জটিল গঠন থাকে, descendantFocusability = “beforeDescendants” সেট করুন এবং তালিকা আইটেম নোডে ক্রম সংজ্ঞায়িত করুন। Jetpack Compose-এর জন্য, ফোকাস অর্ডার Modifier.focusOrder() এবং FocusOrder-এর মাধ্যমে সেট করা হয়। অগ্রাধিকার: previous (চাইল্ড), next (পরবর্তী), কাস্টম কী।
যদি কোনো উপাদান ফোকাসের জন্য খুব ছোট হয় (44pt-এর কম), iOS-এ TouchDelegate বা Android-এ minWidth/minHeight-এর মাধ্যমে হিট এলাকা বাড়ান। Google Material Design, 2024 অনুসারে, ন্যূনতম স্পর্শ এলাকা 48×48dp। VoiceOver এবং TalkBack উপাদানের বাউন্ডিং বক্সে ফোকাস করে। 30pt-এর থেকে ছোট উপাদান অঙ্গভঙ্গি ফোকাসের জন্য অ্যাক্সেসযোগ্য নাও হতে পারে — ব্যবহারকারী শারীরিকভাবে সেগুলি স্পর্শ করতে পারে না।
লাফানো ফোকাস — যখন একটি ক্রিয়ার পরে (যেমন, একটি উপাদান মুছে ফেলা) ফোকাস তালিকার শুরুতে বা সিস্টেম “পিছনে” বোতামে চলে যায়। VoiceOver ব্যবহারকারী প্রসঙ্গ হারায়। সমাধান: মুছে ফেলা উপাদানের নিকটতম উপাদানে প্রোগ্রাম্যাটিকভাবে ফোকাস সরান।
অদৃশ্য ফোকাস — একটি উপাদান ফোকাস পায় কিন্তু কোনো ভিজুয়াল নির্দেশক নেই (কীবোর্ড ব্যবহারকারীরা দেখতে পায় না তারা কোথায় আছে)। iOS-এ, কাস্টম নির্দেশকের জন্য UIAccessibility.isVoiceOverRunning চেক করুন। Deque University, 2024 অনুসারে, অদৃশ্য ফোকাস অ্যাক্সেসিবিলিটি অডিট ব্যর্থ হওয়ার দ্বিতীয় সবচেয়ে সাধারণ কারণ।
মোডাল — মোডাল খোলার পরে ফোকাস পটভূমির বিষয়বস্তুতে থাকে। iOS-এ, মোডাল ভিউ স্বয়ংক্রিয়ভাবে ফোকাস ক্যাপচার করে যদি modalPresentationStyle = .pageSheet সেট করা থাকে। Android-এ, ডায়ালগ কন্টেইনারে setFocusable(true) ব্যবহার করুন।
বিপরীত সমস্যা: ফোকাস মোডালের ভিতরে আটকে যায় এবং বের হতে পারে না (বন্ধ করা ছাড়া)। এটি শুধুমাত্র মোডাল উইন্ডোর জন্য গ্রহণযোগ্য — ব্যবহারকারীকে ইচ্ছাকৃতভাবে উইন্ডোটি বন্ধ করতে হবে। সাধারণ স্ক্রিনের জন্য, ফোকাস ট্র্যাপ একটি গুরুতর ত্রুটি। সমাধান: নিশ্চিত করুন যে মোডালের শেষ উপাদান (“বন্ধ” বোতাম) ফোকাস ফেরত পাঠায়।
কাস্টম স্ক্রিন (মানচিত্র, ক্যানভাস, গেম) এর জন্য স্বয়ংক্রিয় জ্যামিতিক ক্রম প্রযোজ্য নয়। ডেভেলপারকে ম্যানুয়ালি অ্যাক্সেসিবিলিটি ট্রি তৈরি করতে হবে। iOS-এ, এর জন্য UIAccessibilityContainer পদ্ধতি ওভাররাইড করা হয়।
কাস্টম ক্যানভাসের জন্য উদাহরণ:
class CanvasView: UIView {
var shapes: [ShapeView] = []
override var accessibilityElements: [Any]? {
get {
// Z-ইনডেক্স দ্বারা আকারগুলি সাজান, জ্যামিতি দ্বারা নয়
return shapes.sorted { $0.zIndex < $1.zIndex }
}
set {}
}
}
Android-এ, কাস্টম View-এর জন্য onInitializeAccessibilityNodeInfo ওভাররাইড করুন:
override fun onInitializeAccessibilityNodeInfo(
info: AccessibilityNodeInfo
) {
super.onInitializeAccessibilityNodeInfo(info)
info.addChild(firstElement)
info.addChild(secondElement)
info.isFocusable = true
}
গতিশীল তালিকা (চ্যাট, নিউজ ফিড) এর জন্য, উপাদান যোগ করার পরে প্রথম নতুন উপাদানে ফোকাস সরান। iOS-এ: UIAccessibility.post(notification: .layoutChanged, argument: newMessage)। Android-এ: sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)।
iOS উপাদানের ফ্রেমের উপর ভিত্তি করে স্বয়ংক্রিয়ভাবে ফোকাস এলাকা নির্ধারণ করে। যদি উপাদানের রূপান্তর (transform, rotation) থাকে, VoiceOver ভুল এলাকায় ফোকাস করতে পারে। স্ক্রিন স্থানাঙ্কে স্পষ্টভাবে accessibilityFrame সেট করুন: element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(element.bounds, in: element)। এটি নিশ্চিত করে যে VoiceOver সঠিক এলাকা হাইলাইট করে।
অ্যানিমেটেড স্ক্রিনের (UIKit Dynamics, Lottie, SpriteKit) জন্য, প্রোগ্রাম্যাটিক ফোকাস বিশেষভাবে গুরুত্বপূর্ণ। VoiceOver গতিশীলভাবে চলমান উপাদানগুলির জন্য অ্যাক্সেসিবিলিটি ট্রি তৈরি করতে পারে না। অ্যানিমেশন কন্টেইনারে isAccessibilityElement = false এবং ভিতরে শুধুমাত্র ইন্টারেক্টিভ উপাদানগুলিতে true সেট করুন।
ম্যানুয়াল পরীক্ষা: VoiceOver (iOS) বা TalkBack (Android) চালু করুন, পুরো ক্রম জুড়ে ডানদিকে সোয়াইপ করুন। ফোকাসকে ভিজুয়াল অর্ডার অনুসরণ করা উচিত — বাম থেকে ডান, উপরে থেকে নীচে। প্রতিটি ইন্টারেক্টিভ উপাদানকে ঠিক একবার ফোকাস পাওয়া উচিত।
স্বয়ংক্রিয় পরীক্ষা চ্যালেঞ্জিং তবে সম্ভব:
func testKeyboardFocusOrder() {
let app = XCUIApplication()
app.launch()
app.textFields["Email"].tap()
// Tab — শুধুমাত্র হার্ডওয়্যার কীবোর্ডের সাথে
}
Android-এর জন্য, Accessibility Testing Framework ব্যবহার করুন:
@Test
fun testFocusOrder() {
onView(withId(R.id.fieldEmail))
.check(matches(isFocusable()))
onView(withId(R.id.fieldEmail))
.perform(focus())
onView(withId(R.id.fieldPassword))
.check(matches(isFocused()))
}
সবচেয়ে নির্ভরযোগ্য পদ্ধতি হল একটি UI পরিস্থিতি পরীক্ষা: ফর্মটি ধাপে ধাপে পূরণ করুন (ইমেল → পাসওয়ার্ড → জমা দিন), পরীক্ষা করুন যে প্রতিটি ধাপ সফলভাবে সম্পন্ন হয়েছে। যদি ফোকাস অর্ডার ভাঙা থাকে, ফোকাসের বাইরের উপাদানের সাথে যোগাযোগের চেষ্টা করলে পরিস্থিতি ব্যর্থ হবে।
Xcode-এর Accessibility Inspector টুল সম্পূর্ণ অ্যাক্সেসিবিলিটি ট্রি দেখায়। আপনি VoiceOver অর্ডারে উপাদানগুলির মাধ্যমে হাঁটতে পারেন এবং সঠিক ফোকাস পথ দেখতে পারেন। Focus Order লঙ্ঘনের স্বয়ংক্রিয় সনাক্তকরণের জন্য “Audit” ট্যাব ব্যবহার করুন।
সচরাচর জিজ্ঞাসিত প্রশ্ন
WCAG 2.4.3 (Focus Order) একটি স্তর A সাফল্যের মানদণ্ড। এটির প্রয়োজন যে ফোকাস অর্ডার ক্রমিক নেভিগেশনের সময় বিষয়বস্তুর অর্থ সংরক্ষণ করে। লঙ্ঘন গুরুতর হিসাবে বিবেচিত হয় এবং সার্টিফিকেশন ব্লক করে।
লুকানো উপাদানগুলির iOS-এ isAccessibilityElement = false বা Android-এ visibility = gone/invisible থাকতে হবে। উপস্থিত হলে, UIAccessibility.post(notification: .layoutChanged)-এর মাধ্যমে প্রোগ্রাম্যাটিকভাবে ফোকাস সরান।
iOS accessibilityElements এবং shouldGroupAccessibilityElement-এর মাধ্যমে পরিচালনা করে, Android nextFocus* অ্যাট্রিবিউট এবং AccessibilityNodeInfo-এর মাধ্যমে। নীতি একই: ডিফল্টরূপে জ্যামিতিক ক্রম যা ওভাররাইড করা যেতে পারে।
মূল উপাদানে descendantFocusability = “beforeDescendants” সেট করুন এবং প্রতিটি কোষের জন্য onInitializeAccessibilityNodeInfo-এর মাধ্যমে অ্যাডাপ্টারে অর্ডার কনফিগার করুন।
Bluetooth বা USB-এর মাধ্যমে একটি হার্ডওয়্যার কীবোর্ড সংযুক্ত করুন। iOS-এ ফোকাস সরাতে Tab টিপুন। Android-এ TalkBack চালু করুন এবং Tab এবং তীর কী ব্যবহার করুন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন