Como posso deixar o corpo de uma mesa rolar, mas manter a cabeça fixa no lugar?


148

Estou escrevendo uma página na qual preciso de uma tabela HTML para manter um tamanho definido. Eu preciso que os cabeçalhos na parte superior da tabela permaneçam lá o tempo todo, mas também preciso que o corpo da tabela role, independentemente de quantas linhas sejam adicionadas à tabela. Pense em uma mini versão do excel. Parece uma tarefa simples, mas quase todas as soluções que encontrei na web têm algumas desvantagens. Como posso resolver isso?


2
existem muitos exemplos por aí. este é um deles .
Darren Kopp

Eu preciso direcionar IE6, IE7, FF, ... mas especialmente IE infelizmente
mentolado

Há muitos hacks CSS lá. Deve ser trivial começar a trabalhar no IE7.
Jim Jim

4
Estou interessado na resposta para todos os navegadores!
Minty

15
"Deve ser trivial trabalhar no IE7". Jim, é você? Você é meu gerente de projeto? :)
Aaronius 26/06

Respostas:


53

Eu tive que encontrar a mesma resposta. O melhor exemplo que encontrei é http://www.cssplay.co.uk/menu/tablescroll.html - achei que o exemplo nº 2 funcionou bem para mim. Você terá que definir a altura da tabela interna com Java Script, o resto é CSS.


3
infelizmente, esse método falha quando você tem uma tabela ampla (rolagem horizontal). Você terá duas barras de rolagem horizontais; um para o cabeçalho e outro para os dados.
vol7ron

4
sua solução não funciona se você não especificar <th> largura interna <thead>
Alexandru R

2
Para cumprir (relativamente) os novos padrões de estouro de pilha, você poderia editar esta resposta para incluir os bits relevantes do link?
Fund Monica's Lawsuit

Onde está a fonte, Billy?
candlejack

É impossível sincronizar as larguras das colunas entre o cabeçalho e o corpo da tabela (rolável) sem recorrer a JavaScript ou valores predefinidos.
Rustyx


12

Vi a excelente solução de Sean Haddy para uma pergunta semelhante e tomei a liberdade de fazer algumas edições :

  • Use classes em vez de ID, para que um script jQuery possa ser reutilizado para várias tabelas em uma página
  • Adicionado suporte para elementos de tabela HTML semântica, como legenda, cabeçalho, tfoot e tbody
  • Tornou a barra de rolagem opcional para que não apareça em tabelas "menores" que a altura rolável
  • Largura da div de rolagem ajustada para trazer a barra de rolagem até a borda direita da tabela
  • Tornou o conceito acessível por
    • usando aria-hidden = "true" no cabeçalho da tabela estática injetada
    • e deixando o cabeçote original no lugar, apenas oculto com jQuery e definido aria-hidden="false"
  • Exemplos mostrados de várias tabelas com tamanhos diferentes

Sean fez o trabalho pesado, no entanto. Agradecemos também a Matt Burland, por apontar a necessidade de apoiar o tfoot.

Veja por si mesmo em http://jsfiddle.net/jhfrench/eNP2N/


Bom, mas estraga tudo se você quiser um cabeçalho e rodapé!
Matt Burland

3
Obrigado Matt, eu fiz o ajuste.
Jeromy French

O alinhamento precisa ser ajustado se você mostrar as margens td e th.
dhochee

8

Você já tentou usar thead e tbody e definir uma altura fixa em tbody com estouro: scroll?

Quais são os seus navegadores de destino?

EDIT: Funcionou bem (quase) no firefox - a adição da barra de rolagem vertical causou a necessidade de uma barra de rolagem horizontal também - eca. O IE acabou de definir a altura de cada td para o que eu havia especificado como a altura de tbody. Aqui está o melhor que eu poderia encontrar:

<html>
    <head>
    <title>Blah</title>
    <style type="text/css">
    table { width:300px; }
    tbody { height:10em;  overflow:scroll;}
    td { height:auto; }
    </style>
    </head>
    <body>
    <table>
        <thead>
            <tr>
              <th>One</th><th>Two</th>
              </td>
            </tr>
        </thead>
        <tbody>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
        </tbody>
    </table>
    </body>
</html>

1
Eu preciso direcionar IE6, IE7, FF, ... mas especialmente IE infelizmente
mentolado

Alterar a tabela de modo que é menos do que 100% de largura, dizem 99% e vai deve cuidar do problema
WolfmanDragon

2
overflow-x: hidden;e overflow-y: autotambém ajuda.
Just 19/05

7
Isso costumava funcionar no firefox, e é o código óbvio e não complicado. No entanto, nas versões mais recentes do firefox, ele está quebrado.
Rasmus Kaj

6
Isso não funciona porque "overflow" é aplicável apenas a "block containers" ( w3.org/TR/CSS21/visufx.html#overflow ) e as caixas de tabela não são "block containers" ( w3.org/TR/CSS21/ visuren.html # caixas de bloco ).
mhsmith

8

O que você precisa é:

1) ter um corpo de tabela de altura limitada, pois a rolagem ocorre apenas quando o conteúdo é maior que a janela de rolagem. No entanto, tbodynão pode ser dimensionado, e você deve exibi-lo como block:

tbody {
   overflow-y: auto;
   display: block;
   max-height: 10em;    // For example
}

2) Ressincronize as larguras das colunas do cabeçalho da tabela e do corpo da tabela , tornando esta última um blockelemento não relacionado. A única maneira de fazer isso é simular a sincronização, aplicando a mesma largura de colunas a ambas .

No entanto, como tbodyele é um blockagora, ele não pode mais se comportar como um table. Como você ainda precisa de um tablecomportamento para exibir suas colunas corretamente, a solução é solicitar que cada uma de suas linhas seja exibida como tables individuais :

thead {         
   display: table;  
   width: 100%;     // Fill the containing table
}
tbody tr {
   display: table;
   width: 100%;     // Fill the containing table
}

(Observe que, usando esta técnica, você não poderá mais se estender por linhas).

Feito isso, você pode impor larguras de coluna para ter a mesma largura em ambos theade tbody. Você não poderia:

  • individualmente para cada coluna (por meio de classes CSS específicas ou estilo embutido), o que é bastante tedioso para cada instância da tabela;
  • uniformemente para todas as colunas (por exemplo, th, td { width: 20%; }se você tiver cinco colunas), o que é mais prático (não é necessário definir a largura para cada instância da tabela), mas não pode funcionar para nenhuma contagem de colunas
  • uniformemente para qualquer contagem de colunas, por meio de um layout de tabela fixo.

Eu prefiro a última opção, que requer adicionar:

thead {
   table-layout: fixed;   // Same layout for all cells
}
tbody tr {
   table-layout: fixed;   // Same layout for all cells
}
th, td {
   width: auto;   // Same width for all cells, if table has fixed layout
}    

Veja uma demonstração aqui , bifurcada da resposta a esta pergunta .


obrigada pelo esclarecimento. É enganador quantas maneiras algo pode ser feito e a maioria das respostas apenas apresenta algum código e um link plunkr, deixando você descobrir por si mesmo.
Paul Rooney

4

Edit:   Esta é uma resposta muito antiga e está aqui para a prosperidade, apenas para mostrar que foi suportada uma vez nos anos 2000, mas caiu porque a estratégia dos navegadores nos 2010 era respeitar as especificações do W3C, mesmo que alguns recursos fossem removidos: Tabela rolável com cabeçalho fixo / rodapé foi desajeitadamente especificado antes do HTML5.


Más notícias

Infelizmente, não há uma maneira elegante de lidar com a tabela rolável com especificações fixas thead/ tfoot porque HTML / CSS não são muito claras sobre esse recurso .

Explicações

Embora a especificação HTML 4.01 diga thead/ tfoot/ tbodyseja usada (introduzida?) Para rolar o corpo da tabela:

As linhas da tabela podem ser agrupadas [...] usando os elementos THEAD, TFOOT e TBODY [...]. Essa divisão permite que os agentes do usuário suportem a rolagem dos corpos da tabela independentemente da cabeça e do pé da tabela.

Mas o recurso de tabela de rolagem de trabalho no FF 3.6 foi removido no FF 3.7 porque considerado um bug por não ser compatível com as especificações HTML / CSS. Veja isto e aquilo comentários sobre erros de FF.

Dica da Mozilla Developer Network

Abaixo está uma versão simplificada das dicas úteis do MDN para tabela rolável.
Consulte esta página arquivada ou a versão atual em francês

<style type="text/css">
table {
  border-spacing: 0;              /* workaround */
}
tbody {
  height: 4em;                    /* define the height */
  overflow-x: hidden;             /* esthetics */
  overflow-y: auto;               /* allow scrolling cells */
}
td {
  border-left:   1px solid blue;  /* workaround */
  border-bottom: 1px solid blue;  /* workaround */
}
</style>

<table>
    <thead><tr><th>Header
    <tfoot><tr><th>Footer
    <tbody>
        <tr><td>Cell 1    <tr><td>Cell 2
        <tr><td>Cell 3    <tr><td>Cell 4
        <tr><td>Cell 5    <tr><td>Cell 6
        <tr><td>Cell 7    <tr><td>Cell 8
        <tr><td>Cell 9    <tr><td>Cell 10
        <tr><td>Cell 11   <tr><td>Cell 12
        <tr><td>Cell 13   <tr><td>Cell 14
    </tbody>
</table>

