設定したサイズを維持するためにHTMLテーブルが必要なページを書いています。テーブルの上部にあるヘッダーが常に表示されるようにする必要がありますが、テーブルに行がいくつ追加されても、テーブルの本体がスクロールする必要があります。Excelのミニバージョンを考えてください。これは簡単な作業のようですが、私がWebで見つけたほとんどすべてのソリューションにはいくつかの欠点があります。どうすればこれを解決できますか?
設定したサイズを維持するためにHTMLテーブルが必要なページを書いています。テーブルの上部にあるヘッダーが常に表示されるようにする必要がありますが、テーブルに行がいくつ追加されても、テーブルの本体がスクロールする必要があります。Excelのミニバージョンを考えてください。これは簡単な作業のようですが、私がWebで見つけたほとんどすべてのソリューションにはいくつかの欠点があります。どうすればこれを解決できますか?
回答:
私は同じ答えを見つけなければなりませんでした。私が見つけた最良の例は、http://www.cssplay.co.uk/menu/tablescroll.htmlです。例2がうまく機能していることがわかりました。JavaScriptで内部テーブルの高さを設定する必要があります。残りはCSSです。
DataTablesは非常に柔軟であることがわかりました。デフォルトのバージョンはjqueryに基づいていますが、AngularJsプラグインもあります。
Sean Haddy が同様の質問に対して優れた解決策を見つけ、自由に編集を加えました。
aria-hidden="false"
しかし、ショーンは重労働をやった。tfootをサポートする必要性を指摘してくれたMatt Burlandにも感謝します。
theadとtbodyを使用して、overflow:scrollでtbodyに固定の高さを設定してみましたか?
ターゲットブラウザは何ですか?
編集:それはFirefoxで(ほぼ)うまくいきました-垂直スクロールバーの追加は水平スクロールバーの必要性も引き起こしました-残念です。IEは、各tdの高さを、tbodyの高さを指定したものに設定しました。これが私が思いつくことができる最高のものです:
<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>
overflow-x: hidden;
そしてoverflow-y: auto
また助けます。
必要なものは:
1)コンテンツがスクロールウィンドウよりも大きい場合にのみスクロールが発生するため、テーブル本体の高さが制限されています。ただしtbody
、サイズを変更することはできませblock
ん。そのためには、として表示する必要があります。
tbody {
overflow-y: auto;
display: block;
max-height: 10em; // For example
}
2)テーブルヘッダーとテーブルボディの列幅を再同期化して、後者をblock
関連のない要素にしました。これを行う唯一の方法は、両方に同じ列幅を適用して同期をシミュレートすることです。
ただし、それtbody
自体がblock
今なので、のように動作することはできませんtable
。table
列を正しく表示するための動作がまだ必要なので、解決策は、各行を個別table
のとして表示するように要求することです。
thead {
display: table;
width: 100%; // Fill the containing table
}
tbody tr {
display: table;
width: 100%; // Fill the containing table
}
(この手法を使用すると、行をまたがることはできなくなります)。
ことが行われたら、両方で同じ幅を持つように列幅を強制することができますthead
し、tbody
。あなたはそれができませんでした:
th, td { width: 20%; }
たとえば、5つの列がある場合を介して)、これはより実用的です(各テーブルインスタンスに幅を設定する必要はありません)が、どの列数に対しても機能しません。私は追加が必要な最後のオプションを好みます:
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
}
編集: これは非常に古い答えであり、繁栄のためにここにあります。これは2000年代に一度サポートされたものの、2010年代のブラウザー戦略は、一部の機能が削除された場合でもW3C仕様を尊重することであったため、削除されました:固定ヘッダー付きのスクロール可能なテーブル/ footerはHTML5より前に不格好に指定されていました。
残念ながら、thead
/ が固定されたスクロール可能なテーブルを処理するための洗練された方法はありません。HTML/ CSS仕様は、その機能についてあまり明確でないtfoot
ためです。
が、HTML 4.01の仕様は言うthead
/ tfoot
/はtbody
(?導入)スクロールテーブル本体に使用されます。
THEAD、TFOOT、およびTBODY要素を使用して、テーブルの行をグループ化できます[...]。この分割により、ユーザーエージェントは、テーブルのヘッドとフットに関係なく、テーブルボディのスクロールをサポートできます。
ただし、FF 3.6で機能するスクロール可能なテーブル機能は、HTML / CSS仕様に準拠していないためバグと見なされたため、FF 3.7では削除されました。これと、 FFバグに関するコメントを参照してください。
以下は、スクロール可能なテーブルのMDNの便利なヒントの簡易バージョンです。
このアーカイブページまたは現在のフランス語バージョンを参照してください
<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>
しかし、MDNはこれがFFではもう機能しないと言っています :-(
IE8でもテストしました=>テーブルもスクロールできません:-((
まだ誰かがこれを見ているかどうかはわかりませんが、以前私がこれを行った方法は、2つのテーブルを使用して単一の元のテーブルを表示することです。最初のテーブルは元のテーブルタイトル行のみで、テーブルボディ行はありません(または空のボディ行を作成します)検証します)。
2つ目は別のdivにあり、タイトルはなく、元のテーブル本体の行だけがあります。その後、個別のdivがスクロール可能になります。
そのdivの2番目のテーブルは、HTMLの最初のテーブルのすぐ下に配置され、固定ヘッダーとスクロール可能な下部セクションを持つ単一のテーブルのように見えます。私はこれをSafari、Firefox、IE(2010年春のそれぞれの最新バージョン)でのみテストしましたが、すべてで動作しました。
唯一の問題は、最初のテーブルがボディなしでは検証されないこと(W3.orgバリデーター-XHTML 1.0 strict)であり、コンテンツのないものを追加すると、空白行が発生しました。CSSを使用してこれを非表示にすることができますが、それでもページのスペースを消費します。
display: none;
ソース内のスペースを意味するのでない限り、を使用する場合、画面スペースを占有する必要はありません。
このソリューションはChrome 35、Firefox 30、IE 11で動作します(他のバージョンではテストされていません)
その純粋なCSS:http : //jsfiddle.net/ffabreti/d4sope1u/
すべてがdisplay:blockに設定され、テーブルには高さが必要です:
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;
}
これは、私たちのアプリケーションにそのようなグリッドを実装しようとする巨大な頭痛の種となりました。いろいろなテクニックを試しましたが、それぞれに問題がありました。私が近づいたのはFlexigridなどのjQueryプラグインを使用することでしたが(これについてはhttp://www.ajaxrain.comを参照してください)、これは100%幅のテーブルをサポートしていないようです。
私がやったことは、自分で転がすことでした。Firefoxはスクロールtbody
要素をサポートしているので、ブラウザーはスニッフィングし、適切なCSS(高さの設定、オーバーフローなど...詳細を確認する)を使用してスクロールし、他のブラウザーtable-layout: fixed
では、サイズ設定を使用する2つの個別のテーブルセットを使用しました指定されたサイズをオーバーフローしないことが保証されているアルゴリズム(通常のテーブルは、コンテンツが広すぎて収まらない場合に拡張されます)。両方のテーブルに同じ幅を与えることで、列を揃えることができました。スクロールするdivセットに2つ目をラップし、余白などのちょっとしたジグザリーポケリーを使用して、希望どおりのルックアンドフィールを得ることができました。
この回答が場所によって少し曖昧に聞こえる場合は申し訳ありません。時間がないので書いています。これ以上拡大したい場合は、コメントを残してください!
以下は、IEとFFで実際に機能するコードです(少なくとも)。
<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>
元のコードを変更して、わかりやすくし、IEとFFでも正常に機能するようにしました。
元のコードはこちら
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
上記の提案で私が抱えていた主な問題は、tablesorter.jsをプラグインできることと、特定の最大サイズに制限されたテーブルのヘッダーをフロートできることでした。結局、フローティングヘッダーを提供し、並べ替えが機能し続けるプラグインjQuery.floatTheadを見つけました。
ライブJsFiddle
HTMLと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>
ここでJavaScriptを使用しても問題ない場合は、すべての列(ピクセル!)にテーブルセット固定幅を作成します。Scrollifyクラスをテーブルに追加し、このJavaScript + jquery 1.4.xの高さをCSSまたはスタイルで追加します。
テスト済み:Opera、Chrome、Safari、FF、IE5.5(Epic script fail)、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);
}
編集:固定高さ。
私はこれをjavascript(ライブラリなし)とCSSで行います-テーブル本体はページと共にスクロールし、テーブルは幅や高さを固定する必要はありませんが、各列には幅が必要です。並べ替え機能を維持することもできます。
基本的に:
HTMLでは、コンテナーdivを作成して、テーブルヘッダー行とテーブルボディを配置します。また、「マスク」divを作成して、ヘッダーを超えてスクロールするときにテーブルボディを非表示にします
CSSで、テーブルパーツをブロックに変換します
JavaScriptでは、テーブルの幅を取得し、マスクの幅と一致させます...ページコンテンツの高さを取得します...スクロール位置を測定します... CSSを操作してテーブルヘッダーの行位置とマスクの高さを設定します
これがJavaScriptと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();
}
私にとって、テーブルCSSから幅を削除するまで、スクロールに関連することは何も実際には機能しませんでした。当初、CSSテーブルは次のようになっています。
.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;
}
幅を削除するとすぐに、100%; すべてのスクロール機能が機能し始めました。