Yuguruvchi satr (marquee) — bu matn cheklangan maydon ichida avtomatik ravishda gorizontal siljiydigan vizual effekt bo'lib, uzun qatorlarni ixcham konteynerda ko'rsatishga imkon beradi. Tarixiy jihatdan atama 1990-yillar vebida mashhur bo'lgan <marquee> HTML tegi kelib chiqqan. Zamonaviy mobil ishlanmada scrolling text pleerlarda, yangiliklar tickerlarida va holat satrlarida ishlatiladi. Apple Human Interface Guidelines va Google Material Design ma'lumotlariga ko'ra, yuguruvchi satr faqat cheklangan stsenariylarda ruxsat etiladi, bunda statik kesish uch nuqta bilan UX-ni yomonlashtiradi.
Asosiy
Yuguruvchi satr — bu UI effekt bo'lib, unda matn qat'iy maydon ichida gorizontal harakatlanadi, tsiklik siljiydi, foydalanuvchi konteynerga sig'maydigan barcha tarkibni o'qiy oladi. Matnni yashiradigan ellipsizedan farqli o'laroq, marquee butun matnni ko'rsatadi, lekin harakatda.
Marquee atamasi (ing. — "chodir", "reklama taxtasi") Netscape va Internet Explorer brauzerlarining dastlabki versiyalarida qo'shilgan <marquee> HTML tegi tufayli mustahkamlangan. Teg JavaScript va CSSsiz harakatlanuvchi matn yaratishga imkon berar edi, lekin hech qachon HTML standartining bir qismi bo'lmagan. Zamonaviy brauzerlar orqaga qarab moslik uchun uni qo'llab-quvvatlashda davom etadi, lekin undan foydalanish tavsiya etilmaydi.
Mobil ishlanmada yuguruvchi satr ixcham konteynerlarda uzun yozuvlar muammosini hal qiladi: pleerdagi qo'shiq nomlari, valyuta kurslari tickerlari, televidenie ekranlaridagi yangiliklar satrlari. Biroq animatsiya tufayli accessibility yuklaydi va foydalanuvchilarni bezovta qilishi mumkin — shuning uchun nuqtali qo'llaniladi.
Nielsen Norman Group (2023) tadqiqotlariga ko'ra, harakatlanuvchi matn o'qish tezligini 15-20% kamaytiradi va kognitiv yukni oshiradi. Yuguruvchi satrni faqat statik kesish (ellipsize) haqiqatan ham qabul qilib bo'lmas bo'lganda ishlating.
Androidda yuguruvchi satr TextViewning o'rnatilgan mexanizmi orqali android:ellipsize="marquee" atributi bilan amalga oshiriladi. Bu matnni kesmaydigan, balki uning siljishini animatsiya qiladigan yagona ellipsize rejimidir.
Marquee-ni faollashtirish uchun uchta shart bajarilishi kerak: singleLine="true" (yoki maxLines="1"), ellipsize="marquee" va kodda setSelected(true). setSelected() chaqirilmasa, animatsiya boshlanmaydi.
<!-- XML layout -->
<TextView
android:id="@+id/marquee_text"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever" />
// Kotlin: marquee-ni faollashtir
textView.setSelected(true)
textView.isSingleLine = true
marqueeRepeatLimit atributi animatsiya takrorlanish sonini belgilaydi: marquee_forever (cheksiz) yoki aniq raqam. Standart — marquee_forever. Agar matn konteyner kengligidan qisqa bo'lsa, animatsiya boshlanmaydi — TextView statik matnni ko'rsatadi.
Muhim xususiyat: setSelected(true) faqat TextView fokusda bo'lganda yoki selected rejimida ishlaydi. RecyclerViewda bu muammolarni keltirib chiqarishi mumkin — animatsiya faqat bitta element uchun boshlanadi. Yechim — isFocused() ni override qiladigan va har doim true qaytaradigan maxsus MarqueeTextView dan foydalanish.
Android 9 (API 28) dan boshlab, Google marquee xatti-harakatini yaxshiladi — animatsiya silliqroq bo'ldi va ro'yxatni aylantirishda qotib qolmaydi. Biroq eski qurilmalarda marquee, ayniqsa yuqori piksel zichligida, silkinishi mumkin.
iOSda android:ellipsize="marquee" ning o'rnatilgan analogi yo'q. Yuguruvchi satr qo'lda Core Animation yoki SwiftUI animatsiyasi orqali amalga oshiriladi. Eng keng tarqalgan yondashuv — clipping konteyneri bilan birgalikda layer.position animatsiyasi.
UIKitda yuguruvchi satr uchta elementga asoslanadi: clipsToBounds = true bo'lgan UILabel konteyneri, matnning o'zi va matnni X bo'ylab cheksiz takrorlash bilan siljitadigan CABasicAnimation, autoreverses = false bilan, satr bir tomonga siljib, sakrab qaytadi.
func startMarquee(for label: UILabel) {
label.clipsToBounds = true
label.numberOfLines = 1
let textWidth = (label.text as? NSString)?
.size(withAttributes: [.font: label.font as any]).width ?? 0
guard textWidth > label.bounds.width else { return }
let animation = CABasicAnimation(keyPath: "position.x")
animation.fromValue = label.layer.position.x + label.bounds.width / 2
animation.toValue = label.layer.position.x - textWidth - label.bounds.width / 2
animation.duration = CFTimeInterval(textWidth / 60)
animation.repeatCount = .infinity
animation.autoreverses = false
label.layer.add(animation, forKey: "marquee")
}
Duration = textWidth / 60 hisobi soniyada taxminan 60 piksel tezlikni beradi — o'qish uchun qulay temp. Tezlik 120 px/s dan yuqori bo'lsa, matn o'qib bo'lmas holga keladi. 30 px/s dan past bo'lsa — animatsiya sust ko'rinadi. Tezlikni aniq stsenariyga mos ravishda o'zgartiring.
SwiftUIda yuguruvchi satr soddaroq amalga oshiriladi — takrorlanuvchi animatsiya bilan offset() modifikatori va .animation(.linear(duration:).repeatForever(autoreverses: false)) orqali. SwiftUI animatsiyaning hayot aylanishini avtomatik boshqaradi, lekin matn kengligini aniqlash uchun GeometryReader talab qiladi.
Vebda eskirgan <marquee> tegi tavsiya etilmaydi, garchi brauzerlar uni qo'llab-quvvatlashda davom etsa. Yuguruvchi satrning zamonaviy tatbiqi — kalit kadrlar bilan CSS animatsiyasi va transform: translateX.
CSS yondashuvining afzalliklari: tezlik, pauza va animatsiya egri chizig'i ustidan to'liq nazorat, accessibility uchun prefers-reduced-motion qo'llab-quvvatlashi, semantik jihatdan noto'g'ri tegning yo'qligi.
.marquee {
overflow: hidden;
white-space: nowrap;
width: 300px;
}
.marquee-content {
display: inline-block;
animation: marquee 10s linear infinite;
}
@keyframes marquee {
0% { transform: translateX(0); }
100% { transform: translateX(-100%); }
}
/* Pause on hover */
.marquee-content:hover {
animation-play-state: paused;
}
Asosiy hiyla: kontentda display: inline-block element kengligi matn kengligiga teng bo'lishini ta'minlaydi va translateX(-100%) uni aynan shu kenglikka chapga siljitadi. Agar kontent display: block bo'lsa, translateX(-100%) konteyner kengligiga teng bo'ladi, matn kengligiga emas, va animatsiya buziladi.
Accessibility uchun @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } } qo'shing — vestibulyar buzilishlari bo'lgan foydalanuvchilar aylantirish imkoniyati bilan statik matnni ko'radilar.
Yuguruvchi satr foydalanuvchi konteynerni o'zi kengaytira olmaydigan va to'liq matn muhim bo'lgan stsenariylarda oqlanadi: bloklangan ekranda pleerdagi joriy trek, televizion panelda yangiliklar satri, taksi ilovasida yuguruvchi satr (buyurtma holati).
Yuguruvchi satr ishlatilmasligi kerak jadvallar, ro'yxatlar, formalar va dialoglarda — foydalanuvchi interfeys bilan faol o'zaro aloqada bo'lgan har joyda. Animatsiya chalg'itadi, elementni qidirish vaqtini oshiradi va noqulaylik yaratadi. WebAIM (2024) ma'lumotlariga ko'ra, vestibulyar buzilishlari bo'lgan har 3 foydalanuvchidan 1 tasi animatsiyalangan matnni ko'rishda noqulaylik haqida xabar beradi.
Asosiy qoida: agar matnni qisqartirish yoki keyingi qatorga joylashtirish mumkin bo'lsa — buni qiling. Yuguruvchi satr oxirgi chora, uzun yozuvlar uchun universal yechim emas.
Yuguruvchi satr accessibility nuqtai nazaridan eng muammoli UI animatsiyalaridan biridir. Harakatlanuvchi matn vestibulyar buzilishlari bo'lgan odamlarda bosh aylanishi, ko'ngil aynishi va orientatsiyani yo'qotishga sabab bo'lishi mumkin. WCAG 2.2 ga ko'ra, 5 soniyadan ortiq davom etadigan har qanday animatsiya to'xtatish yoki o'chirish mexanizmiga ega bo'lishi kerak.
iOSda tizim sozlamalarini tekshirish uchun UIAccessibility.isReduceMotionEnabled xususiyatidan foydalaning. Agar reduceMotion yoqilgan bo'lsa — animatsiyani boshlamang, ellipsize bilan statik matnni ko'rsating.
Androidda tizim animatsiyasini Settings.Global.ANIMATOR_DURATION_SCALE orqali tekshiring. Agar global animatsiya o'chirilgan bo'lsa (duration scale = 0), yuguruvchi satr yoqilmasligi kerak.
Vebda prefers-reduced-motion media funksiyasidan foydalaning: @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } }. Bu barcha zamonaviy brauzerlar tomonidan qo'llab-quvvatlanadigan standart CSS imkoniyatidir. DevToolsda tekshiring: prefers-reduced-motion emulyatsiyasini yoqing va animatsiyaning o'chayotganiga ishonch hosil qiling.
Ko'p beriladigan savollar
Ellipsize matnni kesadi va uch nuqta qo'yadi, tarkibning bir qismini yashiradi. Marquee butun matnni siljitadi, lekin harakatda. Tanlov ustuvorlikka bog'liq: hamma narsani ko'rsatish (marquee) yoki statikani saqlash (ellipsize).
O'rnatilgan android:ellipsize="marquee" tezlikni o'zgartirishga imkon bermaydi — u tizim ScrollSpeed tomonidan belgilanadi. Maxsus tezlik uchun Animation yoki ValueAnimator dan qo'lda foydalaning.
Viewlarning qayta ishlatilishi sababli setSelected(true) qayta tiklanadi. Yechim: isFocused() ni override qiladigan va true qaytaradigan maxsus MarqueeTextView yarating yoki Adapter.onViewAttachedToWindow() da maxsus animatsiyadan foydalaning.
Ha, translateX o'rniga translateY orqali. Vertikal marquee titrlar (credits) yoki vertikal lentalarda yangiliklar satrlari uchun ishlatiladi. Printsip bir xil, ammo animatsiya o'qi o'zgaradi.
CSSda: :hover { animation-play-state: paused; }. Androidda: fokusni OnFocusChangeListener orqali kuzating va setSelected(false) ni chaqiring. iOSda: layer.removeAnimation(forKey:) orqali animatsiyani olib tashlang.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.