Tətbiqlərdə sürünən sətir — nədir, necə yaratmaq və quraşdırmaq

Müəllif: IT Sectr Dərc olunub: 2026-07-25 Oxuma vaxtı: 9 dəq

Sürünən sətir (marquee) — mətnin məhdud bir sahə daxilində avtomatik olaraq üfüqi şəkildə sürüşdüyü vizual effektdir və uzun sətirlərin kompakt konteynerdə göstərilməsinə imkan verir. Tarixən bu termin 1990-cı illərin vebində məşhur olan <marquee> HTML teqindən qaynaqlanır. Müasir mobil inkişafda scrolling text pleyerlərdə, xəbər tickerlərində və status sətirlərində istifadə olunur. Apple Human Interface Guidelines və Google Material Design-a görə, sürünən sətir yalnız məhdud ssenarilərdə icazəlidir, burada statik kəsmə üç nöqtə ilə UX-i pisləşdirir.

Əsas məqamlar

  • Sürünən sətir — uzun mətnin məhdud konteynerdə avtomatik üfüqi sürüşdürülməsidir.
  • Android-də TextView-də android:ellipsize="marquee" vasitəsilə həyata keçirilir.
  • iOS-da effekt əl ilə Core Animation və ya SwiftUI offset animasiyası ilə edilir.
  • Vebdə HTML <marquee> teqi köhnəlmişdir; translateX ilə CSS animasiyası istifadə olunur.
  • Accessibility üçün prefers-reduced-motion dəstəyi məcburidir.

Sürünən sətir nədir?

Sürünən sətir — mətnin sabit bir sahə daxilində üfüqi şəkildə hərəkət etdiyi, dövrəvi olaraq sürüşdüyü UI effektidir ki, istifadəçi konteynerə sığmayan bütün məzmunu oxuya bilsin. Mətni gizlədən ellipsize-dən fərqli olaraq, marquee bütün mətni göstərir, ancaq hərəkətdə.

Marquee termini (ing. — "çadır", "reklam lövhəsi") Netscape və Internet Explorer brauzerlərinin ilkin versiyalarına əlavə edilmiş <marquee> HTML teqi sayəsində möhkəmlənmişdir. Teq JavaScript və CSS olmadan sürüşən mətn yaratmağa imkan verirdi, lakin heç vaxt HTML standartının bir hissəsi olmamışdır. Müasir brauzerlər geriyə uyğunluq üçün onu dəstəkləməyə davam edir, lakin ondan istifadə tövsiyə edilmir.

Mobil inkişafda sürünən sətir kompakt konteynerlərdə uzun etiketlər problemini həll edir: pleyerdə mahnı adları, valyuta məzənnəsi tickerləri, televiziya ekranlarında xəbər sətirləri. Lakin animasiyaya görə accessibility-ə yük yaradır və istifadəçiləri qıcıqlandıra bilər — buna görə də nöqtəli şəkildə tətbiq olunur.

Nielsen Norman Group (2023) tədqiqatlarına görə, hərəkətli mətn oxu sürətini 15-20% azaldır və idrak yükünü artırır. Sürünən sətiri yalnız statik kəsmə (ellipsize) həqiqətən qəbuledilməz olduqda istifadə edin.

Android-də TextView vasitəsilə sürünən sətir

Android-də sürünən sətir TextView-nin daxili mexanizmi vasitəsilə android:ellipsize="marquee" atributu ilə həyata keçirilir. Bu, mətni kəsməyən, əksinə onun sürüşməsini animasiya edən yeganə ellipsize rejimidir.

Marquee-ni aktivləşdirmək üçün üç şərt yerinə yetirilməlidir: singleLine="true" (və ya maxLines="1"), ellipsize="marquee" və kodda setSelected(true). setSelected() çağırılmazsa, animasiya başlamayacaq.

xml
<!-- 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 aktivləşdir
textView.setSelected(true)
textView.isSingleLine = true

marqueeRepeatLimit atributu animasiyanın təkrar sayını təyin edir: marquee_forever (sonsuz) və ya konkret rəqəm. Varsayılan olaraq — marquee_forever. Mətn konteynerin genişliyindən qısadırsa, animasiya başlamır — TextView statik mətn göstərir.

