2012年3月2日金曜日

css3のelement関数を使ってテーブルの列を固定する(但し限定的)

※この記事は将来的に使えなくなる可能性があります.また現状firefox(しかも比較的新しめの)でしか使えません.
→css4に延期となったようですorz...
excelのカメラ機能のように応用次第で様々な可能性を秘めているとも言えるのですが,どうやら不確定要素が多すぎといった所なんでしょうか.ちょっぴり残念.

css3のedtor's draftを見ていたら,背景画像にelement関数を使うことが出来るとの記述を発見.
element関数を用いると既存の要素のIDを指定することで,要素のレンダリング結果を別の要素の背景に流しこむことができる.
HTML文書の構造を分解することなく見た目のコピーを行うことが出来るので,様々な場面で便利な機能となりそうだが,いかんせん現状firefoxでしか動作しない

とは言え,動作するのであればその応用法を探ることもできるので早速テーブルの列固定に使ってみた.横方向に長いテーブルを特定の列を固定しつつスクロールさせることを目標とする.

方針としては,pushpin headerに似ていて,tableを数層のdiv要素でくるみ,固定したい列を外部div要素の絶対位置に配置する形だ.これまで列そのものを切り出すことはtable要素の構造上不可能であったが,element関数を用いればtableのコピーを生成することができる.このコピーは単なる画像なので,固定列の幅の分だけテーブル画を切り出せれば目的は達成できたこととなる.

ではやってみよう.



このようにあっさりとうまくいった.なお,上に画像が張り付いている都合上,1列目に編集可能な要素(input等)が含まれていた場合,操作することができない.また,文字列の選択ができない,印刷時に出力されないケースがあるなど,background画像であるがゆえのユーザビリティーの低下についても注意しなければならない.

テーブルを横のみにスクロールさせたいというケースは限定的なので、このアイディアが活躍する場はそれほどないかもしれない.だが,element関数そのものは大きな可能性を秘めていると思われるので,firefox以外のブラウザによる早期の対応が望まれる.

なおこれを応用すれば長い間の夢だったcssのみによるヘッダー・フッター・列の同時固定テーブルが実装出来るんじゃないかと考えたのだけれど,横位置,縦位置のいずれか片方のみを固定してもう片方を可変とするのがどうにも不可能.横スクロールdivと縦スクロールdivとで交互にくるんだらどうかとも考えたが,今度はスクロールバー自体がスクロールして見えなくなってしまう.なんとも歯がゆいのであった.



<!DOCTYPE html>
<html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
 <style type="text/css">

div.container{
 position:relative;
 padding-left:88px;/*固定する行だけ空ける*/
}
div.scroller{
 width:300px;
 overflow:auto;
}
div.container:after{/*after擬似要素を固定行として利用する*/
 display:block;
 content:"";
 position:absolute;
 top:0;
 left:0;
 width:88px;
 height:100%;
 background-color:yellow;
 background-image:-moz-element(#fixee);/*テーブルの見た目を背景に設定*/
 /*下記は現状動作しません*/
 background-image:-webkit-element(#fixee);
 background-image:-o-element(#fixee);
 background-image:-ms-element(#fixee);
 background-image:element(#fixee);
 background-repeat:no-repeat;
}
div.fixer{/*テーブル幅を固定する為のdiv*/
 margin-left:-88px;/*固定する行だけずらす*/
 width:607px;
}
#fixee,#fixee th,#fixee td{
 border-style:solid;
 border-width:1px;
 border-color:black;
}
#fixee th,#fixee td{
 width:80px;
 height:22px;
}
 </style>
 </head>
 <body>
<div class="container">
<div class="scroller">
<div class="fixer">
<table id="fixee">
<thead>
<tr><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th></tr>
</thead>
<tfoot>
<tr><td>1</td><td>2</td><td>3</td><td>4</td><td></td><td></td><td></td></tr>
</tfoot>
<tbody>
<tr><td>1行目</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr>
<tr><td>2行目</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr>
<tr><td>3行目</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr>
<tr><td>4行目</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td></tr>
</tbody>
</table>
</div>
</div>
</div>
 </body>
</html>

0 件のコメント:

コメントを投稿