在同一 HTML table 行中合并自动宽度、固定宽度和百分比宽度
Combine auto, fixed, and percentage width in same HTML table row
我想创建一个有 4 列的 table。 table 中的 2 列是标签,应该自动调整到最宽的元素。其他列之一是固定宽度,最后一列应填充剩余的 space。我第一次尝试创建这个 table 看起来像这样:
HTML
<table style="width:100%">
<tr>
<td class="lbl">lbl:</td> <td class="fluidContent">Expandable Content 1</td>
<td class="lbl">longer label:</td> <td class="fixedContent">Me Fixed</td>
</tr>
<tr>
<td class="lbl">longer label:</td> <td class="fluidContent">Expandable Content 2</td>
<td class="lbl">lbl:</td> <td class="fixedContent">Me Fixed</td>
</tr>
</table>
CSS
table {
white-space: nowrap;
}
td {
border: 1px solid orange;
}
.lbl {
text-align: right;
font-style: italic;
width: auto;
}
.fluidContent {
width: calc(100% - 120px);
}
.fixedContent {
width: 120px;
}
https://jsfiddle.net/vf5p0m82/
不幸的是,此标记会生成具有流动宽度的标签列。 "lbl" class 单元格被视为具有 27% 的宽度,而 "fluidContent" 单元格的宽度为 46%。我想要的是 "lbl" 单元格尽可能小,同时仍然适合它们包含的最大字符串。
有什么方法可以简单地使用 tables 来完成我想要的,或者是时候使用新的 CSS3 flex-boxes 了吗?
编辑:一个解决方案
虽然为了清楚起见向这个问题添加了另一个示例,但我偶然发现了一个黑客来让它工作。如果你只是给自动调整大小的列宽度 1px 一切正常。看这里:
https://jsfiddle.net/vf5p0m82/2/
是否有 established/canonical 方法来做到这一点或者就是这样?
可能有更正式的方法来执行此操作,但我发现有效的方法是将单元格宽度设置为 1px。内容大小会覆盖它,因此它只会折叠到内容大小。
.lbl {
text-align: right;
font-style: italic;
width: 1px;
}
顺便说一下,table 格式似乎覆盖了 calc,但根据您的描述,您似乎不需要它。
好的 flexbox 解决方案:https://jsfiddle.net/vf5p0m82/4/
HTML
<div class="fTbl">
<div class="fluidWrapper">
<div class="shrinkCol">
<div class="lbl">lbl:</div>
<div class="lbl">long lbl:</div>
</div>
<div class="stretchCol">
<div class="fluidCell">Expand Content</div>
<div class="fluidCell">Expand Content</div>
</div>
</div>
<div class="fixedWrapper">
<div class="shrinkCol">
<div class="lbl">longer label:</div>
<div class="lbl">lbl:</div>
</div>
<div class="shrinkCol">
<div class="fixCell" style="width:100px;">Fixed</div>
<div class="fixCell" style="width:100px;">Fixed</div>
</div>
</div>
</div>
CSS
.fTbl {
border: solid magenta 2px;
display: flex;
flex-flow: row wrap;
width: 100%;
align-items: flex-start;
}
.fixedWrapper {
display: flex;
flex: 0 0 auto;
flex-flow: row nowrap;
}
.fluidWrapper {
display: flex;
flex: 1 1 auto;
flex-flow: row nowrap;
}
.shrinkCol {
display: flex;
flex: 0 0 auto;
flex-flow: column nowrap;
}
.stretchCol {
display: flex;
flex: 1 1 auto;
flex-flow: column nowrap;
}
.fluidCell {
border: 2px solid orange;
min-width: 140px;
}
.fixCell {
border: 2px solid orange;
}
.lbl {
text-align: right;
font-style: italic;
border: 2px solid orange;
}
好的,下面是您通常如何使用这个 CSS:
- 表格必须分成单独的列,每列逐行独立填写。
- 如果不同列的行包含不同高度的项目,则必须明确赋予它们相同的高度。
- Label/content 列对放置在 fixed/fluidWrapper 类 中,以便标签和内容(通常是文本框)包裹在一起,不会分开。
- 不可能在 1 个 flex table 内有一个 "colspan" 而不将行彼此解耦并显式设置宽度。
我喜欢这种方法,因为它很容易让 flex 项目在垂直和水平方向上拉伸和压缩以填充页面,并且包装项目以响应窄屏幕非常简单。它也不需要像 table 那样的 hacky CSS。我发现 HTML table 有时会非常麻烦且不直观。
我不喜欢这种方法,因为 table 的一行不可能(或者可能很难)跨越多列。如果有更宽的项目,则必须将其放置在新容器中,因此不会与其上方的项目共享其标签宽度。然而,这些抱怨似乎源于 table 和 flex box 设计目标的内在差异,您必须简单地选择最适合给定布局的方法。
关于生成自动 table 列宽大约等于任何行中最宽列的列宽的搜索来到了这个问题。如果那是你想要做的,请在 CSS 中尝试 th,td {width: max-content;}
。适合我。
我想创建一个有 4 列的 table。 table 中的 2 列是标签,应该自动调整到最宽的元素。其他列之一是固定宽度,最后一列应填充剩余的 space。我第一次尝试创建这个 table 看起来像这样:
HTML
<table style="width:100%">
<tr>
<td class="lbl">lbl:</td> <td class="fluidContent">Expandable Content 1</td>
<td class="lbl">longer label:</td> <td class="fixedContent">Me Fixed</td>
</tr>
<tr>
<td class="lbl">longer label:</td> <td class="fluidContent">Expandable Content 2</td>
<td class="lbl">lbl:</td> <td class="fixedContent">Me Fixed</td>
</tr>
</table>
CSS
table {
white-space: nowrap;
}
td {
border: 1px solid orange;
}
.lbl {
text-align: right;
font-style: italic;
width: auto;
}
.fluidContent {
width: calc(100% - 120px);
}
.fixedContent {
width: 120px;
}
https://jsfiddle.net/vf5p0m82/
不幸的是,此标记会生成具有流动宽度的标签列。 "lbl" class 单元格被视为具有 27% 的宽度,而 "fluidContent" 单元格的宽度为 46%。我想要的是 "lbl" 单元格尽可能小,同时仍然适合它们包含的最大字符串。
有什么方法可以简单地使用 tables 来完成我想要的,或者是时候使用新的 CSS3 flex-boxes 了吗?
编辑:一个解决方案
虽然为了清楚起见向这个问题添加了另一个示例,但我偶然发现了一个黑客来让它工作。如果你只是给自动调整大小的列宽度 1px 一切正常。看这里: https://jsfiddle.net/vf5p0m82/2/
是否有 established/canonical 方法来做到这一点或者就是这样?
可能有更正式的方法来执行此操作,但我发现有效的方法是将单元格宽度设置为 1px。内容大小会覆盖它,因此它只会折叠到内容大小。
.lbl {
text-align: right;
font-style: italic;
width: 1px;
}
顺便说一下,table 格式似乎覆盖了 calc,但根据您的描述,您似乎不需要它。
好的 flexbox 解决方案:https://jsfiddle.net/vf5p0m82/4/
HTML
<div class="fTbl">
<div class="fluidWrapper">
<div class="shrinkCol">
<div class="lbl">lbl:</div>
<div class="lbl">long lbl:</div>
</div>
<div class="stretchCol">
<div class="fluidCell">Expand Content</div>
<div class="fluidCell">Expand Content</div>
</div>
</div>
<div class="fixedWrapper">
<div class="shrinkCol">
<div class="lbl">longer label:</div>
<div class="lbl">lbl:</div>
</div>
<div class="shrinkCol">
<div class="fixCell" style="width:100px;">Fixed</div>
<div class="fixCell" style="width:100px;">Fixed</div>
</div>
</div>
</div>
CSS
.fTbl {
border: solid magenta 2px;
display: flex;
flex-flow: row wrap;
width: 100%;
align-items: flex-start;
}
.fixedWrapper {
display: flex;
flex: 0 0 auto;
flex-flow: row nowrap;
}
.fluidWrapper {
display: flex;
flex: 1 1 auto;
flex-flow: row nowrap;
}
.shrinkCol {
display: flex;
flex: 0 0 auto;
flex-flow: column nowrap;
}
.stretchCol {
display: flex;
flex: 1 1 auto;
flex-flow: column nowrap;
}
.fluidCell {
border: 2px solid orange;
min-width: 140px;
}
.fixCell {
border: 2px solid orange;
}
.lbl {
text-align: right;
font-style: italic;
border: 2px solid orange;
}
好的,下面是您通常如何使用这个 CSS:
- 表格必须分成单独的列,每列逐行独立填写。
- 如果不同列的行包含不同高度的项目,则必须明确赋予它们相同的高度。
- Label/content 列对放置在 fixed/fluidWrapper 类 中,以便标签和内容(通常是文本框)包裹在一起,不会分开。
- 不可能在 1 个 flex table 内有一个 "colspan" 而不将行彼此解耦并显式设置宽度。
我喜欢这种方法,因为它很容易让 flex 项目在垂直和水平方向上拉伸和压缩以填充页面,并且包装项目以响应窄屏幕非常简单。它也不需要像 table 那样的 hacky CSS。我发现 HTML table 有时会非常麻烦且不直观。
我不喜欢这种方法,因为 table 的一行不可能(或者可能很难)跨越多列。如果有更宽的项目,则必须将其放置在新容器中,因此不会与其上方的项目共享其标签宽度。然而,这些抱怨似乎源于 table 和 flex box 设计目标的内在差异,您必须简单地选择最适合给定布局的方法。
关于生成自动 table 列宽大约等于任何行中最宽列的列宽的搜索来到了这个问题。如果那是你想要做的,请在 CSS 中尝试 th,td {width: max-content;}
。适合我。