Marca de rolagem TBODY em navegadores Webkit
Pergunta
Eu estou ciente de esta questão , mas nenhuma das respostas trabalho no Safari, Chrome, etc.
A estratégia aceita ( como demonstrado aqui ) é para definir as propriedades de altura tbody e transbordamento assim:
<table>
<thead>
<tr><th>This is the header and doesn't scroll</th></tr>
</thead>
<tbody style="height:100px; overflow:auto;">
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
</tbody>
</table>
Infelizmente, isso não funciona em qualquer navegador WebKit. Há um bug relatório sobre isso que não parece ser uma alta prioridade (relatado 05 de junho).
Então, minha pergunta é: existem estratégias alternativas que fazem realmente o trabalho? Eu tentei a abordagem de dois mesa, mas é impossível garantir que o cabeçalho vai alinhar com o conteúdo. Eu só tenho que esperar para Webkit para corrigi-lo?
Solução
Aqui está um exemplo de trabalho:
http://www.imaputz.com/cssStuff/bigFourVersion.html
Você tem que adicionar o display: block para o thead> tr e tbody
Outras dicas
Usando o display: estilo do bloco só funciona se você tiver uma coluna. Se você tiver várias colunas de dados - com vários campos - então display: block aparece para fazer todas as colunas de dados de rolagem, mas sob a primeira coluna (faz o mesmo no Firefox - que é o único navegador que eu sei que não tbody rolagem bem). . Aliás, no Firefox - você pode usar o overflow-x: estilo escondido para suprimir a rolagem horizontal
Eu percebi que o problema apenas menciono ocorre se você não está especificando uma largura para os th e td elementos - se você pode corrigir as larguras das colunas, em seguida, ele funciona. Problema para mim é que não posso corrigir as larguras das colunas.
Tente o primeiro método desta página, CSS pura, com uma única tabela (2 divs em torno da mesa, eo thead é positionned absoluto): http://www.cssplay.co.uk/menu/tablescroll.html Parece funcionar em FF4 / IE9 / IE8 além IE7 / FF3.6.
Eu tive o mesmo problema e escreveu um script jQuery para fazer isso por mim ... usa dois elementos da tabela e formata o css em conformidade. Espero que isso ajude outras pessoas que têm o mesmo problema ...
Eu vi de Sean Haddy excelente solução e tomou o liberdade de fazendo edições :
- Use classes em vez de ID, assim que um script de jQuery pode ser reutilizado para várias tabelas em uma página
- Adicionado suporte para elementos de tabela HTML semânticos como legenda, thead, tfoot e tbody
- Feito barra de rolagem opcional para que ele não irá aparecer para tabelas que são "mais curta" do que a altura de rolagem
- rolagem Ajustado largura da div para trazer a barra de rolagem até a borda direita da tabela
- conceito disponibilizadas pelos
- usando escondida-ária = "true" na tabela estática injetado cabeçalho
- e deixando thead original no lugar, apenas escondida com jQuery e conjunto
aria-hidden="false"
- exemplos Mostraram de várias tabelas com tamanhos diferentes
Sean fez o trabalho pesado, no entanto. Graças a Matt Burland, também, por apontar necessidade de tfoot apoio.
Por favor, veja por si mesmo em http://jsfiddle.net/jhfrench/eNP2N/
Um enfrentou o mesmo problema há muito tempo, e eu finalmente estabelecer as duas tabelas aproximar. Este é o resultado: http://jsfiddle.net/bGr4V/3/ , ele funciona para todos navegadores (IE6 + incl).
Na este jsFiddle você pode jogar com uma versão limpa.
Minha solução foi adicionar um célula correção <th class="fix"> </th>
em thead
para preencher o espaço da barra de rolagem na tbody
, em seguida, dar uma coluna de largura variável (<td class="grow">
), então o cabeçalho célula correção não iria unmatch no redimensionamento.
HTML:
<div class="fixed_table">
<div class="head">
<table>
<thead>
<tr>
<th>Column header</th>
<th class="grow">Column header</th>
<th class="fix"> </th>
</tr>
</thead>
</table>
<div class="body">
<table class="full_table">
<caption class="caption">Caption</caption>
<tbody>
<tr>
<td>Data</td>
<td class="grow">Data</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
</div>
</div>
CSS:. tem *
e _
corte para ie6-7, e uma específica -webkit
para o cabeçalho correção de células correspondência largura de rolagem em cada caso
.fixed_table table {
table-layout: fixed;
width: auto;
border-width: 0;
padding: 0;
border-collapse: collapse;
}
.fixed_table .body {
overflow: scroll;
overflow-x: hidden;
max-height: 10.75em;
min-height: 2.5em;
padding-bottom: 0.8em;
*padding-right: 17px; /*ie7 & ie6*/
_padding-right: 0; /*ie6*/
_height: 10em ;
}
.fixed_table th, .fixed_table td {
width: 4.7em;
}
.fixed_table .grow {
width: auto;
}
.fixed_table .fix {
width: 16px;
*width: 17px; /*ie7 & ie6*/
_width: 16px; /*ie6*/
}
/* webkit specific */
@media screen and (-webkit-min-device-pixel-ratio:0) {
.fixed_table .fix{ width: 17px }
}
O pensamento eu jogaria minha solução na mistura - http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/ .
É preciso a mesma rota básica como solução de @ Michael Koper, mas inclui uma solução alternativa para que a tabela vai olhar correto no IE volta ao IE6.
Eu resolver o problema de largura, dando a <table>
um table-layout: fixed
e explicitamente a atribuição de largura de células em cada coluna. Não é o ideal, mas ele faz produzir uma tabela semântica que irá alinhar cross browser independentemente de uma barra de rolagem é necessária.
Demonstração: http://codepen.io/tjvantoll/pen/JEKIu
Eu desenvolvi solução javascript para o problema
acima
que funciona apenas no Firefox 7+ como eu ter testado apenas em FF
Eu vim para esta discussão e encontrou solução apontada pelo Michael Koper
Nesta solução três coisas importantes são feitas
1) fixar a coluna largura
2) thead> tr exibição é configurado para bloquear
3) Exibição tbody está definido para bloquear
como outros já mencionaram há problema para corrigir a largura, eu também estou no mesmo lugar;
mesmo eu não posso corrigir a largura estaticamente
Então eu pensei que irá corrigir a largura dinamicamente (após a tabela é processado no navegador) e este fez o truque:)
Segue-se a solução em javascript que funciona apenas no FF
(I ter testado apenas em FF, eu não tenho acesso a outros navegadores)
function test1(){
var tbodys = document.getElementsByTagName("TBODY");
for(var i=0;i<tbodys.length;i++){
do_tbodyscroll(tbodys[i]);
}
}
function do_tbodyscroll(_tbody){
// get the table node
var table = _tbody.parentNode;
// first row of tbody
var _fr = _tbody.getElementsByTagName("TR")[0];
// first row cells ..
var _frcells = _fr.cells;
// Width array , width of each element is stored in this array
var widtharray = new Array(_frcells.length);
for(var i=0;i<_frcells.length;i++){
widtharray[i] = _frcells[i].scrollWidth;
}
// Apply width to first row
for(var i=0;i<_frcells.length;i++){
_frcells[i].width = widtharray[i];
}
// Get the Last row in Thead ...
// COLGROUPS USING COLSPAN NOT YET SUPPORTED
var thead = table.getElementsByTagName("THEAD")[0];
var _rows = thead.getElementsByTagName("TR");
var tableheader = _rows[_rows.length - 1];
var headercells = tableheader.cells;
// Apply width to header ..
for(var i=0;i<headercells.length;i++){
headercells[i].width = widtharray[i];
}
// ADD 16 Pixel of scroll bar to last column ..
headercells[headercells.length -1 ].width = widtharray[headercells.length -1] + 16;
tableheader.style.display = "block";
_tbody.style.display = "block";
}
Esta solução descobre o que é a largura da coluna a partir do navegador
e configurar de novo a mesma largura de colunas (cabeçalho e a primeira fileira de tbody)
após a largura é de conjunto; thead> tr e tbody exibição é definido como bloco
Hope esta solução é útil para todos vocês ..
se você pode estendê-lo a outros navegadores responda a este post
Este é realmente muito hacky mas talvez ele vai ajudar alguém em algum lugar ...
Ele usa colunas em vez de linhas para processá-lo seria, essencialmente, ser feito para trás.
DOCTYPE Transitional adicionado para compatibilidade IE.
Pode ser um exagero para esta pergunta, mas YUI ainda oferece possivelmente o melhor livre tabela de dados cross-browser. Ele pode ser usado para dados somente leitura também.
Clique nos exemplos lá para ver amostras de rolagem. Uma vez que, eu sou um novato para stackoverflow, eu só posso postar estas duas ligações.
Add display:block;
Isso também irá remover a rolagem horizontal desnecessária no FireFox também. Você também é, sem dúvida, ciente de que nem exemplo funciona em MSIE 8.
<table>
<thead>
<tr><th>This is the header and doesn't scroll</th></tr>
</thead>
<tbody style="height:100px; overflow:auto;display:block;">
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
<tr><td>content that scrolls</td></tr>
</tbody>
</table>
Há aqui um exemplo que funciona em IE5 +, Firefox e Chrome. No entanto, ela utiliza largura fixa colunas. http://www.cssplay.co.uk/menu/tablescroll.html
Se alguém precisa dele para trabalhar em modo IE peculiaridades, aqui está como eu mudei e simplificado I.G. código de Pascual de trabalho:
.fixed_table{
overflow: scroll;
overflow-x: hidden;
max-height: 300px;
height: 300px;
min-height: 50px;
padding-right:0;
}
#datatable td
{
padding:3px;
text-align: center;
width: 9%;
vertical-align: middle;
background-color: #343435;
color: #E0E0E3;
overflow:hidden;
}
<div class="head">
<table>
<thead>
<tr>
<th>Time (GMT)</th>
<th>Price</th>
</tr>
</thead>
</table>
</div>
<div class="fixed_table">
<table id="datatable" cellspacing="1" cellpadding="1">
<tbody></tbody>
</table>
</div>
Deixe a mesa desenhar como a sua maneira e calcular a largura de cada coluna e colocá-lo na cada título. Os títulos são feitos com divisões e então nós podemos deixar a mesa para ser rolada livre.
<!DOCTYPE html>
<html>
<head>
<style>
.t_heading{
margin-top: 20px;
font-family: Verdana, Geneva, sans-serif;
background-color: #4CAF50;
}
.heading{
background-color: #4CAF50;
color: white;
float:left;
padding: 8px 0PX 8PX 0PX;
border-bottom: 1px solid #ddd;
height: 20px;
text-align: left;
}
.t_data{
overflow-y: scroll;
overflow-x: hidden;
height:0px;
width: 100%;
}
.t_content{
border-collapse: collapse;
font-family: Verdana, Geneva, sans-serif;
width: 100%;
}
.column1,.column2,.column3,.column4{
padding: 8px 0PX 8PX 0PX;
text-align: left;
border-bottom: 1px solid #ddd;
}
.t_row:hover{
background-color:#f5f5f5;
}
</style>
<script>
function setBody(){
var body = document.body,
html = document.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight );
height = height-300;
/*
** By changing the subtraction value, You can fit the table in to the screen correctly.
** Make sure not to come the hscroll.
** Or you can set fixed height with css for the div as your wish.
*/
document.getElementById("t_data").style.height = height+"px";
setColumnWidth("column1");
setColumnWidth("column2");
setColumnWidth("column3");
setColumnWidth("column4");
}
function setColumnWidth(o){
var object = o;
var x = document.getElementsByClassName(object);
var y = x[0].clientWidth;
document.getElementById(object).style.width = y+"px";
}
</script>
</head>
<body onload="setBody()">
<div class="t_heading">
<div class="heading" id="column1">Heading 1</div>
<div class="heading" id="column2">Heading 2</div>
<div class="heading" id="column3">Heading 3</div>
<div class="heading" id="column4">Heading 4</div>
</div>
<div class="t_data" id="t_data">
<table class="t_content">
<tr class='t_row'>
<td class='column1'>Column1 Row 0</td>
<td class='column2'>Column2 Row 0</td>
<td class='column3'>Column3 Row 0</td>
<td class='column4'>Column4 Row 0</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 1</td>
<td class='column2'>Column2 Row 1</td>
<td class='column3'>Column3 Row 1</td>
<td class='column4'>Column4 Row 1</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 2</td>
<td class='column2'>Column2 Row 2</td>
<td class='column3'>Column3 Row 2</td>
<td class='column4'>Column4 Row 2</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 3</td>
<td class='column2'>Column2 Row 3</td>
<td class='column3'>Column3 Row 3</td>
<td class='column4'>Column4 Row 3</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 4</td>
<td class='column2'>Column2 Row 4</td>
<td class='column3'>Column3 Row 4</td>
<td class='column4'>Column4 Row 4</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 5</td>
<td class='column2'>Column2 Row 5</td>
<td class='column3'>Column3 Row 5</td>
<td class='column4'>Column4 Row 5</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 6</td>
<td class='column2'>Column2 Row 6</td>
<td class='column3'>Column3 Row 6</td>
<td class='column4'>Column4 Row 6</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 7</td>
<td class='column2'>Column2 Row 7</td>
<td class='column3'>Column3 Row 7</td>
<td class='column4'>Column4 Row 7</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 8</td>
<td class='column2'>Column2 Row 8</td>
<td class='column3'>Column3 Row 8</td>
<td class='column4'>Column4 Row 8</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 9</td>
<td class='column2'>Column2 Row 9</td>
<td class='column3'>Column3 Row 9</td>
<td class='column4'>Column4 Row 9</td>
</tr><tr class='t_row'>
<td class='column1'>Column1 Row 10</td>
<td class='column2'>Column2 Row 10</td>
<td class='column3'>Column3 Row 10</td>
<td class='column4'>Column4 Row 10</td>
</tr>
<!--
<?php
$data = array();
for($a = 0; $a<50; $a++)
{
$data[$a] = array();
$data[$a][0] = "Column1 Row ".$a;
$data[$a][1] = "Column2 Row ".$a;
$data[$a][2] = "Column3 Row ".$a;
$data[$a][3] = "Column4 Row ".$a;
}
/*
** supose you have data in an array.. which red from database. The table will draw using array data. Or you can draw the table manualy.
** tip: If using manual table, No need of
** 'var x = document.getElementsByClassName(object); var y = x[0].clientWidth;'.
** You can just set ID of first row's cells in to some name and use it to read width.
*/
for($i=0;$i<sizeof($data);$i++){
echo "<tr class='t_row'><td class='column1'>".$data[$i][0]."</td><td class='column2'>".$data[$i][1]."</td><td class='column3'>".$data[$i][2]."</td><td class='column4'>".$data[$i][3]."</td></tr>";
}
?>
-->
</table>
</div>
</body>
</html>