Tableのヘッダ固定を行うCSS & JQuery

System Lock By: Yuri Samoilov
テーブルの行列のヘッダ固定は、業務系のWebアプリでかなりの需要があるのですが、実際に実装しようとするとかなり面倒な機能の一つです。
今回は、CSSやjQuery、jQueryプラグインを使うヘッダ固定の方法を3種類紹介します。
- Internet Explorer 9 / 10 / 11
- Firefox 29
- Google Chrome 34
- Safari 5
- Opera 12
サンプルとして使用するテーブル
ヘッダ固定の方法を紹介する前に、今回サンプルとして使用するテーブルのHTMLとCSSを紹介します。以降はこのテーブルを使用してヘッダ固定の方法を紹介します。
TableHeader1 | TableHeader2 | TableHeader3 | TableHeader4 |
---|---|---|---|
Contents1 | Contents2 | Contents3 | Contents4 |
Contents5 | Contents6 | Contents7 | Contents8 |
Contents9 | Contents10 | Contents11 | Contents12 |
<table class="table-design tablelock1"> <thead> <tr> <th>TableHeader1</th><th>TableHeader2</th> <th>TableHeader3</th><th>TableHeader4</th> </tr> </thead> <tbody> <tr> <td>Contents1</td><td>Contents2</td> <td>Contents3</td><td>Contents4</td> </tr> <tr> <td>Contents5</td><td>Contents6</td> <td>Contents7</td><td>Contents8</td> </tr> <tr> <td>Contents9</td><td>Contents10</td> <td>Contents11</td><td>Contents12</td> </tr> </tbody> </table>
/* テーブルのデザイン */ .table-design{ border-collapse: collapse; border: 1px solid #666; text-align: center; vertical-align: middle; margin-bottom:30px; } .table-design th{ background: #ccc; border:1px solid #aaa; padding:25px 5px; } .table-design td{ border:1px solid #aaa; padding:25px 5px; }
CSSのみでヘッダを固定する方法
TableHeader1 | TableHeader2 | TableHeader3 | TableHeader4 |
---|---|---|---|
Contents1 | Contents2 | Contents3 | Contents4 |
Contents5 | Contents6 | Contents7 | Contents8 |
Contents9 | Contents10 | Contents11 | Contents12 |
/* ヘッダ固定のCSS */ .tablelock1 thead{ display:block; width:482px; /* 500px - スクロールバー */ } .tablelock1 tbody{ overflow-x: hidden; overflow-y: auto; -ms-overflow-x: hidden; -ms-overflow-y: auto; position: absolute; display:block; height: 100px; width:500px; } .tablelock1 th ,.tablelock1 td { width: 110px; }
theadとtbodyをblock化してヘッダ固定する方法です。
thead・tbodyともwidthを指定する必要があるのですが、paddingやborder分のピクセル数を考慮する必要があるため、作成後にwidthを微調整が必要となります。
また、ボディ部に対して「position: absolute;」を掛けているため位置計算に不具合が発生しtableの下の要素が重なって表示されます。そのためtebleの下に「<div style=”height:●●px”></div>」を入れて擬似的に重ならないようにする必要があります。
jQueryを使いヘッダを固定する方法
TableHeader1 | TableHeader2 | TableHeader3 | TableHeader4 |
---|---|---|---|
Contents1 | Contents2 | Contents3 | Contents4 |
Contents5 | Contents6 | Contents7 | Contents8 |
Contents9 | Contents10 | Contents11 | Contents12 |
(function($){ $(function(){ // スクロールが発生した時に処理を行う $(window).scroll(function () { var $table = $(".tablelock2"); // テーブルの要素を取得 var $thead = $table.children("thead"); // thead取得 var toffset = $table.offset(); // テーブルの位置情報取得 // テーブル位置+テーブル縦幅 < スクロール位置 < テーブル位置 if(toffset.top + $table.height()< $(window).scrollTop() || toffset.top > $(window).scrollTop()){ // クローンテーブルが存在する場合は消す var $clone = $("#clonetable"); if($clone.length > 0){ $clone.css("display", "none"); } } // テーブル位置 < スクロール位置 < テーブル位置+テーブル縦幅 else if(toffset.top < $(window).scrollTop()){ // クローンテーブルが存在するか確認 var $clone = $("#clonetable"); if($clone.length == 0){ // 存在しない場合は、theadのクローンを作成 $clone= $thead.clone(true); // idをclonetableとする $clone.attr("id", "clonetable"); // body部に要素を追加 $clone.appendTo("body"); // theadのCSSをコピーする StyleCopy($clone, $thead); // theadの子要素(tr)分ループさせる for(var i = 0; i < $thead.children("tr").length; i++) { // i番目のtrを取得 var $theadtr = $thead.children("tr").eq(i); var $clonetr = $clone.children("tr").eq(i); // trの子要素(th)分ループさせる for (var j = 0; j < $theadtr.eq(i).children("th").length; j++){ // j番目のthを取得 var $theadth = $theadtr.eq(i).children("th").eq(j); var $cloneth = $clonetr.eq(i).children("th").eq(j); // thのCSSをコピーする StyleCopy($cloneth, $theadth); } } } // コピーしたtheadの表示形式をtableに変更 $clone.css("display", "table"); // positionをブラウザに対し絶対値とする $clone.css("position", "fixed"); $clone.css("border-collapse", "collapse"); // positionの位置を設定(left = 元のテーブルのleftとする) $clone.css("left", toffset.left - $(window).scrollLeft()); // positionの位置を設定(topをブラウザの一番上とする) $clone.css("top", "0px"); // 表示順番を一番優先させる $clone.css("z-index", 99); } }); // CSSのコピー function StyleCopy($copyTo, $copyFrom){ $copyTo.css("width", $copyFrom.css("width")); $copyTo.css("height", $copyFrom.css("height")); $copyTo.css("padding-top", $copyFrom.css("padding-top")); $copyTo.css("padding-left", $copyFrom.css("padding-left")); $copyTo.css("padding-bottom", $copyFrom.css("padding-bottom")); $copyTo.css("padding-right", $copyFrom.css("padding-right")); $copyTo.css("background", $copyFrom.css("background")); $copyTo.css("background-color", $copyFrom.css("background-color")); $copyTo.css("vertical-align", $copyFrom.css("vertical-align")); $copyTo.css("border-top-width", $copyFrom.css("border-top-width")); $copyTo.css("border-top-color", $copyFrom.css("border-top-color")); $copyTo.css("border-top-style", $copyFrom.css("border-top-style")); $copyTo.css("border-left-width", $copyFrom.css("border-left-width")); $copyTo.css("border-left-color", $copyFrom.css("border-left-color")); $copyTo.css("border-left-style", $copyFrom.css("border-left-style")); $copyTo.css("border-right-width", $copyFrom.css("border-right-width")); $copyTo.css("border-right-color", $copyFrom.css("border-right-color")); $copyTo.css("border-right-style", $copyFrom.css("border-right-style")); $copyTo.css("border-bottom-width", $copyFrom.css("border-bottom-width")); $copyTo.css("border-bottom-color", $copyFrom.css("border-bottom-color")); $copyTo.css("border-bottom-style", $copyFrom.css("border-bottom-style")); } }); })(jQuery);
ヘッダ固定用のCSSは不要になるように、widthやheightなどは元のテーブルから自動取得しクローン要素にコピーするようにしました。
ただし、全てのスタイルに対応しているわけでは無く、「StyleCopy()」関数に記載していないスタイルは未対応です。
プラグインを使いヘッダを固定する方法
TableHeader1 | TableHeader2 | TableHeader3 | TableHeader4 |
---|---|---|---|
Contents1 | Contents2 | Contents3 | Contents4 |
Contents5 | Contents6 | Contents7 | Contents8 |
Contents9 | Contents10 | Contents11 | Contents12 |
.tablelock3 td ,.tablelock3 th{ width:110px; }
(function($){ $(function(){ $('.tablelock5').tbodyScroll({ thead_height: '70px', tbody_height: '70px', tfoot_height: '20px', head_bgcolor: 'transparent', foot_bgcolor: 'transparent' }); }); })(jQuery);
ヘッダのみでなく、フッタも固定が可能なプラグイン。
ソース自体も上記の通り、サイズと色を指定するだけで利用できるシンプルなプラグインですが「th」「td」タグに対してwidthを指定して置かないとレイアウトが崩れてしまうため注意が必要です。
Related Posts

« Webで文章を書くときに最初にやっておくCSSの設定 jQueryのバージョンを複数同時に使用する方法 »
Trackback URL
http://webnonotes.com/css/table-header/trackback/No Comments Yet