4 pontos por GN⁺ 2024-02-25 | 1 comentários | Compartilhar no WhatsApp
  • Em tabelas com muitas linhas, quanto mais se rola a página, mais fácil é esquecer o significado das colunas, o que dificulta a leitura dos dados
  • Basta adicionar position: sticky; e top: 0; ao thead para implementar um cabeçalho fixo
  • sticky tem cerca de 96% de suporte nos navegadores no mundo todo, então está longe de ser um recurso experimental
  • Mesmo ao visualizar linhas mais abaixo, como o item 300, os títulos das colunas continuam visíveis, melhorando a experiência de navegação pela tabela
  • A implementação é pequena, mas o efeito é grande; por isso, em páginas com tabelas longas, vale aplicá-la como uma melhoria básica de usabilidade

O problema de o cabeçalho desaparecer em tabelas longas

  • Em tabelas com grandes conjuntos de dados ou centenas de linhas, após rolar a página o cabeçalho da tabela sai da área visível
  • Ao descer até o item 300, pode ficar difícil conferir novamente o que os dados de cada coluna significam
  • Quanto mais desconhecida for a tabela, maior o esforço de navegação, já que é preciso lembrar o significado das colunas durante a leitura

Aplicando sticky ao thead

  • A solução é adicionar duas propriedades CSS ao thead
position: sticky;
top: 0;
  • Ao usar position: sticky junto com top: 0, é possível fixar o cabeçalho no topo da tela mesmo durante a rolagem
  • sticky conta com cerca de 96% de suporte global, então pode ser usado em muitos navegadores
  • Você pode verificar o funcionamento real no exemplo no CodePen

