¿Cómo puedo dejar que el cuerpo de una mesa se desplace pero mantenga su cabeza fija en su lugar?


148

Estoy escribiendo una página donde necesito una tabla HTML para mantener un tamaño establecido. Necesito los encabezados en la parte superior de la tabla para permanecer allí en todo momento, pero también necesito que el cuerpo de la tabla se desplace sin importar cuántas filas se agreguen a la tabla. Piensa en una mini versión de Excel. Esto parece una tarea simple, pero casi todas las soluciones que he encontrado en la web tienen algunos inconvenientes. ¿Como puedo resolver esto?


2
Hay muchos ejemplos por ahí. Este es uno de ellos .
Darren Kopp

Necesito apuntar a IE6, IE7, FF, ... pero especialmente IE desafortunadamente
menta

Hay muchos hacks CSS allí. Debería ser trivial trabajar en IE7.
Jim

44
¡Estoy interesado en la respuesta para todos los navegadores!
mentolado

15
"Debería ser trivial trabajar en IE7". Jim, ¿eres tú? ¿Eres mi gerente de proyecto? :)
Aaronius

Respuestas:


53

Tenía que encontrar la misma respuesta. El mejor ejemplo que encontré es http://www.cssplay.co.uk/menu/tablescroll.html . Encontré que el ejemplo # 2 funcionó bien para mí. Deberá establecer la altura de la tabla interna con Java Script, el resto es CSS.


3
desafortunadamente, este método falla cuando tienes una tabla ancha (desplazamiento horizontal). Tendrás dos barras de desplazamiento horizontales; uno para el encabezado y otro para los datos.
vol7ron

44
su solución no funciona si no especifica <th> ancho dentro de <thead>
Alexandru R

2
Para cumplir con los estándares (relativamente) nuevos de desbordamiento de pila, ¿podría editar esta respuesta para incluir los bits relevantes del enlace?
Financia la demanda de Mónica el

¿Dónde está la fuente, Billy?
Vela el

Es imposible sincronizar los anchos de columna entre el encabezado y el cuerpo de la tabla (desplazable) sin recurrir a JavaScript o valores predefinidos.
rustyx


12

Vi la excelente solución de Sean Haddy a una pregunta similar y me tomé la libertad de hacer algunas ediciones :

  • Use clases en lugar de ID, por lo que un script jQuery podría reutilizarse para varias tablas en una página
  • Se agregó soporte para elementos de tabla HTML semánticos como subtítulos, thead, tfoot y tbody
  • La barra de desplazamiento es opcional para que no aparezca para las tablas que son "más cortas" que la altura desplazable
  • Se ajustó el ancho del div de desplazamiento para llevar la barra de desplazamiento hasta el borde derecho de la tabla
  • Concepto hecho accesible por
    • usando aria-hidden = "true" en el encabezado de la tabla estática inyectada
    • y dejando el thead original en su lugar, solo oculto con jQuery y configurado aria-hidden="false"
  • Se muestran ejemplos de varias tablas con diferentes tamaños.

Sean hizo el trabajo pesado, sin embargo. Gracias a Matt Burland, también, por señalar la necesidad de apoyar el pie.

Véalo usted mismo en http://jsfiddle.net/jhfrench/eNP2N/


Bien, pero se arruina si quieres un encabezado y un pie de página.
Matt Burland

3
Gracias Matt, hice el ajuste.
Jeromy French

La alineación necesita ajustes si muestra los bordes td y th.
dhochee

8

¿Has intentado usar thead y tbody y establecer una altura fija en tbody con overflow: scroll?

¿Cuáles son sus navegadores de destino?

EDITAR: Funcionó bien (casi) en Firefox: la adición de la barra de desplazamiento vertical también provocó la necesidad de una barra de desplazamiento horizontal. IE simplemente establece la altura de cada td a lo que había especificado la altura de tbody. Aquí está lo mejor que se me ocurrió:

<html>
    <head>
    <title>Blah</title>
    <style type="text/css">
    table { width:300px; }
    tbody { height:10em;  overflow:scroll;}
    td { height:auto; }
    </style>
    </head>
    <body>
    <table>
        <thead>
            <tr>
              <th>One</th><th>Two</th>
              </td>
            </tr>
        </thead>
        <tbody>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
            <tr><td>Data</td><td>Data</td></tr>
        </tbody>
    </table>
    </body>
</html>

1
Necesito apuntar a IE6, IE7, FF, ... pero especialmente IE desafortunadamente
menta

Cambie la tabla para que tenga menos del 100% de ancho, digamos 99% y debería solucionar el problema
WolfmanDragon

2
overflow-x: hidden;Y overflow-y: autotambién ayuda.
justkt

77
Esto solía funcionar en Firefox, y es el código obvio y no complicado. Sin embargo, en versiones más recientes de Firefox, está roto.
Rasmus Kaj

66
Esto no funciona porque el "desbordamiento" solo se aplica a los "contenedores de bloques" ( w3.org/TR/CSS21/visufx.html#overflow ), y los cuadros de tabla no son "contenedores de bloques" ( w3.org/TR/CSS21/ visuren.html # block-boxes ).
mhsmith

8

Lo que necesitas es:

1) tener un cuerpo de mesa de altura limitada ya que el desplazamiento se produce solo cuando el contenido es más grande que la ventana de desplazamiento. Sin embargo tbody, no se puede dimensionar, y debe mostrarlo como blockpara hacerlo:

tbody {
   overflow-y: auto;
   display: block;
   max-height: 10em;    // For example
}

2) Vuelva a sincronizar el ancho de las columnas del encabezado de la tabla y del cuerpo de la tabla, ya que esto último lo blockconvirtió en un elemento no relacionado. La única forma de hacerlo es simular la sincronización aplicando el mismo ancho de columnas a ambos .

Sin embargo, dado que tbodyes un blockahora, ya no puede comportarse como un table. Ya que todavía necesitas untable comportamiento para mostrar sus columnas correctamente, la solución es solicitar que cada una de sus filas se muestre como tables individuales :

thead {         
   display: table;  
   width: 100%;     // Fill the containing table
}
tbody tr {
   display: table;
   width: 100%;     // Fill the containing table
}

(Tenga en cuenta que, utilizando esta técnica, ya no podrá atravesar filas).

Una vez hecho esto, puede exigir que los anchos de columna tengan el mismo ancho en ambos thead y tbody. No podrías eso:

  • individualmente para cada columna (a través de clases CSS específicas o estilo en línea), lo cual es bastante tedioso para cada instancia de tabla;
  • uniformemente para todas las columnas (a través de th, td { width: 20%; } si tiene 5 columnas, por ejemplo), lo cual es más práctico (no es necesario establecer el ancho para cada instancia de la tabla) pero no puede funcionar para ningún recuento de columnas
  • uniformemente para cualquier recuento de columnas, a través de un diseño de tabla fijo.

Prefiero la última opción, que requiere agregar:

thead {
   table-layout: fixed;   // Same layout for all cells
}
tbody tr {
   table-layout: fixed;   // Same layout for all cells
}
th, td {
   width: auto;   // Same width for all cells, if table has fixed layout
}    

Vea una demostración aquí , bifurcada de la respuesta a esta pregunta .


gracias por la explicación. Es fascinante de cuántas maneras se puede hacer algo como esto y la mayoría de las respuestas solo presentan un código y un enlace plunkr, dejándote que lo descubras por ti mismo.
Paul Rooney

4

Editar:   Esta es una respuesta muy antigua y está aquí para la prosperidad solo para mostrar que fue respaldada una vez en la década de 2000, pero se abandonó porque la estrategia de los navegadores en la década de 2010 fue respetar las especificaciones del W3C, incluso si se eliminaron algunas características: tabla desplazable con encabezado fijo / pie de página se especificó torpemente antes de HTML5.


Malas noticias

Desafortunadamente, no hay una forma elegante de manejar la tabla desplazable con fijo thead/ tfoot porque las especificaciones HTML / CSS no son muy claras sobre esa característica .

Explicaciones

Aunque la especificación HTML 4.01 dice thead/ tfoot/ tbodyse usa (¿se introduce?) Para desplazar el cuerpo de la tabla:

Las filas de la tabla pueden agruparse [...] utilizando los elementos THEAD, TFOOT y TBODY [...]. Esta división permite a los agentes de usuario soportar el desplazamiento de los cuerpos de la mesa independientemente de la cabeza y el pie de la mesa.

Pero la función de tabla desplazable que funciona en FF 3.6 se ha eliminado en FF 3.7 porque se considera un error porque no cumple con las especificaciones HTML / CSS. Mira esto y aquello comentarios sobre errores de FF.

Consejo de red de desarrolladores de Mozilla

A continuación se muestra una versión simplificada de los consejos útiles de MDN para la tabla desplazable.
Consulte esta página archivada o la versión francesa actual.

<style type="text/css">
table {
  border-spacing: 0;              /* workaround */
}
tbody {
  height: 4em;                    /* define the height */
  overflow-x: hidden;             /* esthetics */
  overflow-y: auto;               /* allow scrolling cells */
}
td {
  border-left:   1px solid blue;  /* workaround */
  border-bottom: 1px solid blue;  /* workaround */
}
</style>

<table>
    <thead><tr><th>Header
    <tfoot><tr><th>Footer
    <tbody>
        <tr><td>Cell 1    <tr><td>Cell 2
        <tr><td>Cell 3    <tr><td>Cell 4
        <tr><td>Cell 5    <tr><td>Cell 6
        <tr><td>Cell 7    <tr><td>Cell 8
        <tr><td>Cell 9    <tr><td>Cell 10
        <tr><td>Cell 11   <tr><td>Cell 12
        <tr><td>Cell 13   <tr><td>Cell 14
    </tbody>
</table>

Sin embargo, MDN también dice que esto ya no funciona en FF :-(
También he probado en IE8 => la tabla tampoco es desplazable: - ((


Los consejos de MDN para el enlace de la tabla desplazable no son información relevante sobre el colapso del borde. Tal vez la página se modificó porque pasaron 5 años
partizanos

Gracias @partizanos ¡Finalmente encontré la página wiki original en la historia de MDN! Mi vieja respuesta ahora parece obsoleta, pero para la prosperidad, la próxima generación de desarrolladores sabrá que era posible y fácil de implementar en la
década de

3

No estoy seguro de si alguien todavía está mirando esto, pero de la manera en que lo hice anteriormente es usar dos tablas para mostrar la tabla original única: la primera solo la línea del título de la tabla original y sin filas de cuerpo de tabla (o una fila de cuerpo vacía para hacer Validar).

El segundo está en un div separado y no tiene título y solo las filas del cuerpo de la tabla original. El div separado se hace desplazable.

La segunda tabla en su div se coloca justo debajo de la primera tabla en el HTML y parece una sola tabla con un encabezado fijo y una sección inferior desplazable. Solo he probado esto en Safari, Firefox e IE (las últimas versiones de cada uno en la primavera de 2010) pero funcionó en todos ellos.

El único problema que tenía era que la primera tabla no se validaría sin un cuerpo (validador W3.org - XHTML 1.0 estricto), y cuando agregué una sin contenido, se genera una fila en blanco. Puede usar CSS para que esto no sea visible, pero aún así ocupa espacio en la página.


¿Cómo ocuparía espacio la fila extra? No tiene que ocupar espacio en la pantalla si lo usa display: none;, a menos que se refiera al espacio en la fuente ...
ClarkeyBoy

3

Esta solución funciona en Chrome 35, Firefox 30 e IE 11 (otras versiones no probadas)

Su CSS puro: http://jsfiddle.net/ffabreti/d4sope1u/

Todo está configurado para mostrar: bloque, la mesa necesita una altura:

    table {
        overflow: scroll;
        display: block;    /*inline-block*/
        height: 120px;
    }
    thead > tr  {
        position: absolute;
        display: block;
        padding: 0;
        margin: 0;
        top: 0;
        background-color: gray;
    }
    tbody > tr:nth-of-type(1) {
        margin-top: 16px;
    }
    tbody tr {
        display: block;
    }

    td, th {
        width: 70px;
        border-style:solid;
        border-width:1px;
        border-color:black;
    }

2

Esto me causó grandes dolores de cabeza al tratar de implementar una cuadrícula de este tipo para una aplicación nuestra. Intenté todas las técnicas, pero cada una tenía problemas. Lo más cerca que llegué fue usar un complemento jQuery como Flexigrid (mire en http://www.ajaxrain.com alternativas ), pero esto no parece admitir tablas 100% anchas, que es lo que necesitaba.

Lo que terminé haciendo fue rodar el mío; Firefox admite tbodyelementos de desplazamiento , por lo que el navegador olfateó y usé CSS apropiado (configuración de altura, desbordamiento, etc.), pregunté si desea más detalles) para hacer ese desplazamiento, y luego para otros navegadores utilicé dos tablas separadas configuradas para usartable-layout: fixed que usan un tamaño algoritmo que se garantiza que no desborde el tamaño establecido (las tablas normales se expandirán cuando el contenido sea demasiado ancho para ajustarse). Al dar a ambas tablas anchos idénticos pude hacer que sus columnas se alinearan. Envolví el segundo en un conjunto div para desplazarse y con un poco de jiggery pokery con márgenes, etc., logré obtener la apariencia que quería.

Lo siento si esta respuesta suena un poco vaga en algunos lugares Estoy escribiendo rápidamente ya que no tengo mucho tiempo. ¡Deja un comentario si quieres que me expanda más!


Lamento resucitar este viejo hilo, pero realmente necesito saber cómo resolviste esto. Tengo FF funcionando pero no los navegadores IE / WebKit. Por favor ayuda cuando puedas.
Alfero Chingono el

2

Aquí hay un código que realmente funciona para IE y FF (al menos):

<html>
<head>
    <title>Test</title>
    <style type="text/css">
        table{
            width: 400px;
        }
        tbody {
            height: 100px;
            overflow: scroll;
        }
        div {
            height: 100px;
            width: 400px;
            position: relative;
        }
        tr.alt td {
            background-color: #EEEEEE;
        }
    </style>
    <!--[if IE]>
        <style type="text/css">
            div {
                overflow-y: scroll;
                overflow-x: hidden;
            }
            thead tr {
                position: absolute;
                top: expression(this.offsetParent.scrollTop);
            }
            tbody {
                height: auto;
            }
        </style>
    <![endif]--> 
</head>
<body>
    <div >
        <table border="0" cellspacing="0" cellpadding="0">
            <thead>
                <tr>
                    <th style="background: lightgreen;">user</th>
                    <th style="background: lightgreen;">email</th>
                    <th style="background: lightgreen;">id</th>
                    <th style="background: lightgreen;">Y/N</th>
                </tr>
            </thead>
            <tbody align="center">
                <!--[if IE]>
                    <tr>
                        <td colspan="4">on IE it's overridden by the header</td>
                    </tr>
                <![endif]--> 
                <tr>
                    <td>user 1</td>
                    <td>user@user.com</td>
                    <td>1</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 2</td>
                    <td>user@user.com</td>
                    <td>2</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 3</td>
                    <td>user@user.com</td>
                    <td>3</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 4</td>
                    <td>user@user.com</td>
                    <td>4</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 5</td>
                    <td>user@user.com</td>
                    <td>5</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 6</td>
                    <td>user@user.com</td>
                    <td>6</td>
                    <td>N</td>
                </tr>
                <tr>
                    <td>user 7</td>
                    <td>user@user.com</td>
                    <td>7</td>
                    <td>Y</td>
                </tr>
                <tr class="alt">
                    <td>user 8</td>
                    <td>user@user.com</td>
                    <td>8</td>
                    <td>N</td>
                </tr>
            </tbody>
        </table>
    </div>
</body></html>

He cambiado el código original para hacerlo más claro y también para que funcione bien en IE y también en FF.

Código original AQUÍ


1
En IE7 / 8 esto solo funciona en el modo Quirks, y deja de funcionar tan pronto como agregue un doctype, es decir<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
ccpizza

1

Aquí está mi alternativa. También usa diferentes DIV para el encabezado, el cuerpo y el pie de página, pero sincronizados para cambiar el tamaño de la ventana y con la búsqueda, desplazamiento, clasificación, filtrado y posicionamiento:

Mis listas de CD

Haga clic en los botones Jazz, Clásico ... para ver las tablas. Está configurado para que sea adecuado incluso si JavaScript está desactivado.

Parece correcto en IE, FF y WebKit (Chrome, Safari).


1

Lo siento, no he leído todas las respuestas a su pregunta.

Sí, aquí lo que quieres (ya lo he hecho)

Puede usar dos tablas, con el mismo nombre de clase para un estilo similar, una solo con el encabezado de la tabla y otra con sus filas. Ahora coloque esta tabla dentro de un div que tenga una altura fija con overflow-y: auto OR scroll.


1

El principal problema que tuve con las sugerencias anteriores fue poder conectar tablesorter.js Y poder flotar los encabezados para una tabla restringida a un tamaño máximo específico. Finalmente me topé con el complemento jQuery.floatThead que proporcionaba los encabezados flotantes y permitía que la clasificación continuara funcionando.

También tiene una buena página de comparación que se muestra frente a complementos similares .


1

Live JsFiddle

Es posible solo con HTML y CSS

table.scrollTable {
  border: 1px solid #963;
  width: 718px;
}

thead.fixedHeader {
  display: block;
}

thead.fixedHeader tr {
  height: 30px;
  background: #c96;
}

thead.fixedHeader tr th {
  border-right: 1px solid black;
}

tbody.scrollContent {
  display: block;
  height: 262px;
  overflow: auto;
}

tbody.scrollContent td {
  background: #eee;
  border-right: 1px solid black;
  height: 25px;
}

tbody.scrollContent tr.alternateRow td {
  background: #fff;
}

thead.fixedHeader th {
  width: 233px;
}

thead.fixedHeader th:last-child {
  width: 251px;
}

tbody.scrollContent td {
  width: 233px;
}
<table cellspacing="0" cellpadding="0" class="scrollTable">
  <thead class="fixedHeader">
    <tr class="alternateRow">
      <th>Header 1</th>
      <th>Header 2</th>
      <th>Header 3</th>
    </tr>
  </thead>
  <tbody class="scrollContent">
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>And Repeat 1</td>
      <td>And Repeat 2</td>
      <td>And Repeat 3</td>
    </tr>
    <tr class="normalRow">
      <td>Cell Content 1</td>
      <td>Cell Content 2</td>
      <td>Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>More Cell Content 1</td>
      <td>More Cell Content 2</td>
      <td>More Cell Content 3</td>
    </tr>
    <tr class="normalRow">
      <td>Even More Cell Content 1</td>
      <td>Even More Cell Content 2</td>
      <td>Even More Cell Content 3</td>
    </tr>
    <tr class="alternateRow">
      <td>End of Cell Content 1</td>
      <td>End of Cell Content 2</td>
      <td>End of Cell Content 3</td>
    </tr>
  </tbody>
</table>


0

Si está bien usar JavaScript aquí es mi solución Crear un conjunto de tablas de ancho fijo en todas las columnas (¡píxeles!) Agregue la clase Scrollify a la tabla y agregue esta altura de conjunto javascript + jquery 1.4.x en CSS o estilo.

Probado en: Opera, Chrome, Safari, FF, IE5.5 ( error de secuencia de comandos épica ), IE6, IE7, IE8, IE9

//Usage add Scrollify class to a table where all columns (header and body) have a fixed pixel width
$(document).ready(function () {
    $("table.Scrollify").each(function (index, element) {
        var header = $(element).children().children().first();
        var headerHtml = header.html();
        var width = $(element).outerWidth();
        var height = parseInt($(element).css("height")) - header.outerHeight();
        $(element).height("auto");
        header.remove();
        var html = "<table style=\"border-collapse: collapse;\" border=\"1\" rules=\"all\" cellspacing=\"0\"><tr>" + headerHtml +
                         "</tr></table><div style=\"overflow: auto;border:0;margin:0;padding:0;height:" + height + "px;width:" + (parseInt(width) + scrollbarWidth()) + "px;\">" +
                         $(element).parent().html() + "</div>";

        $(element).parent().html(html);
    });
});


//Function source: http://www.fleegix.org/articles/2006-05-30-getting-the-scrollbar-width-in-pixels
//License: Apache License, version 2
function scrollbarWidth() {
    var scr = null;
    var inn = null;
    var wNoScroll = 0;
    var wScroll = 0;

    // Outer scrolling div
    scr = document.createElement('div');
    scr.style.position = 'absolute';
    scr.style.top = '-1000px';
    scr.style.left = '-1000px';
    scr.style.width = '100px';
    scr.style.height = '50px';
    // Start with no scrollbar
    scr.style.overflow = 'hidden';

    // Inner content div
    inn = document.createElement('div');
    inn.style.width = '100%';
    inn.style.height = '200px';

    // Put the inner div in the scrolling div
    scr.appendChild(inn);
    // Append the scrolling div to the doc
    document.body.appendChild(scr);

    // Width of the inner div sans scrollbar
    wNoScroll = inn.offsetWidth;
    // Add the scrollbar
    scr.style.overflow = 'auto';
    // Width of the inner div width scrollbar
    wScroll = inn.offsetWidth;

    // Remove the scrolling div from the doc
    document.body.removeChild(
        document.body.lastChild);

    // Pixel width of the scroller
    return (wNoScroll - wScroll);
}

Editar: altura fija.


0

Hago esto con javascript (sin biblioteca) y CSS: el cuerpo de la tabla se desplaza con la página, y la tabla no tiene que tener un ancho o alto fijo, aunque cada columna debe tener un ancho.También puedes seguir ordenando la funcionalidad.

Básicamente:

  1. En HTML, cree divisiones de contenedor para colocar la fila del encabezado de la tabla y el cuerpo de la tabla, también cree una división de "máscara" para ocultar el cuerpo de la tabla a medida que se desplaza más allá del encabezado

  2. En CSS, convierta las partes de la tabla en bloques

  3. En Javascript, obtenga el ancho de la tabla y coincida con el ancho de la máscara ... obtenga la altura del contenido de la página ... mida la posición de desplazamiento ... manipule CSS para establecer la posición de la fila del encabezado de la tabla y la altura de la máscara

Aquí está el javascript y una DEMO jsFiddle.

// get table width and match the mask width

function setMaskWidth() { 
  if (document.getElementById('mask') !==null) {
    var tableWidth = document.getElementById('theTable').offsetWidth;

    // match elements to the table width
    document.getElementById('mask').style.width = tableWidth + "px";
   }
}

function fixTop() {

  // get height of page content 
  function getScrollY() {
      var y = 0;
      if( typeof ( window.pageYOffset ) == 'number' ) {
        y = window.pageYOffset;
      } else if ( document.body && ( document.body.scrollTop) ) {
        y = document.body.scrollTop;
      } else if ( document.documentElement && ( document.documentElement.scrollTop) ) {
        y = document.documentElement.scrollTop;
      }
      return [y];
  }  

  var y = getScrollY();
  var y = y[0];

  if (document.getElementById('mask') !==null) {
      document.getElementById('mask').style.height = y + "px" ;

      if (document.all && document.querySelector && !document.addEventListener) {
        document.styleSheets[1].rules[0].style.top = y + "px" ;
      } else {
        document.styleSheets[1].cssRules[0].style.top = y + "px" ;
      }
  }

}

window.onscroll = function() {
  setMaskWidth();
  fixTop();
}

Pero en su demo, el encabezado de la tabla no se queda, simplemente se desplaza hacia afuera. (Chrome aquí.)
Sz.

No estoy viendo eso en Chrome. ¿Estás seguro de que no estás confundiendo las celdas resaltadas en amarillo con las instrucciones en rojo para el encabezado? Las celdas del encabezado están en la parte superior y son de color gris sobre gris ("Col 1", "Col 2", etc.).
Deborah

0

Para mí, nada relacionado con el desplazamiento realmente funcionó hasta que eliminé el ancho de la tabla CSS. Originalmente, la tabla CSS se veía así:

.table-fill {
    background: white;
    border-radius:3px;
    border-collapse: collapse;
    margin: auto;
    width: 100%;
    max-width: 800px;
    padding:5px;
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
    animation: float 5s infinite;
}

Tan pronto como eliminé el ancho: 100%; Todas las funciones de desplazamiento comenzaron a funcionar.


0

Si tiene estándares lo suficientemente bajos;) podría colocar una tabla que contenga solo un encabezado directamente encima de una tabla que solo tenga un cuerpo. No se desplazará horizontalmente, pero si no necesitas eso ...

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.