ヘッダ固定でスクロールできるテーブル

投稿日:

HTMLで縦に長い表のときは、見出しを固定(エクセルの「ウィンドウ枠の固定」)して、スクロールできるようにしたい。この動作をCSSだけで実現するようにできたのでメモ。

(2013年8月6日改訂)

動作検証ブラウザ

Win:IE7~10、Firefox22、Google Chrome28
Mac:Firefox22、Google Chrome28、Safari6.0.5

テーブルのヘッダ/フッタ固定・スクロールできるテーブルを指定できます。(あらかじめセルの幅を決めておく必要があります)

ポイント

  • TABLE要素を二つのDIV要素で囲む。
  • 外側のDIV要素に「position:relative」を指定。(ポジションの起点になる)
  • 内側のDIV要素に「overflow:auto」と「height」を指定(スクロールする)。見出しの文の高さの罫線を上下に追加。
  • THEAD要素の中のTR要素に「position:absolute」「top:0」を指定。(外側のDIV要素の上に表示される)
  • TFOOT要素の中のTR要素に「position:absolute」「bottom:0」を指定。(外側のDIV要素の下に表示される)
  • セルの幅とスクロールバーの幅(16px)の合計と外側のDIV要素の幅が同じになるように指定。

以上でTBODY要素がスクロールされます。

注意

  • OperaでTBODYに余白が追加されます。(原因不明)
  • 表に罫線を追加する場合は、罫線が表示されないバグ(IE6,7)や、TBODYの左罫線が表示されない(IE8、Firefox)等があるので、細かい対応が必要になります。
  • 上記方法以外で、TBODY要素に「overflow-auto」を指定する方法がありますが、IE で正しく表示されないバグがあります。(TBODY要素に指定したoverflowが無視される・高さがTRに継承されるなど)

デモページ

HTML部