1 comentários

 
GN⁺ 2024-02-25
Opiniões no Hacker News
  • Um cabeçalho fixo em um eixo eu até aceito, mas ainda estou esperando o dia em que o CSS dará suporte a isso nos dois eixos: https://github.com/w3c/csswg-drafts/issues/8286

    • Um trabalho contratado em que eu precisava fixar tanto as colunas quanto o cabeçalho foi uma das coisas mais difíceis que já fiz Com uma tabela padrão seria fácil, mas era uma tabela dinâmica de terceiros em VueJS complexa, usando CSS-as-JS gerado, então demorei só para descobrir de onde vinham o CSS e o JS; no fim, tive que sobrescrever funções de classe em JS e o CSS gerado Fiquei mal com o cliente pelo tempo que levou, e passei a ter muito mais cuidado ao escolher bibliotecas em codebases Vue/React. Tabelas são elementos básicos do HTML; não entendo por que uma tarefa simples precisa de três camadas de classes JS e CSS importado como JSON
    • Provavelmente venho acompanhando há 8 anos a issue original que deu origem a essa, e é uma das partes mais irritantes da especificação CSS Às vezes você precisa de uma tabela de dados enorme e quer manter o topo fixo enquanto também usa overflow-x: auto, mas fazem você escolher só um dos dois
  • Confesso que, mesmo sabendo pouquíssimo CSS, consigo fazer web apps que funcionam razoavelmente. Recentemente tentei fixar o cabeçalho em uma tabela monstruosa de cerca de 20 mil linhas: https://www.datasciencemeta.com/rpackages No começo, esperava que as classes de tabela do Bootstrap tivessem algo como class="table table-header-sticky", mas não tinham; depois de uns 20 minutos mexendo em sugestões do Stack Overflow, GPT e CodePen, sempre surgiam efeitos colaterais estranhos Mas com o CodePen deste artigo funcionou em 2 minutos, e estou colocando isso em produção agora

  • Fixar cabeçalhos de tabela parece fácil com um simples position: sticky;, mas assim que você começa a acrescentar coisas ao conteúdo da tabela, fica complicado Em uma tabela com cabeçalho fixo, implementei um recurso que salvava o índice da primeira linha visível quando o usuário rolava o corpo e saía da página, para restaurá-lo ao voltar; mas ele sempre restaurava cerca de uma linha abaixo. No fim, a linha 5 estava de fato no topo da tabela, só que o thead ficava sobreposto e fazia a linha 6 parecer a primeira Então ajustei a posição de rolagem levando em conta a altura do thead, mas às vezes ainda ficava alguns pixels desalinhado; como a tabela era grande, fazia lazy loading no evento de rolagem e usava o layout automático padrão de tabelas, as células do cabeçalho quebravam linha e a altura total do cabeçalho mudava. No fim, anexei um ResizeObserver ao thead para ajustar dinamicamente a posição de rolagem quando a altura mudava [1] https://developer.mozilla.org/en-US/docs/Web/API/ResizeObser...

  • Ao implementar isso, se você também quiser que a borda do cabeçalho fique fixa, dá para resolver colocando position: absolute, width: 100%, top: 0/bottom: 0 e border-top/border-bottom em table thead:before e table thead:after

  • Seria bom se cabeçalhos de tabela se comportassem assim automaticamente. Se o desenvolvedor já se deu ao trabalho de usar as tags relacionadas, normalmente é provável que esse seja o comportamento desejado

    • Basta instalar um plugin de navegador que consiga carregar folhas de estilo personalizadas em todas as páginas Só que hoje há cada vez mais sites que fazem tabelas com 500 em vez de e, dentro de cada , 45 níveis de aninhados; nesses lugares, acho que não funcionaria
    • Esse tipo de mudança parece ter grande chance de quebrar algo de maneiras inesperadas O principal motivo deve ser que, antes do CSS Grid, muitos sites usavam tabelas para layouts em grade. Se o cabeçalho ficar fixo, esses layouts podem quebrar A grande falha da semântica do HTML foi a tabela passar a ser entendida não como “uma forma de exibir dados tabulares”, mas como “uma grade arbitrária de elementos”
  • Na linha de comando, basta mandar o cabeçalho para stderr e o corpo para stdout Se você não fizer isso, o resultado de heights | sort -k2 -nr fica na ordem George 186, Wally 173, NAME HEIGHT; mas, se o cabeçalho contornar stdout, a ordem fica NAME HEIGHT, George 186, Wally 173

    • heights | (sed -u 1q; sort -k2 -nr) funciona corretamente Fonte: https://stackoverflow.com/a/56151840
    • Se for escrever em um arquivo, é preciso tentar mais algumas coisas e ter mais entendimento de shell Essa é uma limitação contínua dos modelos exclusivamente textuais in-band, mas acho que abusar do STDERR dessa forma mais confunde do que ajuda Se heights for um arquivo, dá para fazer % head -1 heights ; sed 1,1d heights | sort -k2 -nr; se heights for um executável caro de rodar duas vezes, dá para fazer % heights > /tmp/heights ; head -1 /tmp/heights ; sed 1,1d /tmp/heights | sort -k2 -nr. Também dá para passar por um pipe para awk As outras opções são menos convenientes, mas menos surpreendentes, e funcionam mesmo que o autor do executável tenha pensado de outro jeito
    • O que seria melhor aqui? Mandar o cabeçalho para stderr, ou imprimir o cabeçalho apenas quando stdout for um TTY?
  • Isso não funcionou por muito tempo. Antigamente, o Chrome desativava position: sticky nos elementos thead e tr: https://issues.chromium.org/issues/41303743 Lembro que a tabela de suporte dos navegadores parecia quase toda verde, mas justamente nas tabelas do Chrome não funcionava

    • É surpreendente que agora tenha ficado tão simples. Quando precisei disso antes, era necessário enfiar todo tipo de gambiarra em HTML e CSS para funcionar em todos os navegadores Ainda assim, não era tão surpreendente, porque desenvolvimento web costuma ser assim mesmo
  • Também há quem prefira dizer “por favor, não faça isso”: https://news.ycombinator.com/item?id=32998091

    • Para uma página web comum, concordo totalmente. Muitas vezes removo elementos fixos com o uBlock Origin porque é mais rápido do que escrever um estilo no Stylus, e estilos genéricos aplicados ao site todo também funcionaram bem Mas o texto original fala de tabelas de dados com colunas de cabeçalho fixas, então essa sugestão é, na prática, bem útil
    • Aquilo é sobre cabeçalhos fixos da página inteira. Em tabelas é completamente diferente Odeio quando estou olhando uma tabela com umas doze colunas de números e, ao rolar um pouco para baixo, já não dá para saber o que é o quê
    • O que há de ruim na propriedade sticky?
  • O CodePen fica melhor se você compensar o top pela espessura da borda. Por exemplo, usar -1px em vez de 0 evita que o corpo da tabela apareça por cima do cabeçalho Comparação: https://codepen.io/bradleytaunt/pen/bGZyJBj Versão corrigida: https://codepen.io/alokmenghrajani/pen/ExMBQow

  • Sugiro usar uma altura de viewport limitada em vez de um cabeçalho fixo, para que o cabeçalho esteja sempre visível Algo como o DataGridXL(https://datagridxl.com). Aliás, fui eu que criei

    • Só uma ideia que me ocorreu: esse método é muito difícil de navegar sem um dispositivo apontador, por exemplo usando apenas o teclado
    • Não estou querendo criticar, mas em dispositivos móveis nunca gostei desse tipo de abordagem. Acho que o conteúdo deve rolar junto com a página