Skip to content

Tudo para WordPress, desenvolvimento web — e não só

📜 Bloco de scroll em CSS e jQuery: altura fixa com rolagem

📜 Bloco de scroll em CSS e jQuery: altura fixa com rolagem

Blocos de texto SEO em parede, comentários de meio ecrã, registos de administração e tabelas de 30 colunas quebram o layout e obrigam os leitores a fazer scroll infinito. Parece-lhe familiar? Há uma solução, e é embaraçosamente simples: um bloco com altura fixa e scroll interno.

Quando comecei a construir layouts, enfiava o conteúdo em overflow: hidden e rezava para que ninguém reparasse no texto cortado. Depois descobri os blocos de scroll, e isso mudou tudo: os textos de SEO dos clientes ficaram organizados, as páginas deixaram de inchar no telemóvel e os scripts vizinhos nunca mais entraram em conflito.

Abaixo estão duas abordagens funcionais: CSS puro (para a maioria das tarefas) e um wrapper jQuery (para cenários personalizados). Ambas foram testadas em dezenas de projetos, funcionam corretamente em dispositivos móveis e não interferem com scripts vizinhos.

💡 Visão geral rápida:

  • Envolva o conteúdo numa <div> com as classes scroll-block e scroll-content
  • Defina max-height + overflow-y: auto no CSS, o bloco de scroll está pronto
  • Ligue o plugin jQuery do artigo para auto-scroll, animação e eventos
  • Estilize a barra de scroll via ::-webkit-scrollbar para combinar com o design do seu site

O que é um bloco de scroll e onde precisa realmente dele

Um bloco de scroll é um contentor com altura fixa cujo conteúdo faz scroll internamente, independente do scroll principal da página. O navegador adiciona uma barra de scroll automaticamente quando o conteúdo excede a altura definida.

Onde aplico esta solução constantemente:

  • Textos de SEO. O cliente quer uma parede de 3000 palavras no meio de uma landing page, eu envolvo-a num bloco de scroll, a página não se transforma numa tela infinita.
  • Comentários e registos. Tópicos de discussão longos ou registos de depuração no painel de administração, a altura fixa salva a interface de se espalhar.
  • Tabelas de dados. O scroll horizontal para tabelas é clássico, mas o scroll vertical numa tabela com mais de 50 linhas resolve o problema igualmente bem.
  • Widgets de chat e notificações. Uma janela de chat com histórico de mensagens, o mesmo bloco de scroll, apenas com auto-scroll para a última mensagem.

Tecnicamente, tudo se baseia em duas propriedades CSS: max-height (ou height) e overflow-y. Mas o diabo está nos detalhes: navegadores móveis, contentores aninhados, conflitos com position: fixed e peculiaridades do Safari no iOS exigem uma abordagem cuidadosa.

Veja este pequeno tutorial sobre a propriedade overflow, ele mostra claramente todos os modos de scroll e o seu comportamento:

Solução CSS: rápida e sem JavaScript

Para a grande maioria dos casos, não é necessário JavaScript. Bastam três linhas de CSS:

1.scroll-block {
2 max-height: 320px;
3 overflow-y: auto;
4 border: 1px solid #e0e0e0;
5 padding: 16px;
6}

Vamos por partes. max-height define o limite máximo, o bloco não crescerá mais do que 320px, mas pode ser mais baixo se houver menos conteúdo. overflow-y: auto diz ao navegador: «mostra a barra de scroll apenas quando o conteúdo transbordar o contentor.» A borda e o padding são opcionais, mas sem o padding o texto cola-se à barra de scroll e parece barato.

O HTML permanece semanticamente limpo:

1<div class="scroll-block">
2 <p>Your long SEO text, logs, table, or whatever.</p>
3</div>

Esta solução funciona de forma idêntica no Chrome, Firefox, Safari e Edge, a especificação overflow é estável desde o CSS2 e é suportada por todos os navegadores modernos. Em dispositivos móveis, o scroll dentro do bloco não entra em conflito com o scroll principal da página (ao contrário de soluções JavaScript engenhosas dos anos 2010 que capturavam touchmove e frequentemente quebravam o scroll).

Mas há uma nuance com o Safari no iOS: por padrão, o scroll dentro do bloco é «inelástico», não há o efeito nativo de ressalto. Se precisar de scroll inercial suave como o conteúdo principal, adicione:

