web-dev-qa-db-ja.com

flex-boxがdivでは機能するがテーブルでは機能しないのはなぜですか?

次の簡単なスニペットは、上部にヘッダー、下部にフッターを備えた使用可能な画面スペースを占める単一のWebページと、可能な限り多くのスペースを占めるメインコンテンツ(簡単にするために点線のボーダーを使用)になります。見る):

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-flow: column;
}

h1, small {
  flex: 0 1 auto;
}

div {
  flex: 1 1 auto;
  border: 1px dotted;
}
<!doctype html>
<html>
  <body>
    <h1>Some Header</h1>
    <div>Some Text</div>
    <small>Some Footer</small>
  </body>
</html>

CSSとHTMLを変更して、代わりにtableの代わりにdivを使用すると、テーブルが拡張されて使用可能なスペースが消費されません。

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  display: flex;
  flex-flow: column;
}

h1, small {
  flex: 0 1 auto;
}

table {
  flex: 1 1 auto;
  border: 1px dotted;
}
<!doctype html>
<html>
  <body>
    <h1>Some Header</h1>
    <table><tr><td>Some Content</td></tr></table>
    <small>Some Footer</small>
  </body>
</html>

最初のバージョン(div付き)は機能するが、2番目のバージョン(table付き)は機能しないのはなぜですか?また、2番目の例を修正して、テーブルを拡張し、すべての利用可能なスペースを消費する方法はありますか(スクロールバーを導入せずに)?

いくつかのメモ:私のテーブルには、ヘッダーの行(すべて同じ幅の行)といくつかの行(すべて同じ幅/高さの行)があります。 divsの束とより多くのCSSを使用してテーブルを再作成することは可能ですが、そのルートを下るのは、赤ちゃんをお風呂で捨てるように感じます(さらに、私はこの質問をすることはできず、ハッキングしただけかどうかを確認します)。また、JavaScriptはここでは利用できません(そしてやり過ぎのようです)。

私は自分をトラブルに巻き込むのに十分なCSS/HTMLを知っていますが、それを脱するのに十分ではありません...

編集:tabledisplay: flexを使用するというaavrugの提案は、テーブルを適切に拡張して領域を埋めるようにしますが、複数の行/列をテーブルに追加すると、もはや等分布ではありません。 tableのセルの等分布を維持したいのですが。

12
Cornstalks

Html table要素は、そのdisplayプロパティをフレックスコンテナーに保持します。

display: table

したがって、フレックスプロパティは受け付けません。

ただし、単にそのルールを display: blockdisplay: flexとレイアウトが機能する必要があります。

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
body {
  display: flex;
  flex-flow: column;
}
h1,
small {
  flex: 0 1 auto;
}
table {
  display: flex;
  flex: 1 1 auto;
}
tbody {
  display: flex;
  width: 100%;
}
tr {
  display: flex;
  width: 100%;
}
td {
  flex: 1;
  border: 1px solid red;
}
<h1>Some Header</h1>
<table>
  <tr>
    <td>Some Content</td>
    <td>Some Content</td>
    <td>Some Content</td>
    <td>Some Content</td>
    <td>Some Content</td>
  </tr>
</table>
<small>Some Footer</small>
2
Michael_B

問題は テーブルボックスがテーブルラッパーボックス内に配置されていることだと思います

テーブルは、テーブルボックス自体とキャプションボックスを含むテーブルラッパーボックスと呼ばれる主要なブロックボックスを生成します

enter image description here

そのため、テーブルボックスはフレックスコンテナの子ではなくなり、フレックスアイテムではなくなりました。フレックスアイテムはテーブルラッパーボックスですが、flexプロパティをtable要素に設定し、

継承不可能なプロパティの値は、テーブルラッパーボックスではなく、テーブルボックスで使用されます

したがって、flexはフレックスアイテムではないボックスで使用されるため、無視されます。

そのプロパティがテーブルラッパーボックスで使用されている場合は機能した可能性がありますが、選択することはできません。可能であっても、それが関与するFlexboxレイアウトではなく、生成する表レイアウトに従ってサイズを変更する必要があるかどうかは明確ではありません。

解決策は簡単です:

  1. テーブルをラッパーに配置します。これはフレックスアイテムになります
  2. フレックスレイアウトを使用して必要に応じて項目をフレックスするサイズ
  3. テーブルをフローから外し、フレックスアイテムに対して相対的な長さを指定します
html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
body {
  display: flex;
  flex-flow: column;
}
h1, small {
  flex: 0 1 auto;
}
div {
  position: relative;
  flex: 1 1 0; /* Chrome needs non-auto flex-basis */
  overflow: auto;
}
table {
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  table-layout: fixed;
  border-collapse: collapse;
}
td {
  border: 1px dotted;
  text-align: center;
}
<h1>Some Header</h1>
<div>
  <table><tr>
    <td>This</td>
    <td>is</td>
    <td>equidistributed.</td>
  </tr><tr>
    <td>This</td>
    <td>is also</td>
    <td>equidistributed.</td>
  </tr></table>
</div>
<small>Some Footer</small>

おもしろいことに、ラッパーを追加しないハックな方法は、テーブルをブロックとして、自動的に挿入されたtbodyをテーブルとしてスタイリングすることです。

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
body {
  display: flex;
  flex-flow: column;
}
h1, small {
  flex: 0 1 auto;
}
table {
  display: block;
  position: relative;
  flex: 1 1 0;
}
tbody {
  display: table;
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;
  table-layout: fixed;
  border-collapse: collapse;
  box-sizing: border-box;
}
td {
  border: 1px dotted;
  text-align: center;
}
<h1>Some Header</h1>
<table><tr>
  <td>This</td>
  <td>is</td>
  <td>equidistributed.</td>
</tr><tr>
  <td>This</td>
  <td>is also</td>
  <td>equidistributed.</td>
</tr></table>
<small>Some Footer</small>
2
Oriol

ひとつのこととして、高さと幅にはvwとvhの単位を使用する必要があります。これらはほとんどのブラウザーでサポートされていませんが、できることは本当に得意です。また、表の問題では、幅を指定しなかったため、テキストに収まるセルのみが取得されます。

「width:75vw;」のようなものを追加しますテーブルスタイルにすると便利です(幅に%sを使用できます)

0
KevTLW