Table avec en-tête fixe et colonne fixe en pure css
J'ai besoin de créer une table HTML (ou quelque chose de similaire) avec un en-tête fixe et une première colonne fixe.
Toutes les solutions que j'ai vues jusqu'à présent utilisent Javascript ou jQuery
pour définir scrollTop/scrollLeft, mais cela ne fonctionne pas correctement sur les navigateurs mobiles. Je recherche donc une solution CSS pure.
J'ai trouvé une solution pour une colonne fixe ici: jsfiddle.net/C8Dtf/20/ mais je ne sais pas comment l'améliorer pour que l'en-tête soit également corrigé.
Je veux que cela fonctionne sur les navigateurs Webkit ou utilise certaines fonctionnalités de css3
, mais je le répète, je ne veux pas utiliser Javascript
pour le défilement.
EDIT: Ceci est un exemple du comportement que je souhaite obtenir: https://web.archive.org/web/20130829032141/http://datatables.net/release-datatables/extras/FixedColumns/css_size .html
Une solution CSS pure avec une en-tête et une première colonne fixes
Je devais créer un tableau avec à la fois un en-tête fixe et une première colonne fixe utilisant du CSS pur et aucune des réponses ici ne correspondait exactement à ce que je voulais.
La propriété position: sticky
prend en charge à la fois le sommet (comme je l'ai vu le plus souvent utilisé) et le côté des versions modernes de Chrome, Firefox et Edge. Cela peut être combiné avec une div
qui a la propriété overflow: scroll
pour vous donner un tableau avec des en-têtes fixes qui peuvent être placés n'importe où sur votre page:
Placez votre table dans un récipient:
<div class="container">
<table></table>
</div>
Utiliser débordement: faites défiler votre conteneur pour activer le défilement:
div.container {
overflow: scroll;
}
Utilisez position: sticky
pour que les cellules du tableau collent sur le bord et top
, right
ou left
pour choisir le bord auquel vous souhaitez coller:
thead th {
position: -webkit-sticky; /* for Safari */
position: sticky;
top: 0;
}
tbody th {
position: -webkit-sticky; /* for Safari */
position: sticky;
left: 0;
}
Pour que l'en-tête de la première colonne reste à gauche, utilisez:
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: -webkit-sticky; /* for Safari */
position: sticky;
top: 0;
}
tbody th {
position: -webkit-sticky; /* for Safari */
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>
Cela fait maintenant quelques jours que est possible à utiliser avec CSS uniquement avec la propriété position: sticky
.
Voici un extrait:
(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>
En ce qui concerne la compatibilité. Cela fonctionne dans tous les principaux navigateurs, mais pas dans IE. Il y a un polyfill pour position: sticky
mais je ne l'ai jamais essayé.
Ce n'est pas un exploit facile.
Le lien suivant est une démo de travail:
Link Mis à jour en fonction du commentaire de lanoxx
http://jsfiddle.net/C8Dtf/366/
Rappelez-vous simplement d’ajouter:
<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>
je ne vois pas d'autre moyen d'y parvenir. Surtout pas en utilisant css seulement.
C'est beaucoup à traverser. J'espère que cela t'aides :)
Toutes ces suggestions sont excellentes, mais elles ne corrigent que l'en-tête ou la colonne, pas les deux, ou utilisent javascript. La raison - il ne croit pas que cela puisse être fait en CSS pur. La raison:
Si cela était possible, vous auriez besoin d'imbriquer plusieurs divs défilables les uns dans les autres, chacun avec un parchemin dans une direction différente. Ensuite, vous devez diviser votre tableau en trois parties: l'en-tête fixe, la colonne fixe et le reste des données.
Bien. Mais maintenant, le problème - vous pouvez faire en sorte que l’un d’eux reste immobile lorsque vous faites défiler, mais l’autre est imbriqué dans la zone de défilement de la première et est donc susceptible de défiler à l’écran lui-même. l'écran. 'Ah-ha' tu dis 'mais je peux d'une manière ou d'une autre utiliser une position absolue ou fixe pour le faire' - non tu ne peux pas. Dès que vous faites cela, vous perdez la possibilité de faire défiler ce conteneur. C'est une situation de poulet et d'oeufs - vous ne pouvez pas avoir les deux, ils s'annulent.
Je crois que la seule solution est javascript. Vous devez séparer complètement les trois éléments et garder leurs positions synchronisées via javascript. Il y a de bons exemples dans d'autres articles sur cette page. Celui-ci vaut également le coup d'oeil:
http://tympanus.net/codrops/2014/01/09/sticky-table-headers-columns/
Un exemple utilisant uniquement 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>
J'ai fait quelques changements dans jsfiddle. C'est peut-être ce que vous essayez de faire.
J'ai codé les titres comme suit:
<table id="left_table" class="freeze_table">
<tr class='tblTitle'>
<th>Title 1</th>
<th>Title 2</th>
</tr>
</table>
Et j'ai ajouté quelques styles aussi.
.tblTitle{
position:absolute;
top:0px;
margin-bottom:30px;
background:lightblue;
}
td, th{
padding:5px;
height:40px;
width:40px;
font-size:14px;
}
J'espère que c'est ce que tu veux :)
Pour corriger les en-têtes et les colonnes, j'ai trouvé ces plugins:
J'espère que cette aide! :-)
J'ai récemment dû créer une solution avec un groupe d'en-tête fixe et une première colonne fixe. Je divisais ma table en div et utilisais jquery pour capturer le défilement de fenêtre.
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})
}
});
Après deux jours de lutte avec Internet Explorer 9 + Chrome + Firefox (Windows) et Safari (Mac), j'ai trouvé un système qui
- Compatible avec tous ces navigateurs
- Sans utiliser javascript
- Utiliser seulement une div et une table
- En-tête et pied de page fixes (sauf pour IE), avec corps déroulant. En-tête et corps avec les mêmes largeurs de colonne
Résultat:
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;
}
Quelque chose comme cela peut fonctionner pour vous… Cela nécessitera probablement que vous définissiez des largeurs de colonne pour la ligne d'en-tête.
thead {
position: fixed;
}
Mettre à jour:
Je ne suis pas convaincu que l'exemple que vous avez donné soit possible uniquement avec CSS. J'aimerais que quelqu'un me prouve le contraire. Voici ce que j'ai jusqu'à présent . Ce n'est pas le produit fini, mais cela pourrait être un début pour vous. J'espère que cela vous oriente dans une direction utile, où que ce soit.
Un collègue et moi venons de publier un nouveau projet GitHub qui fournit une directive angulaire que vous pouvez utiliser pour décorer votre table avec des en-têtes fixes: https://github.com/objectcomputing/FixedHeader
Il repose uniquement sur css et angular, avec une directive qui ajoute quelques divs. Il n'y a aucun jQuery requis.
Cette implémentation n'est pas aussi complète que d'autres implémentations, mais si vous souhaitez simplement ajouter des tables fixes, nous pensons que cela pourrait être une bonne option.
Paul O'Brien a trouvé une excellente solution au problème et je voudrais partager le lien suivant: https://codepen.io/paulobrien/pen/LBrMxa
J'ai enlevé le style pour le pied de page:
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
.intro {
max-width: 1280px;
margin: 1em auto;
}
.table-scroll {
position: relative;
width:100%;
z-index: 1;
margin: auto;
overflow: auto;
height: 350px;
}
.table-scroll table {
width: 100%;
min-width: 1280px;
margin: auto;
border-collapse: separate;
border-spacing: 0;
}
.table-wrap {
position: relative;
}
.table-scroll th,
.table-scroll td {
padding: 5px 10px;
border: 1px solid #000;
}
.table-scroll thead th {
position: -webkit-sticky;
position: sticky;
top: 0;
}
th:first-child {
position: -webkit-sticky;
position: sticky;
left: 0;
z-index: 2;
background: #ccc;
}
thead th:first-child {
z-index: 5;
}
/* 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: -webkit-sticky; /* for Safari */
position: sticky;
top: 0;
}
tbody th {
position: -webkit-sticky; /* for Safari */
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>
besoin de réparer le pied de page en-tête
Une autre solution consiste à utiliser AngularJS. Le module AngularUI a une directive appelée ng-grid
qui prend en charge une fonctionnalité appelée épinglage de colonne. Ce n'est pas 100% pur CSS, mais les autres solutions ne le sont pas non plus.
Position: sticky ne fonctionne pas pour certains éléments tels que (thead) dans chrome et pour d'autres navigateurs web tels que safari.
Mais ça marche bien avec (th)
Visitez mon exemple de code: <https://codepen.io/yogavicky/pen/QReepb>
Exemple de CSS pur:
<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/
Inconvénient: La structure/logique d'en-tête fixe dépend assez bien de dimensions spécifiques. Abstraction n'est donc probablement pas une option viable.
Les réponses existantes conviendront à la plupart des gens, mais pour ceux qui cherchent à ajouter shadows sous l'en-tête fixe et à la droite de la première colonne (fixe), voici un exemple de travail (css pur):
http://jsbin.com/nayifepaxo/1/edit?html,output
Pour que cela fonctionne correctement, l’astuce consiste à utiliser ::after
pour ajouter des ombres à droite de chacune des premières td
de chaque tr
:
tr td:first-child:after {
box-shadow: 15px 0 15px -15px rgba(0, 0, 0, 0.05) inset;
content: "";
position:absolute;
top:0;
bottom:0;
right:-15px;
width:15px;
}
Il m'a fallu un peu de temps (trop longtemps ...) pour que tout fonctionne, alors je me suis dit que je partagerais avec ceux qui se trouvent dans une situation similaire.