为什么 flex-box 与 div 一起工作,而不是一个表格? [英] Why does flex-box work with a div, but not a table?

查看:18
本文介绍了为什么 flex-box 与 div 一起工作,而不是一个表格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下简单的代码片段会生成一个占据可用屏幕空间的单个网页,顶部有一个页眉,底部有一个页脚,主要内容尽可能多地占用空间(用虚线边框来表示)使其更易于查看):

html, body {宽度:100%;高度:100%;边距:0;填充:0;}身体 {显示:弹性;弹性流:列;}h1,小{弹性:0 1 自动;}div {弹性:1 1 自动;边框:1px 虚线;}

<身体><h1>一些标题</h1><div>一些文字</div><small>一些页脚</small></html>

如果我修改 CSS 和 HTML 以使用 table 代替 div,它不会扩展表格以消耗可用空间:

html, body {宽度:100%;高度:100%;边距:0;填充:0;}身体 {显示:弹性;弹性流:列;}h1,小{弹性:0 1 自动;}桌子 {弹性:1 1 自动;边框:1px 虚线;}

<身体><h1>一些标题</h1><table><tr><td>一些内容</td></tr></table><small>一些页脚</small></html>

为什么第一个版本(带有 div)可以工作,而第二个版本(带有 table)不行?有没有办法修复第二个示例,以便表格扩展并消耗所有可用空间(不引入滚动条)?

一些注意事项:我的表格将有一行标题(均等宽)和几行(均等宽/高).我知道可以使用一堆 div 和更多 CSS 重新创建一个表格,但是沿着这条路线走下去感觉就像把婴儿和洗澡水一起扔掉(此外,我不会问这个问题并了解我是否只是绕过它).另外,我在这里无法使用 JavaScript(而且看起来有点矫枉过正).

我对 CSS/HTML 的了解足以让自己陷入困境,但还不足以让自己摆脱困境...

aavrug 建议对 table 使用 display: flex 使表格正确扩展以填充该区域,但是当我向表中添加了多行/列,它们不再是均匀分布的.我想保留 table 的单元格等分布.

解决方案

我认为问题在于

所以 table box 不再是 flex 容器的子项,因此也不是 flex 项.flex 项是表格包装盒,但您将 flex 属性设置为 table 元素,并且

<块引用>

不可继承的属性值用于表格框而不是表格包装盒

所以你的 flex 被用在一个不是弹性项目的盒子上,因此被忽略了.

如果在表格包装盒上使用该属性可能会起作用,但无法选择它.即使可以,也不清楚是否应该根据它生成的表格布局而不是它参与的 Flexbox 布局来调整大小.

解决方案很简单:

  1. 将表格放在一个包装器中,这将是弹性项目
  2. 使用弹性布局根据需要调整弹性项目的大小
  3. 将表格从流程中取出并为其指定相对于弹性项目的确定长度

html, body {宽度:100%;高度:100%;边距:0;填充:0;}身体 {显示:弹性;弹性流:列;}h1,小{弹性:0 1 自动;}div {位置:相对;弹性:1 1 0;/* Chrome 需要非自动 flex-basis */溢出:自动;}桌子 {位置:绝对;高度:100%;宽度:100%;左:0;顶部:0;表格布局:固定;边框折叠:折叠;}TD{边框:1px 虚线;文本对齐:居中;}

一些标题

<div><表格><tr><td>这个</td><td>是</td><td>等分.</td></tr><tr><td>这个</td><td>也是</td><td>等分.</td></tr></table>

<small>一些页脚</small>

只是为了好玩,一种避免添加包装器的黑客方法是将表格设置为块并将自动插入的 tbody 设置为表格.

html, body {宽度:100%;高度:100%;边距:0;填充:0;}身体 {显示:弹性;弹性流:列;}h1,小{弹性:0 1 自动;}桌子 {显示:块;位置:相对;弹性:1 1 0;}身体{显示:表;位置:绝对;高度:100%;宽度:100%;左:0;顶部:0;表格布局:固定;边框折叠:折叠;box-sizing: 边框框;}TD{边框:1px 虚线;文本对齐:居中;}

一些标题

<表格><tr><td>这个</td><td>是</td><td>等分.</td></tr><tr><td>这个</td><td>也是</td><td>等分.</td></tr></table><small>一些页脚</small>

The following simple snippet results in a single web page that takes up the available screen space with a header at the top, a footer at the bottom, and the main content taking up as much space as possible (with a dotted border to make it easier to see):

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>

If I modify the CSS and HTML to instead use a table in place of a div, it doesn't expand the table to consume the available space:

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>

Why does the first version (with div) work but the second version (with table) not? And is there a way to fix the second example so the table expands and consumes all available space (without introducing scroll bars)?

Some notes: my table will have a row of headers (all with equal width) and several rows (all with equal width/height). I know it's possible to recreate a table using a bunch of divs and more CSS, but going down that route feels like throwing out the baby with the bathwater (and besides, I wouldn't get to ask this question and learn if I just hacked around it). Also, JavaScript isn't available to me here (and seems like overkill).

I know enough CSS/HTML to get myself into trouble but not enough to get myself out of it...

Edit: aavrug's suggestion to use display: flex for the table makes it so the table properly expands to fill the area, but when I add multiple rows/columns to the table they are no longer equidistributed. I'd like to preserve the table's cell equidistribution.

解决方案

I think the problem is that the table box is placed inside a table wrapper box:

the table generates a principal block box called the table wrapper box that contains the table box itself and any caption boxes

So the table box is no longer a child of the flex container, and thus is not a flex item. The flex item is the table wrapper box, but you set the flex property to the table element, and

values of non-inheritable properties are used on the table box and not the table wrapper box

So your flex is used on a box which is not a flex item and thus is ignored.

It might have worked if that property was used on the table wrapper box, but it's not possible to select it. Even if you could, it wouldn't be clear whether it should be sized according to the tabular layout it generates instead of by the the Flexbox layout in which it participates.

The solution is simple:

  1. Place the table in a wrapper, which will be the flex item
  2. Size that flex item as desired using flex layout
  3. Take the table out of flow and give it definite lengths relative to the flex item

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>

Just for fun, a hacky way to avoid adding the wrapper would be styling the table as a block and the automatically inserted tbody as the table.

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>

这篇关于为什么 flex-box 与 div 一起工作,而不是一个表格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