<div class="scroll-table"><!-- 外側のDIV要素 -->
    <div class="scroll-table-inner"><!-- 内側のDIV要素 -->
    <table>
            <table>
                <thead>
                    <tr><th class="th-title">Date</th><th>IE</th><th>Firefox</th><th>Chrome</th><th>Safari</th><th>Opera</th><th>Other</th></tr>
                </thead>
                <tfoot>
                    <tr><th class="th-title">Date</th><th>IE</th><th>Firefox</th><th>Chrome</th><th>Safari</th><th>Opera</th><th>Other</th></tr>
                </tfoot>
                <tbody>
                    <tr><th>2013-07</th><td>51.24</td><td>13.09</td><td>23.19</td><td>8.38</td><td>0.92</td><td>3.18</td></tr>
                    <tr><th>2013-06</th><td>50.86</td><td>13.26</td><td>23.68</td><td>9.07</td><td>0.88</td><td>2.25</td></tr>
                    <tr><th>2013-05</th><td>51.72</td><td>14.1</td><td>22.97</td><td>8.05</td><td>0.94</td><td>2.23</td></tr>
                    <tr><th>2013-04</th><td>51.32</td><td>14.63</td><td>22.78</td><td>8.11</td><td>1.04</td><td>2.12</td></tr>
                    <tr><th>2013-03</th><td>52.36</td><td>14.29</td><td>22.28</td><td>8.08</td><td>1</td><td>2</td></tr>
                    <tr><th>2013-02</th><td>52.38</td><td>14.29</td><td>21.69</td><td>8.67</td><td>1.03</td><td>1.95</td></tr>
                    <tr><th>2013-01</th><td>53.06</td><td>14.48</td><td>21.39</td><td>8.1</td><td>1.03</td><td>1.94</td></tr>
                    <tr><th>2012-12</th><td>53.9</td><td>14.51</td><td>20.87</td><td>7.86</td><td>1.05</td><td>1.81</td></tr>
                    <tr><th>2012-11</th><td>54.34</td><td>14.83</td><td>20.14</td><td>7.86</td><td>1.09</td><td>1.75</td></tr>
                    <tr><th>2012-10</th><td>54.04</td><td>15.04</td><td>19.88</td><td>8.02</td><td>1.28</td><td>1.75</td></tr>
                    <tr><th>2012-09</th><td>54.66</td><td>15.46</td><td>19.36</td><td>7.43</td><td>1.32</td><td>1.76</td></tr>
                    <tr><th>2012-08</th><td>54.7</td><td>15.88</td><td>18.87</td><td>7.17</td><td>1.31</td><td>2.07</td></tr>
                    <tr><th>2012-07</th><td>52.86</td><td>17.72</td><td>18.82</td><td>7.08</td><td>1.5</td><td>2.02</td></tr>
                    <tr><th>2012-06</th><td>52.23</td><td>19.09</td><td>17.95</td><td>7.01</td><td>1.63</td><td>2.09</td></tr>
                    <tr><th>2012-05</th><td>52.74</td><td>19.56</td><td>17.68</td><td>6.9</td><td>1.57</td><td>1.55</td></tr>
                    <tr><th>2012-04</th><td>54.8</td><td>18.54</td><td>16.95</td><td>6.71</td><td>1.46</td><td>1.55</td></tr>
                    <tr><th>2012-03</th><td>56.14</td><td>17.67</td><td>16.92</td><td>6.45</td><td>1.45</td><td>1.37</td></tr>
                    <tr><th>2012-02</th><td>54.36</td><td>18.05</td><td>17.46</td><td>7.38</td><td>1.45</td><td>1.3</td></tr>
                    <tr><th>2012-01</th><td>52.38</td><td>19.17</td><td>18.04</td><td>7.01</td><td>1.67</td><td>1.73</td></tr>
                    <tr><th>2011-12</th><td>53.58</td><td>19.24</td><td>17.18</td><td>6.55</td><td>1.68</td><td>1.77</td></tr>
                    <tr><th>2011-11</th><td>53.85</td><td>19.18</td><td>16.82</td><td>6.67</td><td>1.63</td><td>1.85</td></tr>
                    <tr><th>2011-10</th><td>54.56</td><td>19.31</td><td>16.45</td><td>6.31</td><td>1.63</td><td>1.74</td></tr>
                    <tr><th>2011-09</th><td>55.39</td><td>19.73</td><td>15.6</td><td>6.05</td><td>1.64</td><td>1.58</td></tr>
                    <tr><th>2011-08</th><td>55.87</td><td>19.98</td><td>14.83</td><td>6.19</td><td>1.6</td><td>1.52</td></tr>
                    <tr><th>2011-07</th><td>54.59</td><td>21.06</td><td>14.71</td><td>6.37</td><td>1.73</td><td>1.54</td></tr>
                    <tr><th>2011-06</th><td>55.46</td><td>21</td><td>13.84</td><td>6.55</td><td>1.65</td><td>1.51</td></tr>
                    <tr><th>2011-05</th><td>56.77</td><td>20.88</td><td>12.93</td><td>6.29</td><td>1.58</td><td>1.55</td></tr>
                    <tr><th>2011-04</th><td>60.07</td><td>19.44</td><td>11.54</td><td>6.09</td><td>1.43</td><td>1.43</td></tr>
                    <tr><th>2011-03</th><td>58.25</td><td>20.62</td><td>11.91</td><td>6.35</td><td>1.52</td><td>1.35</td></tr>
                    <tr><th>2011-02</th><td>57.44</td><td>21.28</td><td>11.71</td><td>6.63</td><td>1.64</td><td>1.3</td></tr>
                    <tr><th>2011-01</th><td>57.69</td><td>21.57</td><td>10.93</td><td>6.77</td><td>1.7</td><td>1.34</td></tr>
                    <tr><th>2010-12</th><td>58.6</td><td>21.63</td><td>9.96</td><td>6.63</td><td>1.82</td><td>1.36</td></tr>
                    <tr><th>2010-11</th><td>58.56</td><td>22.18</td><td>9.12</td><td>6.74</td><td>1.98</td><td>1.41</td></tr>
                    <tr><th>2010-10</th><td>59.49</td><td>22.27</td><td>8.23</td><td>6.55</td><td>2.03</td><td>1.43</td></tr>
                    <tr><th>2010-09</th><td>59.94</td><td>22.44</td><td>7.66</td><td>6.48</td><td>1.98</td><td>1.51</td></tr>
                    <tr><th>2010-08</th><td>60.36</td><td>22.74</td><td>7.23</td><td>6.31</td><td>1.75</td><td>1.6</td></tr>
                    <tr><th>2010-07</th><td>60.81</td><td>22.98</td><td>6.93</td><td>6.03</td><td>1.61</td><td>1.64</td></tr>
                    <tr><th>2010-06</th><td>60.97</td><td>23.15</td><td>6.63</td><td>6.04</td><td>1.62</td><td>1.6</td></tr>
                    <tr><th>2010-05</th><td>61.51</td><td>22.97</td><td>6.14</td><td>6.05</td><td>1.6</td><td>1.74</td></tr>
                    <tr><th>2010-04</th><td>62.27</td><td>22.74</td><td>5.52</td><td>6.04</td><td>1.61</td><td>1.81</td></tr>
                    <tr><th>2010-03</th><td>62.98</td><td>22.33</td><td>5.27</td><td>6.14</td><td>1.75</td><td>1.53</td></tr>
                    <tr><th>2010-02</th><td>64.09</td><td>22.54</td><td>4.87</td><td>5.86</td><td>1.69</td><td>0.95</td></tr>
                    <tr><th>2010-01</th><td>65.07</td><td>21.81</td><td>4.46</td><td>5.7</td><td>1.68</td><td>1.28</td></tr>
                </tbody>
            </table>
    </div>