1.scroll-block {
2 -webkit-overflow-scrolling: touch;
3}

A propriedade -webkit-overflow-scrolling: touch ativa o scroll nativo com inércia no iOS. Nota: com o iOS 13, a Apple tornou este o comportamento padrão para overflow: auto, portanto, para versões recentes, o prefixo é opcional. Mas se o projeto suportar iPads antigos, mantenha-o.

Solução jQuery: quando precisa de controlo total

O método CSS resolve a maioria das tarefas. Os restantes casos são quando precisa de scroll programático para o fundo (chat), eventos personalizados ao atingir os limites do bloco ou animação de scroll via botão. É aqui que entra o jQuery.

Aqui está um plugin pronto, mínimo, sem dependências exceto o próprio jQuery, testado em projetos com versões modernas de WordPress e que não entra em conflito com outros scripts do tema:

1(function($) {
2 $.fn.scrollBlock = function(options) {
3 var settings = $.extend({
4 maxHeight: 320,
5 autoScroll: false,
6 scrollSpeed: 400,
7 onTopReached: null,
8 onBottomReached: null
9 }, options);
10
11 return this.each(function() {
12 var $block = $(this);
13
14 $block.css({
15 'max-height': settings.maxHeight + 'px',
16 'overflow-y': 'auto'
17 });
18
19 if (settings.autoScroll) {
20 $block.animate({
21 scrollTop: $block[0].scrollHeight
22 }, settings.scrollSpeed);
23 }
24
25 $block.on('scroll', function() {
26 var scrollTop = $block.scrollTop();
27 var maxScroll = $block[0].scrollHeight - $block.outerHeight();
28
29 if (scrollTop <= 0 && settings.onTopReached) {
30 settings.onTopReached.call(this);
31 }
32 if (scrollTop >= maxScroll && settings.onBottomReached) {
33 settings.onBottomReached.call(this);
34 }
35 });
36 });
37 };
38})(jQuery);

Onde o lançar: no seu script (ficheiro JS separado do tema ou secção <script> no rodapé). Inclua depois do jQuery:

1$(document).ready(function() {
2 $('.scroll-content').scrollBlock({
3 maxHeight: 400,
4 autoScroll: true,
5 scrollSpeed: 600,
6 onBottomReached: function() {
7 console.log('Reached bottom of block');
8 }
9 });
10});

O que está a acontecer aqui: o plugin recebe um seletor, aplica um limite de altura CSS, opcionalmente faz scroll do bloco para o fundo e monitoriza o alcance dos limites superior/inferior via callbacks. Sem magia, apenas um wrapper sobre os métodos padrão do jQuery .css(), .animate() e o evento scroll.

Use esta solução quando: a) precisar de fazer auto-scroll do chat para a última mensagem, b) for necessária uma animação de scroll suave via botão externo «Para baixo»/«Para cima», c) precisar de anexar análises ao evento «utilizador leu até ao fim».

Vários blocos numa página

Cenário: três blocos de scroll com conteúdo diferente na página. Se definir uma classe .scroll-block sem identificadores únicos, tudo funciona, o CSS aplica-se a todos de uma vez. Mas assim que cada bloco precisar da sua própria altura, bem-vindo ao mundo dos IDs.

CSS para vários blocos com alturas diferentes:

1#seo-text-block {
2 max-height: 320px;
3 overflow-y: auto;
4}
5
6#changelog-block {
7 max-height: 480px;
8 overflow-y: auto;
9}
10
11#comments-block {
12 max-height: 600px;
13 overflow-y: auto;
14}

HTML:

1<div id="seo-text-block" class="scroll-block">
2 <!-- Long SEO text -->
3</div>
4
5<div id="changelog-block" class="scroll-block">
6 <!-- Changelog list -->
7</div>

Com o plugin jQuery, a mesma lógica: inicialize cada bloco separadamente com as suas próprias definições:

1$('#seo-text-block').scrollBlock({ maxHeight: 320 });
2$('#changelog-block').scrollBlock({ maxHeight: 480, autoScroll: true });
3$('#comments-block').scrollBlock({ maxHeight: 600, autoScroll: true, scrollSpeed: 300 });

Se houver muitos blocos (mais de 10) e todos idênticos, uma classe comum é suficiente. Se forem diferentes, IDs mais definições individuais. Sem magia com nth-child ou iteração manual, os seletores CSS tratam disto de raiz.

