¿Tabla HTML con encabezados fijos?

15 minutos de lectura

¿Tabla HTML con encabezados fijos
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.

  • 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

1646958974 435 ¿Tabla HTML con encabezados fijos
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:

  1. Clone la tabla que debe tener un encabezado fijo y coloque la copia clonada encima del original.
  2. Retire el cuerpo de la mesa de la mesa superior.
  3. Retire el encabezado de la tabla de la tabla inferior.
  4. 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.

  • y ¿cómo podemos solucionar el problema cuando el contenido es más grande que el ancho?

    – Maertz

    30 de noviembre de 2011 a las 17:01

  • @tetra td { ancho máximo: 30px; } esto le permitirá a usted, el desarrollador, controlar cómo se muestran las filas.

    – Lyuben Todorov

    30 de mayo de 2012 a las 22:28

  • Pero, ¿qué pasa si el contenido de alguna celda de encabezado es más largo que el de las celdas td? Probé eso en IE7, y width() rompe todo. Sin embargo, IE8 e IE9 funcionan bien…

    – JustAMartin

    10 de noviembre de 2012 a las 21:54

  • Desafortunadamente, si necesita una alineación perfecta de píxeles de las columnas, esto no funciona: jsbin.com/elekiq/1 (código fuente). Puede ver que algunos encabezados están desplazados de donde deberían estar, solo un poco. El efecto es más obvio si estás usando fondos: jsbin.com/elekiq/2 (código fuente). (Estaba trabajando de la misma manera, me encontré con esto en mi código, encontré el tuyo y pensé “¡Oh, me pregunto si me resolvió eso!” Lamentablemente no. 🙂 ) Los navegadores son TAN molestos por querer controlar el anchos de celdas…

    –TJ Crowder

    25 de junio de 2013 a las 13:38


  • Esto no parece funcionar con el desplazamiento horizontal: crea el encabezado, pero se extiende más allá del área desplazable (visiblemente) y no se desplaza con el contenido.

    – Choque

    5 de agosto de 2013 a las 19:56

  • ¡Gracias! Agregaré una nueva versión más tarde hoy cuando llegue a casa del trabajo. Aquí hay un enlace a mi entrada de blog con lo que estoy agregando: fixedheadertable.mmalek.com/2009/10/07/…

    – Marca

    7 oct 2009 a las 18:13

  • Gracias por esto. Sé que esta pregunta tiene más de un año, pero incluso a riesgo de remover sedimentos sedimentados, me gustaría decirle que apreciamos su trabajo.

    – sova

    21 de octubre de 2010 a las 17:39

  • En su demostración, los anchos están desactivados en ie6 🙁 el encabezado y el cuerpo de la tabla no están alineados.

    – Descarado

    14 de octubre de 2011 a las 9:37


  • La última versión no funciona en IE6. Ya no soy compatible con IE6.

    – Marca

    14/10/2011 a las 15:45

  • excelente trabajo Mark: desafortunadamente, hay algunos problemas con el desplazamiento del encabezado fijo y la columna en dispositivos móviles (iPad, tableta Android) – cuando desplazo el contenido, esas partes fijas no se desplazan – cuando dejo de desplazarme y toco una vez la tabla , las partes fijas “saltan” a las posiciones adecuadas. ¿Existe una forma sencilla de solucionarlo?

    – Okizb

    19 de febrero de 2013 a las 17:43

¿Tabla HTML con encabezados fijos
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.

  • Gran complemento, admite tablas anidadas y compensaciones.

    –Mihai Alex

    27/10/2015 a las 12:00

  • Genial. Muchas gracias. El complemento funcionó bien en Firefox 45.2, Chromium 51 e IE 11. Además, no interfiere con una gran cantidad de código JS y jQuery creado en la misma página.

    –Aldo Paradiso

    12/09/2016 a las 11:39

  • Gracias. Me complace informar que, en este momento, el proyecto recibe alrededor de 1 informe de error cada 4 meses. No estoy haciendo muchos cambios importantes. Es bastante sólido y funciona.

    – mkoryak

    1 de noviembre de 2018 a las 15:57

  • Andrew, ¿qué se supone que debo hacer con tu comentario? Por supuesto, el complemento funciona, ya que se usa en mi propio sitio de documentos y en muchos otros sitios.

    – mkoryak

    20 de agosto de 2021 a las 0:22

1646958975 678 ¿Tabla HTML con encabezados fijos
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!

  • Gran complemento, admite tablas anidadas y compensaciones.

    –Mihai Alex

    27/10/2015 a las 12:00

  • Genial. Muchas gracias. El complemento funcionó bien en Firefox 45.2, Chromium 51 e IE 11. Además, no interfiere con una gran cantidad de código JS y jQuery creado en la misma página.

    –Aldo Paradiso

    12/09/2016 a las 11:39

  • Gracias. Me complace informar que, en este momento, el proyecto recibe alrededor de 1 informe de error cada 4 meses. No estoy haciendo muchos cambios importantes. Es bastante sólido y funciona.

    – mkoryak

    1 de noviembre de 2018 a las 15:57

  • Andrew, ¿qué se supone que debo hacer con tu comentario? Por supuesto, el complemento funciona, ya que se usa en mi propio sitio de documentos y en muchos otros sitios.

    – mkoryak

    20 de agosto de 2021 a las 0:22

¿Tabla HTML con encabezados fijos
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 …

  • Si reduce el ancho de la ventana hasta que se activa el desplazamiento horizontal, entonces el encabezado no se desplaza horizontalmente con el cuerpo. Maldito.

    – dlaliberte

    17/08/2014 a las 18:30

  • @dlaliberte: bueno, dado que el encabezado y la tabla son en realidad dos elementos diferentes, puede, por supuesto, entrar en rarezas. Pero mi ejemplo no permite el desbordamiento en las columnas de la tabla y los encabezados suelen ser más fáciles de controlar que el contenido de la tabla. Dicho esto, si hace que el encabezado se “desborde”, sobresaldrá a la derecha de la tabla y se verá severamente roto. Podría arreglar esto estableciendo un ancho mínimo en la tabla, forzándolo a desbordar la página también… Pero es un truco, por lo que nunca será perfecto…

    – Jonas Schubert Erlandsson

    2 de diciembre de 2014 a las 12:19

  • Vale la pena señalar que esto requiere un diseño donde se pueda especificar una mesa de altura fija.

    – Descarado

    30 de marzo de 2015 a las 15:46

  • @Cheekysoft: no, la tabla y el contenido de la fila pueden fluir libremente. El contenedor, en mi ejemplo el <section> elemento, debe tener una altura limitada solo para obligarlo a desbordarse y mostrar el desplazamiento. Cualquier diseño que haga que el contenedor se desborde funcionaría. Si encuentra un caso en el que no lo hace, publique un enlace a un violín.

    – Jonas Schubert Erlandsson

    02/04/2015 a las 12:56

  • El codificado duro padding-top El valor también significa que si el texto del encabezado de la tabla está en más de una línea, aparecerá en la parte superior de las celdas de la tabla. Lástima, porque esto funciona a las mil maravillas la mayor parte del tiempo. Muy buen truco con el div en el th para evitar el problema del tamaño de la columna que tienen la mayoría de las otras soluciones.

    – Bernhard Hoffmann

    14 de agosto de 2015 a las 14:19

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad