Texto rolante em aplicações — o que é, como criar e configurar

Autor: IT Sectr Publicado: 2026-07-25 Tempo de leitura: 9 min

O texto rolante (marquee) é um efeito visual no qual o texto rola automaticamente horizontalmente dentro de uma área limitada, permitindo exibir strings longas em um contêiner compacto. Historicamente, o termo vem da tag HTML <marquee>, popular na web dos anos 1990. No desenvolvimento móvel moderno, o scrolling text é usado em players, tickers de notícias e barras de status. De acordo com as Apple Human Interface Guidelines e o Google Material Design, o marquee só é aceitável em cenários limitados onde o truncamento estático com reticências degrada a UX.

Pontos principais

  • Texto rolante — rolagem horizontal automática de texto longo em um contêiner limitado.
  • No Android é implementado via android:ellipsize="marquee" no TextView.
  • No iOS o efeito é feito manualmente com Core Animation ou SwiftUI com animação offset.
  • Na web, a tag <marquee> está obsoleta; usa-se animação CSS com translateX.
  • Para acessibilidade, o suporte a prefers-reduced-motion é obrigatório.

O que é texto rolante?

O texto rolante é um efeito de UI no qual o texto se move horizontalmente dentro de uma área fixa, rolando ciclicamente para que o usuário possa ler todo o conteúdo que não cabe no contêiner. Ao contrário do ellipsize, que esconde parte do texto, o marquee mostra o texto inteiro, mas em movimento.

O termo marquee se consolidou graças à tag HTML <marquee>, que foi adicionada nas primeiras versões dos navegadores Netscape e Internet Explorer. A tag permitia criar texto rolante sem JavaScript ou CSS, mas nunca fez parte do padrão HTML. Os navegadores modernos continuam a suportá-la para compatibilidade retroativa, mas seu uso não é recomendado.

No desenvolvimento móvel, o marquee resolve o problema de rótulos longos em contêineres compactos: nomes de faixas em um player, tickers de moedas, notícias em telas de TV. No entanto, devido à animação, ele cria uma carga para a acessibilidade e pode irritar os usuários — portanto, é usado seletivamente.

De acordo com a pesquisa do Nielsen Norman Group (2023), o texto em movimento reduz a velocidade de leitura em 15-20% e aumenta a carga cognitiva. Use marquee apenas quando o truncamento estático (ellipsize) for realmente inaceitável.

Texto rolante no Android via TextView

No Android, o marquee é implementado pelo mecanismo integrado do TextView através do atributo android:ellipsize="marquee". Este é o único modo ellipsize que não trunca o texto, mas anima sua rolagem.

Para ativar o marquee, três condições devem ser atendidas: singleLine="true" (ou maxLines="1"), ellipsize="marquee" e setSelected(true) no código. Sem chamar setSelected(), a animação não será iniciada.

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: activate marquee
textView.setSelected(true)
textView.isSingleLine = true

O atributo marqueeRepeatLimit determina o número de repetições da animação: marquee_forever (infinito) ou um número específico. O padrão é marquee_forever. Se o texto for mais curto que a largura do contêiner, a animação não inicia — o TextView exibe texto estático.

Uma característica importante: setSelected(true) só funciona quando o TextView está com foco ou em modo selecionado. No RecyclerView, isso pode causar problemas — a animação só inicia para um item. A solução é usar um MarqueeTextView personalizado que sobrescreva isFocused() e sempre retorne true.

A partir do Android 9 (API 28), o Google melhorou o comportamento do marquee — a animação ficou mais suave e não congela ao rolar uma lista. No entanto, em dispositivos mais antigos, o marquee pode tremer, especialmente em altas densidades de pixels.

Implementação de scrolling text no iOS

O iOS não tem um equivalente integrado ao android:ellipsize="marquee". O marquee é implementado manualmente usando Core Animation ou animação SwiftUI. A abordagem mais comum é animar layer.position combinado com um contêiner de recorte.

No UIKit, o marquee é construído com três elementos: um contêiner UILabel com clipsToBounds = true, o próprio texto e uma CABasicAnimation para deslocar o texto no eixo X com repetição infinita e autoreverses = false, para que a linha role em uma direção e volte com um salto.

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")
}

Calcular duration = textWidth / 60 dá uma velocidade de aproximadamente 60 pixels por segundo — um ritmo confortável para leitura. Se a velocidade exceder 120 px/s, o texto se torna ilegível. Se for inferior a 30 px/s, a animação parece lenta. Ajuste a velocidade para seu cenário específico.

No SwiftUI, o marquee é implementado de forma mais simples — usando o modificador offset() com animação repetível e .animation(.linear(duration:).repeatForever(autoreverses: false)). O SwiftUI gerencia automaticamente o ciclo de vida da animação, mas requer GeometryReader para determinar a largura do texto.