Estilizar a barra de scroll: para não parecer saída de 2007

A barra de scroll padrão do navegador é um retângulo cinzento da era do Windows XP. Dois minutos de CSS, e ela adapta-se ao seu design:

1.scroll-block::-webkit-scrollbar {
2 width: 6px;
3}
4
5.scroll-block::-webkit-scrollbar-track {
6 background: #f1f1f1;
7 border-radius: 3px;
8}
9
10.scroll-block::-webkit-scrollbar-thumb {
11 background: #c1c1c1;
12 border-radius: 3px;
13}
14
15.scroll-block::-webkit-scrollbar-thumb:hover {
16 background: #a1a1a1;
17}

Importante: os pseudo-elementos ::-webkit-scrollbar funcionam no Chrome, Edge, Safari e Opera, cobrindo a grande maioria dos utilizadores. O Firefox usa propriedades separadas scrollbar-width: thin e scrollbar-color, mas não é possível estilizar globalmente a barra de scroll no Firefox ao nível do elemento (apenas para toda a página). Para o Firefox, isto é suficiente:

1html {
2 scrollbar-width: thin;
3 scrollbar-color: #c1c1c1 #f1f1f1;
4}

Não exagere na largura da barra de scroll: 4 a 8px é o intervalo ideal. Mais fina do que 4px, os utilizadores não lhe acertam com o dedo no telemóvel. Mais grossa do que 8px, a barra de scroll começa a chamar demasiado a atenção.

⁉️🤔 Perguntas frequentes

O bloco de scroll funciona em dispositivos móveis?

Sim, e sem hacks. A propriedade CSS overflow-y: auto é suportada nativamente pelo Safari no iOS e Chrome para Android. O scroll interno do bloco não entra em conflito com o scroll principal da página, o navegador determina qual o contentor a percorrer com base na posição do dedo. Única nuance: em iOS antigo (antes do 13), adicione -webkit-overflow-scrolling: touch para scroll inercial.

Pode usar-se um bloco de scroll dentro de um contentor Flexbox ou Grid?

Pode. O bloco de scroll precisa de altura fixa, defina-a via max-height em pixéis ou via flex-basis/grid-row com um valor absoluto. Não use altura percentual dentro de um filho flex sem altura explícita no pai, o navegador não consegue calcular a base para o cálculo do overflow e o scroll não aparecerá.

Como fazer o scroll suave do bloco para o fundo sem jQuery?

Em JavaScript puro: element.scrollTo({ top: element.scrollHeight, behavior: 'smooth' }). O método scrollTo com a opção behavior: 'smooth' é suportado por todos os navegadores modernos. Para auto-scroll de chat, chame esta linha após adicionar cada nova mensagem.

O bloco de scroll entra em conflito com outros scripts na página?

A solução CSS, não. Estas são propriedades nativas do navegador, funcionam isoladamente. O plugin jQuery do artigo usa o seu próprio namespace $.fn.scrollBlock e não toca em variáveis globais, pelo que os conflitos estão excluídos. Testado em sites com mais de 20 plugins ativos, não surgiram problemas.

Pode animar-se a aparição de um bloco de scroll?

Sim. Adicione max-height: 0 e overflow: hidden no estado inicial, depois anime até à altura desejada. Quando a animação terminar, mude overflow para auto. Em jQuery, isto é feito via .animate({ 'max-height': '320px' }, 500, function() { $(this).css('overflow-y', 'auto') }). Em CSS puro, via transition: max-height 0.5s ease.

JQuery ou CSS: o que usar em 2026

A solução CSS cobre a grande maioria dos cenários e pesa zero kilobytes. Se precisa apenas de um bloco organizado com scroll interno, use-a e não complique.

O plugin jQuery justifica-se quando: está a construir um chat com auto-scroll, a anexar análises a eventos de scroll ou a animar o scroll via um botão externo. Noutros casos, o wrapper jQuery é uma solução excessiva que adiciona uma dependência de biblioteca para três linhas de CSS.

Experimente a variante CSS agora mesmo: copie três linhas de estilos, envolva o conteúdo de teste em <div class="scroll-block"> e abra a página no seu telemóvel. Verá resultados num minuto, sem npm install, sem bundlers, sem dores de cabeça.