</div>

CSS

/****************************************/
/* ヘッダ、フッタ固定
/****************************************/
.scroll-table {
    position: relative;
}
.scroll-table .scroll-table-inner {
    height: 200px;
    overflow: auto;
}
.scroll-table table {
    border-top: 3em solid #fff;
    border-bottom: 3em solid #fff;
}
.scroll-table table th ,
.scroll-table table td {
    text-align: center;
    vertical-align: middle;
}
.scroll-table table thead tr {
    position: absolute;
    left: 0;
    top: 0;
}
.scroll-table table tfoot tr {
    position: absolute;
    left: 0;
    bottom: 0;
}
.scroll-table table thead tr th ,
.scroll-table table tfoot tr th {
    height: 3em;
    line-height: 1.142857;/*16px*/
}
.scroll-table table tbody tr td ,
.scroll-table table thead tr th ,
.scroll-table table tfoot tr th {
    width: 80px;
}
.scroll-table table tbody tr th ,
.scroll-table table thead tr th.th-title ,
.scroll-table table tfoot tr th.th-title {
    width: 104px;
}

/****************************************/
/* Color
/****************************************/
.scroll-table table thead tr th {
    color: #fff;
    background: #09aa04;
    background: -webkit-gradient(linear, left top, left bottom, from(rgba(9,170,4,1)), to(rgba(9,170,4,0.8)));
    background: -webkit-linear-gradient(top, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background:    -moz-linear-gradient(top, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background:      -o-linear-gradient(top, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background: linear-gradient(to bottom, rgba(9,170,4,1), rgba(9,170,4,0.8));
}
.scroll-table table tfoot tr th {
    color: #fff;
    background: #09aa04;
    background: -webkit-gradient(linear, left bottom, left top, from(rgba(9,170,4,1)), to(rgba(9,170,4,0.8)));
    background: -webkit-linear-gradient(bottom, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background:    -moz-linear-gradient(bottom, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background:      -o-linear-gradient(bottom, rgba(9,170,4,1), rgba(9,170,4,0.8));
    background: linear-gradient(to top, rgba(9,170,4,1), rgba(9,170,4,0.8));
}
.scroll-table table thead tr th.th-title {
    background: #ffa64d;
    background: -webkit-gradient(linear, left top, left bottom, from(rgba(255,166,77,1)), to(rgba(255,166,77,0.8)));
    background: -webkit-linear-gradient(top, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background:    -moz-linear-gradient(top, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background:      -o-linear-gradient(top, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background: linear-gradient(to bottom, rgba(255,166,77,1), rgba(255,166,77,0.8));
}
.scroll-table table tfoot tr th.th-title {
    background: #ffa64d;
    background: -webkit-gradient(linear, left bottom, left top, from(rgba(255,166,77,1)), to(rgba(255,166,77,0.8)));
    background: -webkit-linear-gradient(bottom, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background:    -moz-linear-gradient(bottom, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background:      -o-linear-gradient(bottom, rgba(255,166,77,1), rgba(255,166,77,0.8));
    background: linear-gradient(to top, rgba(255,166,77,1), rgba(255,166,77,0.8));
}
.scroll-table table tbody tr th {
    background: #fff9f2;
}
.scroll-table table tbody tr:nth-child(2n) th {
    background: #f7f8e3;
}
.scroll-table table tbody tr:nth-child(2n) td {
    background: #f6feee;
}

/****************************************/
/* For less than IE10
/****************************************/
.ie-lt10 .scroll-table table thead tr th {
    overflow: hidden;
    background: transparent;
    -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff09aa04,endColorstr=#cc09aa04,GradientType=0)";
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff09aa04,endColorstr=#cc09aa04,GradientType=0);
}
.ie-lt10 .scroll-table table tfoot tr th {
    position: relative;
    background: transparent;
    -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#cc09aa04,endColorstr=#ff09aa04,GradientType=0)";
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#cc09aa04,endColorstr=#ff09aa04,GradientType=0);
}
.ie-lt10 .scroll-table table thead tr th.th-title {
    position: relative;
    background: transparent;
    -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffa64d,endColorstr=#ccffa64d,GradientType=0)";
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ffffa64d,endColorstr=#ccffa64d,GradientType=0);
}
.ie-lt10 .scroll-table table tfoot tr th.th-title {
    position: relative;
    background: transparent;
    -ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#ccffa64d,endColorstr=#ffffa64d,GradientType=0)";
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#ccffa64d,endColorstr=#ffffa64d,GradientType=0);
}