Tabela de rolagem de inicialização do Twitter

149

Eu gostaria de ter uma mesa no meu site. O problema é que esta tabela terá cerca de 400 linhas. Como posso limitar a altura da tabela e aplicar a barra de rolagem? Este é o meu código:

<div class="span3">
  <h2>Achievements left</h2>
<table class="table table-striped">
  <thead>
    <tr>
      <th>#</th>
      <th>Name</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>2</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>3</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>4</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>5</td>
      <td>Something</td>
    </tr>
    <tr>
      <td>6</td>
      <td>Something</td>
    </tr>
  </tbody>
</table>

  <p><a class="btn" href="#">View details &raquo;</a></p>
</div>

Tentei aplicar a altura máxima e a altura fixa à mesa, mas não funciona.

pangi
fonte

Respostas:

241

Os elementos da tabela não parecem suportar isso diretamente. Coloque a tabela em uma div e defina a altura da div e defina overflow: auto.

Jonathan Wood
fonte
50
Isso realmente funcionou? Eu tentei isso e não teve nenhum efeito.
Cjstehno
8
Apenas o FYI, configurando o estouro para 'automático', em vez do estouro: rolagem, não criará uma barra de rolagem horizontal redundante.
DaCoda
8
@ JonathanWood: existe uma maneira de aplicar overflowapenas no corpo da tabela, mas onde as <thead>peças são sempre exibidas?
Willem Van Onsem
8
Só para deixar isso claro para as pessoas .... <div style = "overflow: auto;"> <table class = "table"> .... </ table> </ div>
Henry Weber
3
Por favor, dê um pequeno exemplo!
Yahya Yahyaoui 27/03
53
.span3 {  
    height: 100px !important;
    overflow: scroll;
}​

Você deseja envolvê-lo em sua própria div ou atribuir a esse span3 um ID próprio para não afetar todo o layout.

Aqui está um violino: http://jsfiddle.net/zm6rf/

Acordes
fonte
2
Observe que o '! Important' não é importante;)
Acordes
8
Cuidado, a configuração dessas propriedades .span3afetará todos os span3 elementos em todo o site controlado por Bootstrap.
Terry
1
Você só pode adicionar uma porcentagem de altura se o contêiner pai tiver uma altura de pixel. No seu caso, você precisa fazer algo como definir .row para 500px e .span3 para 50%. Se o pai não tiver uma altura definida, o navegador usará como padrão a altura do conteúdo, se você especificar uma porcentagem.
Acordes
1
Você pode fazer isso enquanto deixa o corpo patinável e o cabeçote não?
Streetlight
1
Para sua informação, configurar overflow: scroll criará uma barra de rolagem horizontal que pode ser redundante. Tornar automático, ou seja, overflow: auto, não faz isso.
DaCoda 12/07
38

Não precisa embrulhá-lo em uma div ...

CSS :

tr {
width: 100%;
display: inline-table;
table-layout: fixed;
}

table{
 height:300px;              // <-- Select the height of the table
 display: -moz-groupbox;    // Firefox Bad Effect
}
tbody{
  overflow-y: scroll;      
  height: 200px;            //  <-- Select the height of the body
  width: 100%;
  position: absolute;
}

Bootply : http://www.bootply.com/AgI8LpDugl

BENARD Patrick
fonte
Fiquei muito empolgado quando vi esse exemplo, mas o layout fica "cheio de graça" quando os dados no tdelemento variam em tamanho. bootply.com/OsvzINuTUA
Frito
4
@Frito Não se preocupe, seja feliz;) Acabei de me esquecer do layout da tabela: fixo; ... Link atualizado
BENARD Patrick
30

Eu tive o mesmo problema e usei uma combinação das soluções acima (e adicionei um toque pessoal). Observe que eu tive que especificar as larguras das colunas para mantê-las consistentes entre o cabeçalho e o corpo.

Na minha solução, o cabeçalho e o rodapé permanecem fixos enquanto o corpo rola.

<div class="table-responsive">
    <table class="table table-striped table-hover table-condensed">
        <thead>
            <tr>
                <th width="25%">First Name</th>
                <th width="13%">Last Name</th>
                <th width="25%" class="text-center">Address</th>
                <th width="25%" class="text-center">City</th>
                <th width="4%" class="text-center">State</th>
                <th width="8%" class="text-center">Zip</th>
            </tr>
        </thead>
    </table>
    <div class="bodycontainer scrollable">
        <table class="table table-hover table-striped table-condensed table-scrollable">
            <tbody>
                <!-- add rows here, specifying same widths as in header, at least on one row -->
            </tbody>
        </table>
    </div>
    <table class="table table-hover table-striped table-condensed">
        <tfoot>
            <!-- add your footer here... -->
        </tfoot>
    </table>
</div>

E então apenas apliquei o seguinte CSS:

.bodycontainer { max-height: 450px; width: 100%; margin: 0; overflow-y: auto; }
.table-scrollable { margin: 0; padding: 0; }

Espero que isto ajude alguém.

Todd
fonte
Graças ajuda. Infelizmente, não posso especificar a largura dos elementos, uma vez que não é um elemento válido. (???)
Erwin Rooijakkers
1
colunas do td não estão alinhados com os elementos th porque a barra de rolagem muda o conteúdo
IHeartAndroid
Ahh ... Estou em um Mac em que as barras de rolagem são invisíveis e aparecem na parte superior do conteúdo apenas durante a rolagem. Isso será difícil, pois as barras de rolagem dependem do sistema operacional e do navegador.
Todd
9

Recentemente, tive que fazer isso com o bootstrap e o angularjs, criei uma diretiva angularjs que resolve o problema. Você pode ver um exemplo de trabalho e detalhes nesta postagem do blog .

Você o usa apenas adicionando um atributo de cabeçalho fixo à tag da tabela:

<table class="table table-bordered" fixed-header>
...
</table>

Se você não estiver usando o angularjs, poderá ajustar o javascript da diretiva e usá-lo diretamente.

Jason
fonte
8

CSS

.achievements-wrapper { height: 300px; overflow: auto; }

HTML

<div class="span3 achievements-wrapper">
    <h2>Achievements left</h2>
    <table class="table table-striped">
    ...
    </table>
</div>
Terry
fonte
É possível manter a altura relativa?
Pangi
Eu quero ter a altura definida com porcentagens. Isso é possível? Não consegui fazê-lo funcionar.
Pangi
Claro, basta definir a altura da tabela para 100%. .table-class-name { height: 100%; }.
Terry
Isso amplia minha mesa e continua. (Não tem nenhum efeito)
Pangi
4
Por esse método, o cabeçalho também pode ser rolado, então existe uma maneira de corrigir o cabeçalho da tabela?
Kyleinincubator
4

Esta pode não ser uma solução para uma grande contagem de linhas. Eu simplesmente uso o truque da tabela de duplicação para fazer a coisa para a tabela de contagem de linhas pequena, enquanto ela pode manter a largura da coluna flexível, você pode tentar esse violino .

(A coluna de largura fixa é o método que eu uso para a tabela de contagem de linhas grandes que requer apenas a duplicação da linha de cabeçalho)

Código de amostra:

<div style="height:30px;overflow:hidden;margin-right:15px;">
   <table class="table">
       <thead>
           <tr>
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Cel 1,1</td>
                <td>Cel 1,2</td>
                <td>Cel 1,3</td>
            </tr>
            <tr>
                <td>Cel 2,1</td>
                <td>Cel 2,2</td>
                <td>Cel 2,3</td>
            </tr>
            <tr>
                <td>Cel 3,1</td>
                <td>Cel 3,2</td>
                <td>Cel 3,3</td>
            </tr>


        </tbody>
    </table>
</div>
<div style="height:100px;overflow-y:scroll;;">
    <table class="table">
        <thead>

        </thead>
        <tbody>
            <tr>
                <td>Cel 1,1</td>
                <td>Cel 1,2</td>
                <td>Cel 1,3</td>
            </tr>
            <tr>
                <td>Cel 2,1</td>
                <td>Cel 2,2</td>
                <td>Cel 2,3</td>
            </tr>
            <tr>
                <td>Cel 3,1</td>
                <td>Cel 3,2</td>
                <td>Cel 3,3</td>
            </tr>
             <tr style="color:white">
                <th>Col 1</th>
                <th>Col 2</th>
                <th>Col 3</th>
            </tr>
        </tbody>
    </table>
</div>
Chukiat
fonte
4

Coloque a tabela em uma div e dê a essa div a classe pre-scrollable.

Reza Saadati
fonte
3

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.

Guzmonne
fonte
3

Todas as soluções acima também rolam o cabeçalho da tabela ... Se você deseja rolar apenas para o corpo, aplique o seguinte:

tbody {
    height: 100px !important;
    overflow: scroll;
    display:block;
}
solo999
fonte
7
Isso só funcionará se for uma tabela de coluna única. Se você tiver uma tabela com várias colunas, isso fará apenas a primeira coluna rolar.
5602
2

Nenhuma dessas respostas funcionou satisfatoriamente para mim. Eles não consertaram a linha de cabeçalho da tabela ou exigiram larguras de colunas fixas para funcionar e, mesmo assim, tendiam a ter a linha de cabeçalho e as linhas do corpo desalinhadas em vários navegadores.

Eu recomendo morder a bala e usar um controle de grade apropriado como jsGrid ou meu favorito pessoal, SlickGrid . Obviamente, isso introduz uma dependência, mas se você deseja que suas tabelas se comportem como grades reais com suporte a vários navegadores, isso poupará você a arrancar os cabelos. Também oferece a opção de classificar e redimensionar colunas, além de vários outros recursos, se você desejar.

Simon Brangwin
fonte
2

Re sugestão de Jonathan Wood. Não tenho a opção de quebrar tabelas com uma nova div, pois estou usando um CMS. Usando JQuery aqui está o que eu fiz:

$( "table" ).wrap( "<div class='table-overflow'></div>" );

Isso agrupa os elementos da tabela com uma nova div com a classe "estouro de tabela".

Você pode simplesmente adicionar a seguinte definição no seu arquivo css:

.table-overflow { overflow: auto; }     
Scott
fonte
2

coloque a tabela dentro da div para fazer a tabela rolável verticalmente. mude overflow-ypara overflow-xpara tornar a tabela rolável horizontalmente. apenas overflowpara tornar a tabela rolável na horizontal e na vertical.

<div style="overflow-y: scroll;"> 
    <table>
    ...
    </table>
</div>
Iqbal Pratomo Santoso
fonte
1

Imaginei que iria postar aqui, já que não consegui fazer com que nenhum dos itens acima funcione com o Bootstrap 4. Encontrei isso online e funcionou perfeitamente para mim ...

table
{
    width: 100%;
    display: block;
    border:solid black 1px;
}

thead
{
    display: inline-block;
    width: 100%;
    height: 20px;
}

tbody
{
    height: 200px;
    display: inline-block;
    width: 100%;
    overflow: auto;
}

th, td
{
    width: 100px;
    border:solid 1px black;
    text-align:center;
}

Também anexei o jsfindle em funcionamento.

https://jsfiddle.net/jgngg28t/

Espero que isso ajude mais alguém.

BV2005
fonte