Animação CSS em vez da tag marquee

Na web, a tag obsoleta <marquee> não é recomendada para uso, embora os navegadores continuem a suportá-la. A implementação moderna do marquee é a animação CSS com keyframes e transform: translateX.

Vantagens da abordagem CSS: controle total sobre velocidade, pausa e curva de animação, suporte a prefers-reduced-motion para acessibilidade e ausência de uma tag semanticamente incorreta.

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

O truque principal: display: inline-block no conteúdo garante que a largura do elemento seja igual à largura do texto, e translateX(-100%) o desloca exatamente essa largura para a esquerda. Se o conteúdo for display: block, translateX(-100%) será igual à largura do contêiner, não à do texto, e a animação quebrará.

Para acessibilidade, adicione @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } } — usuários com distúrbios vestibulares verão texto estático com capacidade de rolagem.

Quando usar e quando evitar

O marquee é justificado em cenários onde o usuário não pode expandir o contêiner por si mesmo e o texto completo é criticamente importante: a faixa atual em um player na tela bloqueada, um ticker de notícias em um painel de TV ou um marquee em um aplicativo de transporte (status do pedido).

O marquee não deve ser usado em tabelas, listas, formulários e diálogos — em qualquer lugar onde o usuário interaja ativamente com a interface. A animação distrai do objetivo, aumenta o tempo de busca de elementos e causa desconforto. De acordo com a WebAIM (2024), 1 em cada 3 usuários com distúrbios vestibulares relata desconforto ao visualizar texto animado.

Uma regra prática: se o texto pode ser encurtado ou quebrado para a próxima linha — faça isso. O marquee é um último recurso, não uma solução universal para rótulos longos.

Acessibilidade: animação e reduced motion

O marquee é uma das animações de UI mais problemáticas do ponto de vista da acessibilidade. O texto em movimento pode causar tontura, náusea e desorientação em pessoas com distúrbios vestibulares. De acordo com a WCAG 2.2, qualquer animação que dure mais de 5 segundos deve ter um mecanismo de pausa ou desativação.

No iOS, use a propriedade UIAccessibility.isReduceMotionEnabled para verificar a configuração do sistema. Se reduceMotion estiver ativado — não inicie a animação, mostre texto estático com ellipsize.

No Android, verifique a animação do sistema através de Settings.Global.ANIMATOR_DURATION_SCALE. Se a animação global estiver desativada (duration scale = 0), o marquee não deve ser ativado.

Na web, use o recurso de mídia prefers-reduced-motion: @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } }. Este é um recurso CSS padrão suportado por todos os navegadores modernos. Verifique no DevTools: ative a emulação de prefers-reduced-motion e confirme que a animação desliga.

Perguntas frequentes

Qual a diferença entre Marquee e Ellipsize?

Ellipsize trunca o texto e adiciona reticências, escondendo parte do conteúdo. Marquee rola o texto inteiro, mas em movimento. A escolha depende da prioridade: mostrar tudo (marquee) ou manter a exibição estática (ellipsize).

Como acelerar ou desacelerar o marquee no Android?

O android:ellipsize="marquee" integrado não permite alterar a velocidade — ela é determinada pelo ScrollSpeed do sistema. Para velocidade personalizada, use Animation ou ValueAnimator manualmente.

Por que o marquee não funciona no RecyclerView?

Devido à reciclagem de views, setSelected(true) é redefinido. Solução: crie um MarqueeTextView personalizado que sobrescreva isFocused() e retorne true, ou use animação personalizada em Adapter.onViewAttachedToWindow().

É possível fazer um marquee vertical?

Sim, usando translateY em vez de translateX. O marquee vertical é usado para créditos ou tickers de notícias em feeds verticais. O princípio é o mesmo, mas o eixo da animação muda.

Como parar o marquee ao focar?

Em CSS: :hover { animation-play-state: paused; }. No Android: monitore o foco via OnFocusChangeListener e redefina setSelected(false). No iOS: remova a animação via layer.removeAnimation(forKey:).

Resumo

  • Texto rolante — rolagem horizontal do texto, mostrando o conteúdo completo através de animação.
  • No Android, o android:ellipsize="marquee" integrado requer setSelected(true) e singleLine="true".
  • No iOS, a implementação é feita via CABasicAnimation com o key path position.x.
  • Na web, a tag <marquee> está obsoleta; use CSS @keyframes com translateX.
  • Use marquee apenas quando ellipsize for inaceitável — em players, tickers, barras de status.
  • Desative a animação para prefers-reduced-motion em todas as plataformas.
  • Velocidade de animação: ~60 px/s — confortável para leitura, acima de 120 px/s — ilegível.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também