table要素で指定したwidthが、col要素で指定したwidthと矛盾する場合、列幅はどうなるか？


# 背景
W3CのCSS3の仕様によると、tableの列幅の計算アルゴリズムは複雑です。条件分岐がたくさんあります。
https://www.w3.org/TR/css-tables-3/#content-measure

列幅の指定で、期待通りにならないことがよくあるので、まとめました。



# 前提条件

## 用語
* セル要素: td要素, th要素
* 列要素: col要素, colgroup要素

## 確認に使ったブラウザ
* Firefox 60.0.2 (64 ビット)

## CSS

```css:sample.css
    table {
      table-layout: fixed; /* 列幅を固定レイアウトにする */
    }

    table,td,th {
      border: 1px solid black;
      border-collapse: collapse;
    }

    th {
      background-color: gray;
    }

    td,th {
      /* td/th要素でwidthを指定したときと、col要素で指定したときの幅が同じになるようにする */
      box-sizing: border-box; 
    }
```

## 基準とするHTMLのtable

```html
  <table style="width:200px;">
    <colgroup>
      <col><col>
    </colgroup>
    <tbody>
      <tr>
        <td>1A</td><td>1B</td>
      </tr>
    </tbody>
  </table>
````  


## 確認方法
table要素のwidthを200pxにした状態で、さらにcol要素のwidthを指定します。
実際に表示される列の幅を、ブラウザの開発ツールで確認します。


# 結果


<p data-height="377" data-theme-id="0" data-slug-hash="XYaEBG" data-default-tab="result" data-user="yuji38kwmt" data-embed-version="2" data-pen-title="table要素で指定したwidthが、col要素で指定したwidthと矛盾する場合、列幅はどうなるか？" class="codepen">See the Pen <a href="https://codepen.io/yuji38kwmt/pen/XYaEBG/">table要素で指定したwidthが、col要素で指定したwidthと矛盾する場合、列幅はどうなるか？</a> by yuji38kwmt (<a href="https://codepen.io/yuji38kwmt">@yuji38kwmt</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
  
## `table_width ＞ col1_width + co2_width `の場合


```html
  <table style="width:200px;">
    <colgroup>
      <col style="width:100px;"><col style="width:50px;">
    </colgroup>
    <tbody>
      <tr>
        <td>1A</td><td>1B</td>
      </tr>
    </tbody>
  </table>
```  

* tableのwidthは、table要素に指定したwidthと同じ
* 各列のwidthは、各列に指定したwidthの比率を保った状態で、拡大される
    - co1_widthは132.883px, co2_widthは66.45px



## `table_width ＜ col1_width + co2_width `の場合


```html
  <table style="width:200px;">
    <colgroup>
      <col style="width:200px;"><col style="width:50px;">
    </colgroup>
    <tbody>
      <tr>
        <td>1A</td><td>1B</td>
      </tr>
    </tbody>
  </table>
```  

* 各列のwidthは、col要素に指定したwidthと同じ
* table要素のwidthは、各列に指定したwidthの合計値
    - table要素のwidthは250px


## `table_width ≧ col1_width AND  co2_widthは未指定 `の場合

```html
  <table style="width:200px;">
    <colgroup>
      <col style="width:200px;"><col >
    </colgroup>
    <tbody>
      <tr>
        <td>1A</td><td>1B</td>
      </tr>
    </tbody>
  </table>
```  

* 1列目のwidthは、col要素に指定したwidthと同じ
* tableのwidthは、table要素に指定したwidthと同じ
* 2列目は、罫線外に表示される
    - 2列目のcol要素のwidthは`0px`
    - 2列目のtd要素のwidthは`-2.66px`.  **負の値!!**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37903/f4c40191-8ba4-29ed-0928-56c222594c29.png)



# まとめ
*  `table_width ＞ col1_width + co2_width `の場合
    - 列幅は、各列に指定したwidthの比率を保った状態で、拡大される
*  `table_width ＜ col1_width + co2_width `の場合
    - 列幅は、各列に指定したwidthと同じ
* `table_width ≧ col1_width AND  co2_widthは未指定 `の場合
    - 2列目の幅は0pxで、罫線の外に表示される。

# 【補足】col要素でなくtd要素にwidthを指定
結果はcol要素のときと同じでした。
CodePen参照

# 感想
 `table_width ＜ col1_width + co2_width `の挙動が意外でした。
 「table要素のwidthが優先」という訳ではないようです。
 
 前回まとめた記事でもそうでしたが、widthは「最大値」が優先になるときが多そうですね。
 https://qiita.com/yuji38kwmt/items/25763a557d76017ecf2f
 
まあ、CSS3の仕様を理解すれば、すべて解決なのですが。。。