
descarado
¿Existe una técnica de CSS/JavaScript entre navegadores para mostrar una tabla HTML larga de modo que los encabezados de las columnas permanezcan fijos en la pantalla y no se desplacen con el cuerpo de la tabla? Piense en el efecto de “congelar paneles” en Microsoft Excel.
Quiero poder desplazarme por el contenido de la tabla, pero siempre poder ver los encabezados de las columnas en la parte superior.

Mahés
Estuve buscando una solución para esto por un tiempo y descubrí que la mayoría de las respuestas no funcionan o no son adecuadas para mi situación, así que escribí una solución simple con jQuery.
Este es el esquema de la solución:
- Clone la tabla que debe tener un encabezado fijo y coloque la copia clonada encima del original.
- Retire el cuerpo de la mesa de la mesa superior.
- Retire el encabezado de la tabla de la tabla inferior.
- Ajuste los anchos de columna. (Hacemos un seguimiento de los anchos de columna originales)
A continuación se muestra el código en una demostración ejecutable.
function scrolify(tblAsJQueryObject, height) {
var oTbl = tblAsJQueryObject;
// for very large tables you can remove the four lines below
// and wrap the table with <div> in the mark-up and assign
// height and overflow property
var oTblDiv = $("<div/>");
oTblDiv.css('height', height);
oTblDiv.css('overflow', 'scroll');
oTbl.wrap(oTblDiv);
// save original width
oTbl.attr("data-item-original-width", oTbl.width());
oTbl.find('thead tr td').each(function() {
$(this).attr("data-item-original-width", $(this).width());
});
oTbl.find('tbody tr:eq(0) td').each(function() {
$(this).attr("data-item-original-width", $(this).width());
});
// clone the original table
var newTbl = oTbl.clone();
// remove table header from original table
oTbl.find('thead tr').remove();
// remove table body from new table
newTbl.find('tbody tr').remove();
oTbl.parent().parent().prepend(newTbl);
newTbl.wrap("<div/>");
// replace ORIGINAL COLUMN width
newTbl.width(newTbl.attr('data-item-original-width'));
newTbl.find('thead tr td').each(function() {
$(this).width($(this).attr("data-item-original-width"));
});
oTbl.width(oTbl.attr('data-item-original-width'));
oTbl.find('tbody tr:eq(0) td').each(function() {
$(this).width($(this).attr("data-item-original-width"));
});
}
$(document).ready(function() {
scrolify($('#tblNeedsScrolling'), 160); // 160 is height
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div style="width:300px;border:6px green solid;">
<table border="1" width="100%" id="tblNeedsScrolling">
<thead>
<tr><th>Header 1</th><th>Header 2</th></tr>
</thead>
<tbody>
<tr><td>row 1, cell 1</td><td>row 1, cell 2</td></tr>
<tr><td>row 2, cell 1</td><td>row 2, cell 2</td></tr>
<tr><td>row 3, cell 1</td><td>row 3, cell 2</td></tr>
<tr><td>row 4, cell 1</td><td>row 4, cell 2</td></tr>
<tr><td>row 5, cell 1</td><td>row 5, cell 2</td></tr>
<tr><td>row 6, cell 1</td><td>row 6, cell 2</td></tr>
<tr><td>row 7, cell 1</td><td>row 7, cell 2</td></tr>
<tr><td>row 8, cell 1</td><td>row 8, cell 2</td></tr>
</tbody>
</table>
</div>
Esta solución funciona en Chrome e IE. Dado que se basa en jQuery, esto también debería funcionar en otros navegadores compatibles con jQuery.

mkoryak
También creé un complemento que aborda este problema. Mi proyecto – jQuery.floatThead ha existido por más de 4 años y es muy maduro.
No requiere estilos externos y no espera que su tabla tenga un estilo en particular. Es compatible con Internet Explorer9+ y Firefox/Chrome.
Actualmente (2018-05) cuenta con:
405 confirmaciones y 998 estrellas en GitHub
Muchas (no todas) de las respuestas aquí son trucos rápidos que pueden haber resuelto el problema que tenía una persona, pero no funcionarán para todas las mesas.
Algunos de los otros complementos son antiguos y probablemente funcionen muy bien con Internet Explorer, pero fallarán en Firefox y Chrome.

Pedro Mortensen
Todos los intentos de resolver esto desde fuera de la especificación CSS son sombras pálidas de lo que realmente queremos: Cumplir con la promesa implícita de THEAD.
Este problema de encabezados congelados para una tabla ha sido una herida abierta en HTML/CSS durante mucho tiempo.
En un mundo perfecto, habría una solución de CSS puro para este problema. Desafortunadamente, no parece haber uno bueno en su lugar.
Las discusiones estándar relevantes sobre este tema incluyen:
ACTUALIZAR: Firefox enviado position:sticky
en la versión 32. ¡Todos ganan!

H. Pauwelyn
TL;DR
Si apunta a navegadores modernos y no tiene necesidades de estilo extravagantes: http://jsfiddle.net/dPixie/byB9d/3/ … Aunque el versión de los cuatro grandes es bastante dulce también, esta versión maneja mucho mejor el ancho fluido.
¡Buenas noticias para todos!
Con los avances de HTML5 y CSS3, esto ahora es posible, al menos para los navegadores modernos. La implementación ligeramente pirateada que se me ocurrió se puede encontrar aquí: http://jsfiddle.net/dPixie/byB9d/3/. Lo he probado en FX 25, Chrome 31 e IE 10…
HTML relevante (sin embargo, inserte un tipo de documento HTML5 en la parte superior de su documento):
html,
body {
margin: 0;
padding: 0;
height: 100%;
}
section {
position: relative;
border: 1px solid #000;
padding-top: 37px;
background: #500;
}
section.positioned {
position: absolute;
top: 100px;
left: 100px;
width: 800px;
box-shadow: 0 0 15px #333;
}
.container {
overflow-y: auto;
height: 200px;
}
table {
border-spacing: 0;
width: 100%;
}
td+td {
border-left: 1px solid #eee;
}
td,
th {
border-bottom: 1px solid #eee;
background: #ddd;
color: #000;
padding: 10px 25px;
}
th {
height: 0;
line-height: 0;
padding-top: 0;
padding-bottom: 0;
color: transparent;
border: none;
white-space: nowrap;
}
th div {
position: absolute;
background: transparent;
color: #fff;
padding: 9px 25px;
top: 0;
margin-left: -25px;
line-height: normal;
border-left: 1px solid #800;
}
th:first-child div {
border: none;
}
<section class="positioned">
<div class="container">
<table>
<thead>
<tr class="header">
<th>
Table attribute name
<div>Table attribute name</div>
</th>
<th>
Value
<div>Value</div>
</th>
<th>
Description
<div>Description</div>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>align</td>
<td>left, center, right</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the alignment of a table according to surrounding text</td>
</tr>
<tr>
<td>bgcolor</td>
<td>rgb(x,x,x), #xxxxxx, colorname</td>
<td>Not supported in HTML5. Deprecated in HTML 4.01. Specifies the background color for a table</td>
</tr>
<tr>
<td>border</td>
<td>1,""</td>
<td>Specifies whether the table cells should have borders or not</td>
</tr>
<tr>
<td>cellpadding</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between the cell wall and the cell content</td>
</tr>
<tr>
<td>cellspacing</td>
<td>pixels</td>
<td>Not supported in HTML5. Specifies the space between cells</td>
</tr>
<tr>
<td>frame</td>
<td>void, above, below, hsides, lhs, rhs, vsides, box, border</td>
<td>Not supported in HTML5. Specifies which parts of the outside borders that should be visible</td>
</tr>
<tr>
<td>rules</td>
<td>none, groups, rows, cols, all</td>
<td>Not supported in HTML5. Specifies which parts of the inside borders that should be visible</td>
</tr>
<tr>
<td>summary</td>
<td>text</td>
<td>Not supported in HTML5. Specifies a summary of the content of a table</td>
</tr>
<tr>
<td>width</td>
<td>pixels, %</td>
<td>Not supported in HTML5. Specifies the width of a table</td>
</tr>
</tbody>
</table>
</div>
</section>
¡¿Pero cómo?!
En pocas palabras, tiene un encabezado de tabla, que oculta visualmente al hacerlo de 0px de alto, que también contiene divs utilizados como encabezado fijo. El contenedor de la tabla deja suficiente espacio en la parte superior para permitir que el encabezado tenga una posición absoluta, y la tabla con las barras de desplazamiento aparece como cabría esperar.
El código anterior usa la clase posicionada para posicionar la tabla absolutamente (lo estoy usando en un cuadro de diálogo de estilo emergente), pero también puede usarlo en el flujo del documento eliminando el positioned
clase del contenedor.
Pero …
no es perfecto Firefox se niega a hacer que la fila del encabezado sea 0px (al menos no encontré ninguna forma) pero obstinadamente la mantiene en un mínimo de 4px… No es un gran problema, pero dependiendo de tu estilo, se alterará con tus bordes, etc.
La tabla también usa un enfoque de columna falsa donde el color de fondo del contenedor en sí se usa como fondo para los divs del encabezado, que son transparentes.
Resumen
En general, puede haber problemas de estilo según sus requisitos, especialmente bordes o fondos complicados. También puede haber problemas con la computabilidad, aún no lo he comprobado en una amplia variedad de navegadores (comenta con tus experiencias si lo pruebas), pero no encontré nada parecido, así que pensé que valía la pena publicarlo. de todos modos …
Prueba esto: Tabla desplazable de CSS puro con encabezado fijo EDITAR: Este debería funcionar en Internet Explorer 7 como se ve en el ejemplo: Desplazamiento de tabla HTML con encabezado fijo EDITAR 2: Encontré un par de enlaces adicionales que podrían ser útiles: – Encabezado fijo estúpido – Un complemento de jQuery con algunas limitaciones. – [Fixed Table Headers](cross-browser.com/x/example
– puntuaciones
23 de marzo de 2009 a las 12:13
Me he encontrado con muchas soluciones que generalmente funcionan, pero ninguna de ellas funcionó desplazando div. Quiero decir, su tabla está dentro de un div desplazable y aún desea que el encabezado de su tabla aún esté dentro de ese div. He resuelto eso y comparto el solución aquí.
– Yogee
23 de mayo de 2013 a las 13:16
En 2018, todos los navegadores pueden usar la siguiente solución simple:
thead th { position: sticky; top: 0; }
. Safari necesita un prefijo de proveedor:-webkit-sticky
–Daniel Waltrip
31 de agosto de 2018 a las 20:29
@DanielWaltrip, debe agregar esta respuesta para que pueda ser votada en el primer puesto; todas las demás respuestas son redundantes con la posición: pegajoso es un mejor soporte hoy en día
–Peter Kerr
3 oct 2018 a las 13:40
¡Hecho! stackoverflow.com/a/52637779/111635
–Daniel Waltrip
4 de octubre de 2018 a las 1:37