Əhəmiyyətli xüsusiyyət: setSelected(true) yalnız TextView fokusda olduqda və ya seçilmiş rejimdə olduqda işləyir. RecyclerView-də bu problem yarada bilər — animasiya yalnız bir element üçün başlayır. Həll yolu — isFocused()-u override edən və həmişə true qaytaran xüsusi MarqueeTextView istifadə etməkdir.

Android 9-dan (API 28) başlayaraq, Google marquee davranışını yaxşılaşdırdı — animasiya daha hamar oldu və siyahının sürüşdürülməsi zamanı donmur. Lakin köhnə cihazlarda marquee, xüsusilə yüksək piksel sıxlığında, sıçraya bilər.

iOS-da scrolling text tətbiqi

iOS-da android:ellipsize="marquee"-nin daxili analoqu yoxdur. Sürünən sətir əl ilə Core Animation və ya SwiftUI animasiyası vasitəsilə həyata keçirilir. Ən geniş yayılmış yanaşma — layer.position animasiyasının clipping konteyneri ilə birləşdirilməsidir.

UIKit-də sürünən sətir üç element üzərində qurulur: clipsToBounds = true olan UILabel konteyneri, mətnin özü və mətni X oxu boyunca sonsuz təkrarla sürüşdürən CABasicAnimation, autoreverses = false ilə ki, sətir bir istiqamətdə sürüşsün və sıçrayışla qayıtsın.

swift
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 hesablanması saniyədə təxminən 60 piksel sürət verir — oxumaq üçün rahat temp. Sürət 120 px/s-dən yuxarı olarsa, mətn oxunmaz hala gəlir. 30 px/s-dən aşağı olarsa — animasiya ləng görünür. Sürəti konkret ssenariyə uyğun dəyişin.

SwiftUI-də sürünən sətir daha sadə həyata keçirilir — offset() modifieri ilə təkrarlanan animasiya və .animation(.linear(duration:).repeatForever(autoreverses: false)). SwiftUI animasiyanın həyat dövrünü avtomatik idarə edir, lakin mətnin genişliyini təyin etmək üçün GeometryReader tələb edir.

Marquee teqi əvəzinə CSS animasiyası

Vebdə köhnəlmiş <marquee> teqi tövsiyə edilmir, baxmayaraq ki, brauzerlər onu dəstəkləməyə davam edir. Sürünən sətirin müasir tətbiqi — açar kadrlarla CSS animasiyası və transform: translateX.

CSS yanaşmasının üstünlükləri: sürət, pauza və animasiya əyrisi üzərində tam nəzarət, accessibility üçün prefers-reduced-motion dəstəyi, semantik cəhətdən düzgün olmayan teqin olmaması.

css
.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;
}

Əsas hiylə: kontentdə display: inline-block elementin genişliyinin mətnin genişliyinə bərabər olmasını təmin edir, translateX(-100%) isə onu dəqiq bu genişlikdə sola sürüşdürür. Kontentdə display: block olarsa, translateX(-100%) konteynerin genişliyinə bərabər olacaq, mətnin genişliyinə yox, və animasiya pozulacaq.

Accessibility üçün @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } } əlavə edin — vestibulyar pozuntusu olan istifadəçilər sürüşdürmə imkanı ilə statik mətn görəcəklər.

Nə vaxt istifadə etməli və nə vaxt çəkinməli

Sürünən sətir əsaslandırılmışdır istifadəçinin konteyneri özü genişləndirə bilmədiyi və tam mətnin kritik əhəmiyyət daşıdığı ssenarilərdə: bloklanmış ekranda pleyerdə cari trek, televiziya panelində xəbər sətri, taksi tətbiqində sürünən sətir (sifariş statusu).

Sürünən sətir istifadə edilməməlidir cədvəllərdə, siyahılarda, formalarda və dialoqlarda — istifadəçinin interfeyslə aktiv qarşılıqlı əlaqədə olduğu hər yerdə. Animasiya diqqəti yayındırır, elementin axtarış vaxtını artırır və narahatlıq yaradır. WebAIM (2024) məlumatlarına görə, vestibulyar pozuntusu olan hər 3 istifadəçidən 1-i animasiyalı mətnə baxarkən narahatlıq bildirir.

