Recentemente, tive um problema semelhante e acabei corrigindo-o usando uma mistura de soluções diferentes.
A primeira e mais simples foi usar duas tabelas, uma para os cabeçalhos e outra para o corpo. Isso funciona, mas os cabeçalhos e as colunas do corpo não estão alinhados. E, como eu queria usar o tamanho automático que acompanha as tabelas de inicialização do twitter, acabei criando uma função Javascript que altera os cabeçalhos quando: o corpo é renderizado; as janelas são redimensionadas; os dados na coluna são alterados etc.
Aqui está um pouco do código que eu usei:
<table class="table table-striped table-hover" style="margin-bottom: 0px;">
<thead>
<tr>
<th data-sort="id">Header 1</i></th>
<th data-sort="guide">Header 2</th>
<th data-sort="origin">Header 3</th>
<th data-sort="supplier">Header 4</th>
</tr>
</thead>
</table>
<div class="bodycontainer scrollable">
<table class="table table-hover table-striped table-scrollable">
<tbody id="rows"></tbody>
</table>
</div>
Os cabeçalhos e o corpo são divididos em duas tabelas separadas. Um deles está dentro de um DIV com o estilo necessário para gerar as barras de rolagem verticais. Aqui está o CSS que eu usei:
.bodycontainer {
//height: 200px
width: 100%;
margin: 0;
}
.table-scrollable {
margin: 0px;
padding: 0px;
}
Comentei a altura aqui porque queria que a tabela chegasse ao final da página, qualquer que seja a altura da página.
Os atributos de classificação de dados que usei nos cabeçalhos também são usados em todos os td. Dessa forma, eu poderia obter a largura e o preenchimento de cada td e a largura da linha. Usando os atributos de ordenação de dados, defino usando CSS o preenchimento e a largura de cada cabeçalho de acordo e da linha do cabeçalho, que é sempre maior, pois não possui uma barra de rolagem. Aqui está a função usando coffeescript:
fixHeaders: =>
for header, i in @headers
tdpadding = parseInt(@$("td[data-sort=#{header}]").css('padding'))
tdwidth = parseInt(@$("td[data-sort=#{header}]").css('width'))
@$("th[data-sort=#{header}]").css('padding', tdpadding)
@$("th[data-sort=#{header}]").css('width', tdwidth)
if (i+1) == @headers.length
trwidth = @$("td[data-sort=#{header}]").parent().css('width')
@$("th[data-sort=#{header}]").parent().parent().parent().css('width', trwidth)
@$('.bodycontainer').css('height', window.innerHeight - ($('html').outerHeight() -@$('.bodycontainer').outerHeight() ) ) unless @collection.length == 0
Aqui, presumo que você tenha uma matriz de cabeçalhos chamada @headers.
Não é bonito, mas funciona. Espero que ajude alguém.