with tbody left first example column bootstrap and html css3 html-table markup fixed-header-tables

html - tbody - Tabla con encabezado fijo y columna fija en css puro



table header fixed bootstrap (16)

Necesito crear una tabla html (o algo parecido) con un encabezado fijo y una primera columna fija.

Cada solución que he visto hasta ahora usa Javascript o jQuery para establecer scrollTop / scrollLeft, pero no funciona sin problemas en los navegadores móviles, entonces estoy buscando una solución pura de CSS.

Encontré una solución para una columna fija aquí: jsfiddle.net/C8Dtf/20/ pero no sé cómo puedo mejorarla para que también se jsfiddle.net/C8Dtf/20/ el encabezado.

Quiero que funcione en navegadores webkit o use algunas funciones css3 , pero repito, no quiero usar Javascript para desplazarme.

EDITAR: Este es un ejemplo del comportamiento que quiero lograr: http://datatables.net/release-datatables/extras/FixedColumns/css_size.html


Una solución CSS pura real con una fila de encabezado fijo y primera columna

Tuve que crear una tabla con un encabezado fijo y una primera columna fija usando CSS puro y ninguna de las respuestas aquí era exactamente lo que quería.

La propiedad de position: sticky admite que ambos se adhieran a la parte superior (como he visto que se usa más) y al costado en las versiones modernas de Chrome, Firefox y Edge. Esto se puede combinar con un div que tiene el overflow: scroll propiedad de overflow: scroll para darle una tabla con encabezados fijos que se pueden colocar en cualquier lugar de la página:

Coloque su mesa en un contenedor:

<div class="container"> <table></table> </div>

Usar desbordamiento: desplácese en su contenedor para habilitar el desplazamiento:

div.container { overflow: scroll; }

position: sticky uso position: sticky para que se adhiera al borde y a la top , right o left para elegir a qué borde adherirse:

thead th { position: sticky; top: 0; } tbody th { position: sticky; left: 0; }

Para que el encabezado de la primera columna se adhiera a la izquierda, use:

thead th:first-child { left: 0; z-index: 1; }