Əsas qayda: mətni qısaltmaq və ya növbəti sətirə yerləşdirmək mümkündürsə — bunu edin. Sürünən sətir son çarədir, uzun etiketlər üçün universal həll yolu deyil.

Accessibility: animasiya və reduced motion

Sürünən sətir accessibility baxımından ən problemli UI animasiyalarından biridir. Hərəkətli mətn vestibulyar pozuntusu olan insanlarda başgicəllənmə, ürəkbulanma və oriyentasiya itkisinə səbəb ola bilər. WCAG 2.2-yə görə, 5 saniyədən çox davam edən hər hansı animasiya dayandırma və ya söndürmə mexanizminə malik olmalıdır.

iOS-da sistem parametrini yoxlamaq üçün UIAccessibility.isReduceMotionEnabled xüsusiyyətindən istifadə edin. Əgər reduceMotion aktivdirsə — animasiyanı işə salmayın, ellipsize ilə statik mətn göstərin.

Android-də sistem animasiyasını Settings.Global.ANIMATOR_DURATION_SCALE vasitəsilə yoxlayın. Əgər qlobal animasiya söndürülübsə (duration scale = 0), sürünən sətir işə salınmamalıdır.

Vebdə prefers-reduced-motion media funksiyasından istifadə edin: @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } }. Bu, bütün müasir brauzerlər tərəfindən dəstəklənən standart CSS imkanıdır. DevTools-da yoxlayın: prefers-reduced-motion emulyasiyasını aktivləşdirin və animasiyanın söndüyünə əmin olun.

Tez-tez verilən suallar

Marquee Ellipsize-dan nə ilə fərqlənir?

Ellipsize mətni kəsir və üç nöqtə qoyur, məzmunun bir hissəsini gizlədir. Marquee bütün mətni sürüşdürür, ancaq hərəkətdə. Seçim prioritetdən asılıdır: hər şeyi göstərmək (marquee) və ya statikanı saxlamaq (ellipsize).

Android-də sürünən sətri necə sürətləndirmək və ya yavaşlatmaq olar?

Daxili android:ellipsize="marquee" sürəti dəyişməyə imkan vermir — o, sistem ScrollSpeed tərəfindən müəyyən edilir. Xüsusi sürət üçün əl ilə Animation və ya ValueAnimator istifadə edin.

Marquee RecyclerView-də niyə işləmir?

View-lərin təkrar istifadəsi səbəbindən setSelected(true) sıfırlanır. Həll yolu: isFocused()-u override edən və true qaytaran xüsusi MarqueeTextView yaradın və ya Adapter.onViewAttachedToWindow()-da xüsusi animasiyadan istifadə edin.

Şaquli sürünən sətir etmək mümkündürmü?

Bəli, translateX əvəzinə translateY vasitəsilə. Şaquli marquee titrlər (credits) və ya şaquli lentlərdə xəbər sətirləri üçün istifadə olunur. Prinsip eynidir, ancaq animasiya oxu dəyişir.

Fokus zamanı sürünən sətri necə dayandırmaq olar?

CSS-də: :hover { animation-play-state: paused; }. Android-də: fokusu OnFocusChangeListener vasitəsilə izləyin və setSelected(false) çağırın. iOS-da: layer.removeAnimation(forKey:) vasitəsilə animasiyanı silin.

Nəticə

  • Sürünən sətir — məzmunu tam göstərən animasiya vasitəsilə mətnin üfüqi sürüşdürülməsidir.
  • Android-də daxili android:ellipsize="marquee" setSelected(true) və singleLine="true" tələb edir.
  • iOS-da tətbiq CABasicAnimation ilə position.x açar yolu vasitəsilə edilir.
  • Vebdə <marquee> teqi köhnəlmişdir; CSS @keyframes ilə translateX istifadə edin.
  • Marquee-ni yalnız ellipsize qəbuledilməz olduqda tətbiq edin — pleyerlərdə, tickerlərdə, status sətirlərində.
  • Bütün platformalarda prefers-reduced-motion zamanı animasiyanı mütləq söndürün.
  • Animasiya sürəti: ~60 px/s — oxumaq üçün rahat, 120 px/s-dən yuxarı — oxunmaz.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun