◆ Firefox
  ◆ visibility:hidden のときに border ができる
  ◆ セルの有無にかかわらず table の border は表示される
◆ Chrome
  ◆ visiblity:hidden のときに border はない
  ◆ セルがない (display:none も) とそこに隣接する table の border が表示されない

CSS Grid でテーブルを置き換えたいと思っていますが その理由が table の動きが分かりづらい上にブラウザごとに違うことが多いことです
table は昔からある割に比較的ブラウザの違いに苦しまされるタグです
逆に昔からあるからこそ もうそのまま放置で新しい機能を優先してるのかもしれません

比較的 Chrome のバグだろうと思うのが多くてだいたいは Firefox のほうが正しそうなのですが 今回のはちょっとよくわからなかったです
一応 CSS の spec を流し見はしたのですが separated borders model は単純なのに collapsing border model はちょっと複雑でサッと理解するのは大変そうだったのでとりあえず現状ブラウザごとに違うという理解にとどめてます

ところで この URL の仕様は CSS 2.2 なのですが CSS 3 でこれに相当するのは見当たらなかったです
ググって全然出てこないとなると 存在しないのでしょうか
見かけるのって新機能が追加されたり変更されたものばかりなので 変更のない基本的な部分は特に level3 として作る必要がないのでそのままなのでしょうか
この 2.2 のバージョンも最終更新がまだ 2 年前ですし 作ってはいてもまだ勧告されてないのかもしれません
WhatWG の HTML spec の reference が CSS として参照してるのは 2.2 ですし まだ見る価値のあるドキュメント何だと思うことにします

コード

border-collapse が collapse でセルが visibility:hidden や display:none のときの見た目です

<!doctype html>

<style>
* {
box-sizing: border-box;
}

#container {
width: 500px;
}

table {
width: 100%;
border-collapse: collapse;
border: 15px solid plum;
}

th {
background: seashell;
}

td {
border: 1px solid deepskyblue;
}

.invisible {
visibility: hidden;
}
</style>

<div id="container">
<div id="wrapper">
<table>
<thead>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td class="invisible">2</td>
<td class="invisible">3</td>
</tr>
<tr>
<td>1</td>
<td hidden>2</td>
<td hidden>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td class="invisible">2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td hidden>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td class="invisible">2</td>
</tr>
</tbody>
</table>
</div>
</div>

ブラウザごとの結果

Chrome

chrome-table-border-collapse


Firefox


firefox-table-border-collapse

Demo

違い

Chrome だと全体的に border が少ないです

HTML では
1 行目は普通に 3 列あります
2 行目は 2, 3 列目が .invisible (visibility:hidden) です
3 行目は 2, 3 列目が hidden (display:none) です
4 行目は普通に 3 列あります
5 行目は 2 列目が .invisible (visibility:hidden) です
6 行目は 2 列目が hidden (display: none) です
7 行目は 2 列目が .invisible (visibility:hidden) で 3 列目はセル自体がありません

Chrome はセルなしと .invisible と hidden の違いはなくどれも border は描画されていません
5 行目 2 列目は囲まれていますが そのまわりのセルに border があるからで 2 行目の 2,3 列目の下側や 7 行目の 2 列目の右側のように単体では border はありません

Firefox だと 2 行目や 7 行目を見たとおり .invisible では border が存在します
.invisible では見えなくてもスペースは確保されるとは言え table 関係以外の通常の要素と同様に border がない Chrome のほうが自然に思います


hidden ではどちらも border はありません
6 行目の 2 列目が 3 と表示されているようにスペースが確保されずないもの扱いされて次のセルが詰められて配置されます
ただし テーブルの端の場合は Chrome だと table の border 自体も消えてしまいます
Firefox では table の border は残ります
こっちはセルがなくても table の border は残る Firefox のほうが自然に思えます

5 行目 3 列目の下側の border をみると border はあります
border なしと border ありがくっつくと border なしになるなんてことはおかしいですし これで正しいと思います
その考えで言えば border がない 6 行目 3 列目の右側と border のある table がくっつくと border が表示されるように思います
table だけ特別扱いなのかと思いましたが スペックの図によると 端のセルは table の border と border を共有してるようです

tbl-width

ただ セルがない場合は この図で言う 右側の width や padding の場所すらないので これに当てはまらないようにも思います

empty cell の動きがどうなるのかを探してみたのですが 背景が透過されるとか show に設定されていたら通常のセルと同じ動きだとかあるものの すべて separated borders model に対する説明です
collapsing borders model では未定義だったりするのでしょうか

今回の例のように table と td で border のスタイルが違うと変に目立つので Chrome の動きが正しいということがありえないように思うのですが 揃えているなら Firefox の動きだと右下は不要な場合に欠けたテーブルを作れないのでこっちが正しいのもありえないように思います
将来直るかわからないですが どっちとして考えれば良いのか悩みます

対策

とりあえず

  • td と揃えるなら table に border はなくていいので 欠けたテーブルを作りたい場合は table に border はつけない
  • table 全体に枠が欲しい場合は ラップする div 等に border をつける

にしておけばどっちでも問題無いと思います