/* Use overflow:scroll on your container to enable scrolling: */ div { max-width: 400px; max-height: 150px; overflow: scroll; } /* Use position: sticky to have it stick to the edge * and top, right, or left to choose which edge to stick to: */ thead th { position: sticky; top: 0; } tbody th { position: sticky; left: 0; } /* To have the header in the first column stick to the left: */ thead th:first-child { left: 0; z-index: 1; } /* Just to display it nicely: */ thead th { background: #000; color: #FFF; } tbody th { background: #FFF; border-right: 1px solid #CCC; } table { border-collapse: collapse; } td, th { padding: 0.5em; }

<div> <table> <thead> <tr> <th></th> <th>headheadhead</th> <th>headheadhead</th> <th>headheadhead</th> <th>headheadhead</th> <th>headheadhead</th> <th>headheadhead</th> <th>headheadhead</th> </tr> </thead> <tbody> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> <tr> <th>head</th> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> <td>body</td> </tr> </tbody> </table> </div>

https://jsfiddle.net/wvypo83c/1/


Ejemplo puro de CSS:

<div id="cntnr"> <div class="tableHeader"> <table class="table-header table table-striped table-bordered"> <thead> <tr> <th>this</th> <th>transmission</th> <th>is</th> <th>coming</th> <th>to</th> <th>you</th> </tr> </thead> <tbody> <tr> <td>we''ve got it...</td> <td>alright you are go</td> <td>uh, we see the Earth now</td> <td>we''ve got it...</td> <td>alright you are go</td> <td>uh, we see the Earth now</td> </tr> </tbody> </table> </div> <div class="tableBody"> <table class="table-body table table-striped table-bordered"> <thead> <tr> <th>this</th> <th>transmission</th> <th>is</th> <th>coming</th> <th>to</th> <th>you</th> </tr> </thead> <tbody> <tr> <td>we''ve got it...</td> <td>alright you are go</td> <td>uh, we see the Earth now</td> <td>we''ve got it...</td> <td>alright you are go</td> <td>uh, we see the Earth now</td> </tr> </tbody> </table> </div> </div> #cntnr { width: auto; height: 200px; border: solid 1px #444; overflow: auto; } .tableHeader { position: fixed; height: 40px; overflow: hidden; margin-right: 18px; background: white; } .table-header tbody { height: 0; visibility: hidden; } .table-body thead { height: 0; visibility: hidden; }

http://jsfiddle.net/cCarlson/L98m854d/

Desventaja: la estructura / lógica del encabezado fijo depende bastante de las dimensiones específicas, por lo que la abstracción probablemente no sea una opción viable .


Ahora un día, esto es posible lograr usando CSS solo con la position: sticky propiedad position: sticky .

Aquí va un fragmento:

(jsFiddle: https://jsfiddle.net/hbqzdzdt/5/ )

.grid-container { display: grid; /* This is a (hacky) way to make the .grid element size to fit its content */ overflow: auto; height: 300px; width: 600px; } .grid { display: flex; flex-wrap: nowrap; } .grid-col { width: 150px; min-width: 150px; } .grid-item--header { height: 100px; min-height: 100px; position: sticky; position: -webkit-sticky; background: white; top: 0; } .grid-col--fixed-left { position: sticky; left: 0; z-index: 9998; background: white; } .grid-col--fixed-right { position: sticky; right: 0; z-index: 9998; background: white; } .grid-item { height: 50px; border: 1px solid gray; }

<div class="grid-container"> <div class="grid"> <div class="grid-col grid-col--fixed-left"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> <div class="grid-item"> <p>Hello</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> <div class="grid-item"> <p>P</p> </div> </div> <div class="grid-col grid-col--fixed-right"> <div class="grid-item grid-item--header"> <p>HEAD</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> <div class="grid-item"> <p>9</p> </div> </div> </div> </div>

Respecto a la compatibilidad. Funciona en todos los navegadores principales, pero no en IE. Hay un polyfill para position: sticky pero nunca lo intenté.


Algo como esto puede funcionar para usted ... Probablemente requerirá que haya establecido el ancho de columna para su fila de encabezado.

thead { position: fixed; }

http://jsfiddle.net/vkhNC/

Actualizar:

No estoy convencido de que el ejemplo que dio sea posible solo con CSS. Me encantaría que alguien me probara mal. Esto es lo que tengo hasta ahora . No es el producto terminado, pero podría ser un comienzo para ti. Espero que esto te indique una dirección útil, donde sea que sea.



Después de dos días luchando con Internet Explorer 9 + Chrome + Firefox (Windows) y Safari (Mac), he encontrado un sistema que es

  • Compatible con todos estos navegadores
  • Sin usar javascript
  • Usando solo une div y una tabla
  • Se corrigió el encabezado y el pie de página (Excepto para IE), con cuerpo desplazable. Encabezado y cuerpo con anchos de columna iguales

Resultado:

HTML:

<thead> <tr> <th class="nombre"><%= f.label :cost_center %></th> <th class="cabecera cc">Personal</th> <th class="cabecera cc">Dpto</th> </tr> </thead> <tbody> <% @cost_centers.each do |cc| %> <tr> <td class="nombre"><%= cc.nombre_corto %></td> <td class="cc"><%= cc.cacentrocoste %></td> <td class="cc"><%= cc.cacentrocoste_dpto %></td> </tr> <% end %> </tbody> <tfoot> <tr> <td colspan="3"><a href="#">Mostrar mas usuarios</a></td> </tr> </tfoot> </table>

CSS:

div.cost_center{ width:320px; font-size:75%; margin-left:5px; margin-top:5px; margin-bottom: 2px; float: right; display: inline-block; overflow-y: auto; overflow-x: hidden; max-height:300px; } div.cost_center label { float:none; font-size:14px; } div.cost_center table{ width:300px; border-collapse: collapse; float:right; table-layout:fixed; } div.cost_center table tr{ height:16px; } div.cost_center th{ font-weight:normal; } div.cost_center table tbody{ display: block; overflow: auto; max-height:240px; } div.cost_center table thead{ display:block; } div.cost_center table tfoot{ display:block; } div.cost_center table tfoot td{ width:280px; } div.cost_center .cc{ width:60px; text-align: center; border: 1px solid #999; } div.cost_center .nombre{ width:150px; } div.cost_center tbody .nombre{ border: 1px solid #999; } div.cost_center table tfoot td{ text-align:center; border: 1px solid #999; } div.cost_center table th, div.cost_center table td { padding: 2px; vertical-align: middle; } div.cost_center table tbody td { white-space: normal; font: .8em/1.4em Verdana, sans-serif; color: #000; background-color: white; } div.cost_center table th.cabecera { font: 0.8em/1.4em Verdana, sans-serif; color: #000; background-color: #FFEAB5; }


He hecho algunos cambios en jsfiddle. Esto podría ser lo que estás tratando de hacer.

http://jsfiddle.net/C8Dtf/81/

He codificado los títulos así:

<table id="left_table" class="freeze_table"> <tr class=''tblTitle''> <th>Title 1</th> <th>Title 2</th> </tr> </table>

Y agregué algunos estilos también.

.tblTitle{ position:absolute; top:0px; margin-bottom:30px; background:lightblue; } td, th{ padding:5px; height:40px; width:40px; font-size:14px; }

Espero que esto es lo que quieres :)


Otra solución es usar AngularJS. El módulo AngularUI tiene una directiva llamada ng-grid que admite una función llamada fijación de columnas. No es CSS 100% puro, pero tampoco lo son las otras soluciones.

http://angular-ui.github.io/ng-grid/#columnPinning



Recientemente tuve que crear una solución con un grupo de encabezado fijo y una primera columna fija. Dividí mi tabla en div''s y usé jquery para capturar el desplazamiento de la ventana.

http://jsfiddle.net/TinT/EzXub/2346/

var prevTop = 0; var prevLeft = 0; $(window).scroll(function(event){ var currentTop = $(this).scrollTop(); var currentLeft = $(this).scrollLeft(); if(prevLeft !== currentLeft) { prevLeft = currentLeft; $(''.header'').css({''left'': -$(this).scrollLeft()}) } if(prevTop !== currentTop) { prevTop = currentTop; $(''.leftCol'').css({''top'': -$(this).scrollTop() + 40}) } });


Si solo quieres usar HTML puro y CSS, tengo una solución para tu problema:
En este jsFiddle puede ver una solución que no es de script que proporciona una tabla con un encabezado fijo. No debería ser un problema adaptar el marcado para una primera columna fija también. Solo necesita crear una tabla de posición absoluta para la primera columna dentro de hWrapper -div y reposicionar vWrapper -div.
Proporcionar contenido dinámico no debería ser un problema al usar motores tentadores del lado del servidor o del lado del navegador, mi solución funciona bien en todos los navegadores modernos y navegadores anteriores desde IE8 en adelante.


Solo necesito cambiar el estilo como

<table style="position: relative;"> <thead> <thead> <tr> <th></th> </tr> </thead> </thead> <tbody style="position: absolute;height: 300px;overflow:auto;"> <tr> <td></td> </tr> </tbody> </table>

Demostración: https://plnkr.co/edit/Qxy5RMJBXmkaJAOjBtQn?p=preview


Todas estas sugerencias son geniales y todas, pero solo están solucionando el encabezado o una columna, no ambas, o están usando javascript. La razón: no cree que se pueda hacer en CSS puro. La razón:

Si fuera posible, necesitaría anidar varios divs desplazables uno dentro del otro, cada uno con un desplazamiento en una dirección diferente. Entonces necesitarías dividir tu tabla en tres partes: el encabezado fijo, la columna fija y el resto de los datos.

Multa. Pero ahora el problema es que puede hacer que uno de ellos permanezca fijo cuando se desplaza, pero el otro está anidado dentro del área de desplazamiento primero y, por lo tanto, está sujeto a desplazarse fuera de la vista, por lo que no se puede fijar en su lugar. la pantalla. ''Ah-ha'' dices ''pero de alguna manera puedo usar la posición absoluta o fija para hacer eso'' - no, no puedes. Tan pronto como lo haga, perderá la capacidad de desplazarse por ese contenedor. Es una situación de gallina y huevo: no puedes tener ambas cosas, se anulan mutuamente.

Creo que la única solución es a través de javascript. Necesita separar por completo los tres elementos y mantener sus posiciones sincronizados a través de javascript. Hay buenos ejemplos en otras publicaciones en esta página. También vale la pena echar un vistazo a este:

http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/


Un compañero de trabajo y acabo de lanzar un nuevo proyecto GitHub que proporciona una directiva angular que puede usar para decorar su tabla con encabezados fijos: https://github.com/objectcomputing/FixedHeader

Se basa en css y angular solamente, con una directiva que agrega algunos divs. No se requiere jQuery.

Esta implementación no es tan completa como algunas otras implementaciones, pero si su necesidad es simplemente agregar tablas fijas, creemos que esta podría ser una buena opción.


Un ejemplo que usa solo CSS:

.table { table-layout: fixed; width: 500px; border-collapse: collapse; } .header th { font-family: Calibri; font-size: small; font-weight: lighter; border-left: 1px solid #000; background: #d0d0d0; } .body_panel { display: inline-block; width: 520px; height: 300px; overflow-y: scroll; } .body tr { border-bottom: 1px solid #d0d0d0; } .body td { border-left: 1px solid #d0d0d0; padding-left: 3px; font-family: Calibri; font-size: small; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

<body> <table class="table"> <thead class="header"> <tr> <th style="width:20%;">teste</th> <th style="width:30%;">teste 2</th> <th style="width:50%;">teste 3</th> </tr> </thead> </table> <div class="body_panel"> <table class="table"> <tbody class="body"> <tr> <td style="width:20%;">asbkj k kajsb ksb kabkb</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> <tr> <td style="width:20%;">2</td> <td style="width:30%;">2</td> <td style="width:50%;">3</td> </tr> </tbody> </table> </div> </body>


Esto no es tarea fácil.

El siguiente enlace es para una demostración en funcionamiento:

Enlace actualizado según el comentario de lanoxx

http://jsfiddle.net/C8Dtf/366/

Solo recuerda agregar estos:

<script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.js"></script> <script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js"></script> <script type="text/javascript" charset="utf-8" src="http://datatables.net/release-datatables/extras/FixedColumns/media/js/FixedColumns.js"></script>

no veo otra forma de lograr esto. Especialmente no usando css solamente.

Esto es mucho por lo que pasar. Espero que esto ayude :)