LoginSignup
3
4

More than 5 years have passed since last update.

CSS で横グラデーションボーダーのテーブルを作る

Last updated at Posted at 2017-10-06

CSS で横グラデーションボーダーのテーブルを作る。
こんなやつ。
table01.png

  • Mac:Safari 10, Firefox 56, Chrome 61, Opera 48
  • Windows 7:IE 11, Firefox 56, Chrome 61 以上の環境で確認

背景を塗りつぶしても構わない場合

テーブルの背景を単一色で塗りつぶしても良いなら、シンプルに以下で実装可能。
table の背景を linear-gradient で塗り、border-spacing の隙間からそれを見せる仕組み。

<div class="grad-border">
<table>
<tbody>
<tr>
<th>見出し</th>
<td>サンプルテキスト</td>
</tr>
... 一般的なテーブル
</table>
</div>
.grad-border table {
background: linear-gradient(to right, transparent 0%,#f00 30%,#00f 70%,transparent 100%);
border-collapse: separate;
border-spacing: 0 4px;
}

.grad-border table tr {
background: #fff;
}

背景を塗りつぶさず、純粋に罫線のみを描く場合

一方で、多色&柄背景への対応を考え、純粋に罫線のみを描こうとすると意外にコレが難しい。
...と思ったのだが、すったもんだの回り道の末たどり着いたのは単純な結論という、よくあるオチだった。

2017年10月9日追記
before 擬似要素を使用した場合、特定構成の table において表示崩れの発生が見られたので after を使用する形に修正。

/* HTML は上記と共通 */

.grad-border table {
position: relative;
}

.grad-border th,.grad-border td {
vertical-align: middle;/* top,middle,bottom いずれかの指定が必須 */
}

.grad-border table::after,.grad-border tr::after {
position: absolute;
content: "";
width: 100%;
height: 4px;/* 罫線の太さ */
left: 0;
margin-top: -2px;/* 罫線の太さの半分のネガティブ値 */
background: linear-gradient(to right, transparent 0%,#f00 30%,#00f 70%,transparent 100%);
}

.grad-border table::after {
bottom: -2px;/* 罫線の太さの半分のネガティブ値 */
}

上記の通り、tr::after の背景をグラデーションに塗り罫線に見せるという単純なもの。
なぜ回り道する事になったかは後述。

なお、tr::before, tr::after どちらも垂直方向の初期配置は tr の上部に張り付く形となるため、tr の擬似要素で描く事ができるのは上罫線のみ。そのため、最後の下罫線は table 自体の擬似要素を利用している。(tr に position: relative は適用されないため bottom:0 で位置調整して下罫線を引く事はできない)

テーブルの内側のみ罫線を引きたい場合は下記の通り。
table 自体の擬似要素は作成せず、最初の tr::after を隠せば良い。
最上段、最下段の罫線だけ要らないなんてケースもこれらを組み合わせる事で実現可能。
table02.png

.grad-border table {
position: relative;
}

.grad-border th,.grad-border td {
vertical-align: middle;/* top,middle,bottom いずれかの指定が必須 */
}

.grad-border tr::after {
position: absolute;
content: "";
width: 100%;
height: 4px;/* 罫線の太さ */
left: 0;
margin-top: -2px;/* 罫線の太さの半分のネガティブ値 */
background: linear-gradient(to right, transparent 0%,#f00 30%,#00f 70%,transparent 100%);
}

.grad-border tr:first-child::after {
visibility: hidden;
}

/* thead がある場合、tbody の最初の tr::after は再表示させる */
.grad-border thead + tbody tr:first-child::after {
visibility: visible;
}

回り道する羽目になった理由

当然この「tr::after の背景をグラデーションに塗り罫線に見せる」という手法は真っ先に試してみたのだが、大きな回り道をする要因となったのは以下の部分。

.grad-border th,.grad-border td {
vertical-align: middle;/* top,middle,bottom いずれかの指定が必須 */
}

table 系タグの内部要素(tr や th,td)は CSS の仕様上 position: relative が適用されないため、top:0 等の指定は使えず、位置調整は margin による「初期配置からの上下移動」のみとなる。
この縛りがあるため「各ブラウザで同じ初期配置になる要素を使って罫線を描く」事が前提条件となるのだが、

vertical-align: baseline(無指定の場合の初期値)の場合、「Firefox / IE」と「Safari / Chrome」では tr 擬似要素の、垂直方向の初期配置が異なる

という落とし穴があった。
そんな訳で、vertical-align を明示指定せずに行った最初のテストでは、ブラウザによって罫線が揃わない事態となり、「ありゃ、イケると思ったのにダメか」と延々遠回りする羽目となった。

なお、上記の理由により、vertical-align: baseline を適用したい table に、この手法は使えないので注意。
その場合は、最初の背景を塗りつぶす方法を使うしかない。

おまけ:CSS によるグラデーション下線

上記に辿り着くまでに見つけた小ネタ。
CSS でグラデーションのラインを引く方法というと、今回も使用している「擬似要素を作り、その要素の background をグラデーションに塗る」手法がよく知られているが、border-radius を使わない単純な直線で良ければ、シンプルに以下でも設定できる。ただし、border-image は IE11 以降対応なので、それ以前も対象に含める場合は使用できない。

h2 {
border-bottom: solid 4px;
border-image: linear-gradient(to right, #ff6e02 0%, #ff0 50%, #ffb600 74%, #ff6e02 100%);
border-image-slice: 1;
}

「border-image-slice: 1」がポイント。
ショートハンドで下記のようにまとめる事もできる。

h2 {
border-bottom: solid 4px;
border-image: linear-gradient(to right, #ff6e02 0%, #ff0 50%, #ffb600 74%, #ff6e02 100%) 1;
}

また、同様に border-radius を使わない直角の枠で良ければ、上記を「border: solid 4px;」にする事でグラデーションの囲み枠も簡単に作成できる。border-image と border-radius が併用できないのが非常に惜しい。

もちろん「tr にこれを使えば簡単じゃん」と試してみたのだが、「border-collapse: collapse」の場合「border-image」は反映されないらしく撃沈。(tr に border を描く際は「border-collapse: collapse」が必須)

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4