No entanto, a MDN também diz que isso não funciona mais no FF :-(
Também testei no IE8 => a tabela também não pode ser rolada: - ((


As dicas MDN para o link da tabela rolável não são informações relevantes sobre o colapso da borda. Talvez página foi alterações porque 5 anos se passaram
partizanos

Obrigado @partizanos Finalmente encontrei a página wiki original na história do MDN! Minha resposta velho parece agora obsoleto, mas para a prosperidade a próxima geração de desenvolvedores saberão que era possível e fácil de implementar para trás nos anos 2000 ;-) Felicidades
olibre

3

Não tenho certeza se alguém ainda está olhando para isso, mas do jeito que eu fiz isso anteriormente é usar duas tabelas para exibir a única tabela original - a primeira apenas a linha de título da tabela original e nenhuma linha de corpo da tabela (ou uma linha de corpo vazia para criar) validar).

O segundo está em uma div separada e não tem título e apenas as linhas do corpo da tabela original. A div separada é então tornada rolável.

A segunda tabela em sua div é colocada logo abaixo da primeira tabela no HTML e parece uma única tabela com um cabeçalho fixo e uma seção inferior rolável. Eu só testei isso no Safari, Firefox e IE (versões mais recentes de cada uma na primavera de 2010), mas funcionou em todas elas.

O único problema era que a primeira tabela não seria validada sem um corpo (validador W3.org - XHTML 1.0 estrito) e, quando adicionei uma sem conteúdo, ela causava uma linha em branco. Você pode usar CSS para tornar isso não visível, mas ele ainda ocupa espaço na página.


Como a linha extra ocuparia ainda espaço? Não é necessário ocupar espaço na tela se você usar display: none;, a menos que você queira dizer espaço na fonte ..?
precisa saber é o seguinte

3

Esta solução funciona no Chrome 35, Firefox 30 e IE 11 (não testou outras versões)

Seu CSS puro: http://jsfiddle.net/ffabreti/d4sope1u/

Tudo está definido para exibir: bloco, tabela precisa de uma altura:

    table {
        overflow: scroll;
        display: block;    /*inline-block*/
        height: 120px;
    }
    thead > tr  {
        position: absolute;
        display: block;
        padding: 0;
        margin: 0;
        top: 0;
        background-color: gray;
    }
    tbody > tr:nth-of-type(1) {
        margin-top: 16px;
    }
    tbody tr {
        display: block;
    }

    td, th {
        width: 70px;
        border-style:solid;
        border-width:1px;
        border-color:black;
    }

2

Isso me causou enormes dores de cabeça ao tentar implementar essa grade para uma aplicação nossa. Eu tentei todas as várias técnicas disponíveis, mas cada uma delas teve problemas. O mais próximo que cheguei foi o uso de um plugin jQuery como o Flexigrid (procure alternativas em http://www.ajaxrain.com ), mas isso não parece suportar tabelas 100% amplas, é o que eu precisava.

O que acabei fazendo foi rolar sozinho; O Firefox suporta tbodyelementos de rolagem , de modo que o navegador cheirou e utilizou o CSS apropriado (altura da configuração, estouro, etc ... pergunto se você deseja mais detalhes) para fazer essa rolagem; depois, para outros navegadores, usei duas tabelas separadas, table-layout: fixedque usam um tamanho. algoritmo garantido para não exceder o tamanho indicado (as tabelas normais serão expandidas quando o conteúdo for muito amplo para caber). Ao dar a ambas as tabelas larguras idênticas, consegui alinhar suas colunas. Enrolei o segundo em um conjunto de div para rolar e, com um pouco de brincadeira com margens, etc., consegui a aparência que eu queria.

Desculpe se esta resposta parece um pouco vaga em alguns lugares; Estou escrevendo rapidamente, pois não tenho muito tempo. Deixe um comentário se você quiser que eu expanda ainda mais!


Desculpe ressuscitar esse tópico antigo, mas eu realmente preciso saber como você resolveu isso. Eu tenho o FF funcionando, mas não os navegadores IE / WebKit. Por favor, ajude quando puder.
Alfero Chingono

2

Aqui está um código que realmente funciona para IE e FF (pelo menos):

<html>
<head>
    <title>Test</title>
    <style type="text/css">
        table{
            width: 400px;
        }
        tbody {
            height: 100px;
            overflow: scroll;
        }
        div {
            height: 100px;
            width: 400px;
            position: relative;
        }
        tr.alt td {
            background-color: #EEEEEE;
        }
    </style>
    <!--[if IE]>
        <style type="text/css">
            div {
                overflow-y: scroll;
                overflow-x: hidden;
            }
            thead tr {
                position: absolute;
                top: expression(this.offsetParent.scrollTop);
            }
            tbody {
                height: auto;
            }
        </style>
    <![endif]--> 
</head>
<body>
    <div >
        <table border="0" cellspacing="0" cellpadding="0">
            <thead>
                <tr>
                    <th style="background: lightgreen;">user</th>
                    <th style="background: lightgreen;">email</th>
                    <th style="background: lightgreen;">id</th>
                    <th style="background: lightgreen;">Y/N</th>
                </tr>
            </thead>
            <tbody align="center">
                <!--[if IE]>
                    <tr>
                        <td colspan="4">on IE it's overridden by the header</td>
                    </tr>
                <![endif]--> 
                <tr>
                    <td>user 1</td>
                    <td>user@user.com</td>
                    <td>1</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 2</td>
                    <td>user@user.com</td>
                    <td>2</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 3</td>
                    <td>user@user.com</td>
                    <td>3</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 4</td>
                    <td>user@user.com</td>
                    <td>4</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 5</td>
                    <td>user@user.com</td>
                    <td>5</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 6</td>
                    <td>user@user.com</td>
                    <td>6</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 7</td>
                    <td>user@user.com</td>
                    <td>7</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 8</td>
                    <td>user@user.com</td>
                    <td>8</td>
                    <td>N</td>
                </tr>
            </tbody>
        </table>
    </div>
</body></html>

Alterei o código original para torná-lo mais claro e também para colocá-lo funcionando bem no IE e também no FF.

Código original AQUI


1
No IE7 / 8 isso só funciona no modo Quirks, e ele pára de funcionar assim que você adicionar um doctype, ou seja<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
ccpizza

1

Aqui está a minha alternativa. Ele também usa DIVs diferentes para o cabeçalho, corpo e rodapé, mas sincronizados para redimensionar janelas e com pesquisa, rolagem, classificação, filtragem e posicionamento:

Minhas listas de CDs

Clique nos botões Jazz, Clássica ... para ver as tabelas. Ele é configurado para ser adequado mesmo se o JavaScript estiver desativado.

Parece OK no IE, FF e WebKit (Chrome, Safari).


1

Desculpe, eu não tenho lido todas as respostas à sua pergunta.

Sim, aqui a coisa que você quer (eu já fiz)

Você pode usar duas tabelas, com o mesmo nome de classe para estilos semelhantes, uma apenas com cabeçalho da tabela e outra com suas linhas. Agora coloque esta tabela dentro de uma div com altura fixa com overflow-y: auto OR scroll.


1

O principal problema que tive com as sugestões acima foi ser capaz de conectar o tablesorter.js E poder flutuar os cabeçalhos de uma tabela restrita a um tamanho máximo específico. Acabei encontrando o plugin jQuery.floatThead, que fornecia os cabeçalhos flutuantes e permitia que a classificação continuasse funcionando.

Ele também possui uma boa página de comparação mostrando plugins semelhantes a outros .


1

Live JsFiddle

É possível apenas com HTML e CSS

table.scrollTable {
  border: 1px solid #963;
  width: 718px;
}

thead.fixedHeader {
  display: block;
}

thead.fixedHeader tr {
  height: 30px;
  background: #c96;
}

thead.fixedHeader tr th {
  border-right: 1px solid black;
}

tbody.scrollContent {
  display: block;
  height: 262px;
  overflow: auto;
}

tbody.scrollContent td {
  background: #eee;
  border-right: 1px solid black;
  height: 25px;
}

tbody.scrollContent tr.alternateRow td {
  background: #fff;
}

thead.fixedHeader th {
  width: 233px;
}

thead.fixedHeader th:last-child {
  width: 251px;
}

tbody.scrollContent td {
  width: 233px;
}
<table cellspacing="0" cellpadding="0" class="scrollTable">
  <thead class="fixedHeader">
    <tr class="alternateRow">
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
    </tr>
  </thead>
  <tbody class="scrollContent">
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>End of Cell Content 1</td>
      <td>End of Cell Content 2</td>
      <td>End of Cell Content 3</td>
    </tr>
  </tbody>
</table>


0

Se está tudo bem em usar JavaScript, aqui está minha solução. Crie uma tabela com largura fixa em todas as colunas (pixels!) Adicione a classe Scrollify à tabela e adicione esta altura do conjunto javascript + jquery 1.4.x em css ou estilo!

Testado em: Opera, Chrome, Safari, FF, IE5.5 ( falha de script épica ), IE6, IE7, IE8, IE9

//Usage add Scrollify class to a table where all columns (header and body) have a fixed pixel width
$(document).ready(function () {
    $("table.Scrollify").each(function (index, element) {
        var header = $(element).children().children().first();
        var headerHtml = header.html();
        var width = $(element).outerWidth();
        var height = parseInt($(element).css("height")) - header.outerHeight();
        $(element).height("auto");
        header.remove();
        var html = "<table style=\"border-collapse: collapse;\" border=\"1\" rules=\"all\" cellspacing=\"0\"><tr>" + headerHtml +
                         "</tr></table><div style=\"overflow: auto;border:0;margin:0;padding:0;height:" + height + "px;width:" + (parseInt(width) + scrollbarWidth()) + "px;\">" +
                         $(element).parent().html() + "</div>";

        $(element).parent().html(html);
    });
});


//Function source: http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels
//License: Apache License, version 2
function scrollbarWidth() {
    var scr = null;
    var inn = null;
    var wNoScroll = 0;
    var wScroll = 0;

    // Outer scrolling div
    scr = document.createElement('div');
    scr.style.position = 'absolute';
    scr.style.top = '-1000px';
    scr.style.left = '-1000px';
    scr.style.width = '100px';
    scr.style.height = '50px';
    // Start with no scrollbar
    scr.style.overflow = 'hidden';

    // Inner content div
    inn = document.createElement('div');
    inn.style.width = '100%';
    inn.style.height = '200px';

    // Put the inner div in the scrolling div
    scr.appendChild(inn);
    // Append the scrolling div to the doc
    document.body.appendChild(scr);

    // Width of the inner div sans scrollbar
    wNoScroll = inn.offsetWidth;
    // Add the scrollbar
    scr.style.overflow = 'auto';
    // Width of the inner div width scrollbar
    wScroll = inn.offsetWidth;

    // Remove the scrolling div from the doc
    document.body.removeChild(
        document.body.lastChild);

    // Pixel width of the scroller
    return (wNoScroll - wScroll);
}

Editar: altura fixa.


0

Faço isso com javascript (sem biblioteca) e CSS - o corpo da tabela rola com a página e a tabela não precisa ter largura ou altura fixa, embora cada coluna deva ter uma largura. Você também pode manter a funcionalidade de classificação.

Basicamente:

  1. Em HTML, crie divs de contêiner para posicionar a linha do cabeçalho da tabela e o corpo da tabela, também crie uma div "mask" para ocultar o corpo da tabela à medida que ela passa pelo cabeçalho

  2. Em CSS, converta as partes da tabela em blocos

  3. Em Javascript, obtenha a largura da tabela e corresponda à largura da máscara ... obtenha a altura do conteúdo da página ... meça a posição de rolagem ... manipule CSS para definir a posição da linha do cabeçalho da tabela e a altura da máscara

Aqui está o javascript e uma DEMO jsFiddle.

// get table width and match the mask width

function setMaskWidth() { 
  if (document.getElementById('mask') !==null) {
    var tableWidth = document.getElementById('theTable').offsetWidth;

    // match elements to the table width
    document.getElementById('mask').style.width = tableWidth + "px";
   }
}

function fixTop() {

  // get height of page content 
  function getScrollY() {
      var y = 0;
      if( typeof ( window.pageYOffset ) == 'number' ) {
        y = window.pageYOffset;
      } else if ( document.body && ( document.body.scrollTop) ) {
        y = document.body.scrollTop;
      } else if ( document.documentElement && ( document.documentElement.scrollTop) ) {
        y = document.documentElement.scrollTop;
      }
      return [y];
  }  

  var y = getScrollY();
  var y = y[0];

  if (document.getElementById('mask') !==null) {
      document.getElementById('mask').style.height = y + "px" ;

      if (document.all && document.querySelector && !document.addEventListener) {
        document.styleSheets[1].rules[0].style.top = y + "px" ;
      } else {
        document.styleSheets[1].cssRules[0].style.top = y + "px" ;
      }
  }

}

window.onscroll = function() {
  setMaskWidth();
  fixTop();
}

Mas na sua demonstração, o cabeçalho da tabela não fica parado, apenas desloca para longe. (Chrome aqui.)
Sz.

Não estou vendo isso no Chrome. Tem certeza de que não está confundindo as células destacadas em amarelo com instruções em vermelho para o cabeçalho? As células do cabeçalho estão na parte superior e são cinza sobre cinza ("Col 1", "Col 2" etc.).
Deborah

0

Para mim, nada relacionado à rolagem realmente funcionou até remover a largura da tabela CSS. Originalmente, a tabela CSS era assim:

.table-fill {
    background: white;
    border-radius:3px;
    border-collapse: collapse;
    margin: auto;
    width: 100%;
    max-width: 800px;
    padding:5px;
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
    animation: float 5s infinite;
}

Assim que eu removi a largura: 100%; todos os recursos de rolagem começaram a funcionar.


0

Se você tiver padrões suficientemente baixos;), poderá colocar uma tabela que contenha apenas um cabeçalho diretamente acima de uma tabela que possua apenas um corpo. Não rolará horizontalmente, mas se você não precisar disso ...

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.